我在搜索一些材料和代码示例,但大多数材料我发现,而不是让它更容易理解,使其难以理解。
For example if I have a list of Users and from that List I have a
class Called Control that does lots of things like Send a greeting and
goodbye message when a user comes in/out,verify weather the user
should be able to enter or not and kick him,receive user commands and messages,etc.
从这个例子你不需要太多的了解我已经做了太多的一个类,但我不够清楚如何拆分和重组后。
如果我理解SRP,我会有一个类加入频道,问候和再见,用户验证类,阅读命令的类,对不对?
但是我在哪里和如何使用踢脚?
我有验证类,所以我相信我会有所有类型的用户验证,包括天气或不是一个用户应该被踢。
因此,kick函数将在通道连接类内部,如果验证失败,将被调用?
例如:
public void UserJoin(User user) { if (verify.CanJoin(user)) { messages.Greeting(user); } else { this.kick(user); } }
如果你们可以在这里借给我一个容易理解的在线和免费的C#材料,或者通过显示我如何分割引用的示例,如果可能的话一些示例代码,建议等等。
类应该只有一个理由改变。
这有效地意味着每个对象(类)应当具有单个责任,如果一个类具有多个责任,这些责任变得耦合并且不能被独立地执行,即一个变化可以影响甚至在特定实现中破坏另一个。
一个肯定必须读这是源本身(从“Agile Software Development,Principles,Patterns,and Practices”的pdf章):The Single Responsibility Principle
话说,你应该设计你的类,所以他们最好只做一件事,做一件好事。
首先想想你有什么“实体”,在你的例子中,我可以看到用户和频道以及它们之间通信的媒介(“消息”)。这些实体彼此之间具有一定的关系:
这也自然地导致以下功能列表:
>用户可以请求加入频道。
>用户可以向已加入的频道发送消息
>用户可以离开频道
>频道可以拒绝或允许用户的请求加入
>频道可以踢用户
>频道可以向该频道中的所有用户广播消息
>频道可以向个别用户发送问候消息
渠道
SRP是一个重要的概念,但不应该独立 – 对于您的设计同样重要的是Dependency Inversion Principle(DIP)。要将其纳入设计中,请记住,用户,消息和通道实体的特定实现应取决于抽象或接口,而不是特定的具体实现。为此,我们从设计接口而不是具体类开始:
public interface ICredentials {} public interface IMessage { //properties string Text {get;set;} DateTime TimeStamp { get; set; } IChannel Channel { get; set; } } public interface IChannel { //properties ReadOnlyCollection<IUser> Users {get;} ReadOnlyCollection<IMessage> MessageHistory { get; } //abilities bool Add(IUser user); void Remove(IUser user); void BroadcastMessage(IMessage message); void UnicastMessage(IMessage message); } public interface IUser { string Name {get;} ICredentials Credentials { get; } bool Add(IChannel channel); void Remove(IChannel channel); void ReceiveMessage(IMessage message); void SendMessage(IMessage message); }
这个列表没有告诉我们是什么原因这些功能被执行。我们最好把“为什么”(用户管理和控制)的责任放在一个单独的实体中 – 这样,如果“为什么”改变,用户和频道实体不必改变。我们可以利用战略模式和DI这里,并可以有任何具体的实现IChannel取决于一个IUserControl实体,给我们“为什么”。
public interface IUserControl { bool ShouldUserBeKicked(IUser user,IChannel channel); bool MayUserJoin(IUser user,IChannel channel); } public class Channel : IChannel { private IUserControl _userControl; public Channel(IUserControl userControl) { _userControl = userControl; } public bool Add(IUser user) { if (!_userControl.MayUserJoin(user,this)) return false; //.. } //.. }
你看到在上面的设计SRP甚至不是接近完美,即IChannel仍然依赖于抽象IUser和IMessage。
最后,应该努力实现灵活,松耦合的设计,但总是要做出折衷,灰色区域也取决于您希望应用程序改变的位置。
SRP在我看来极端,导致非常灵活,但也碎片和复杂的代码,可能不是那么容易理解作为简单但有点更紧密耦合的代码。
事实上,如果两个责任总是在同一时间改变,你可以说,不应该把它们分成不同的类,因为这将导致马丁,“无需复杂的气味”。对于从不改变的责任也是如此 – 行为是不变的,并且没有必要分裂它。
这里的主要思想是,你应该做出一个判断呼叫,你看到责任/行为可能在未来独立地改变,这种行为是相互依赖的,并且总是在同一时间改变(“拴在一起”)并且哪种行为首先不会改变。