学习单一责任原则与C#

前端之家收集整理的这篇文章主要介绍了学习单一责任原则与C#前端之家小编觉得挺不错的,现在分享给大家,也给大家做个参考。
我试图学习单一责任原则(SRP),但它是相当困难,因为我有一个巨大的困难,以确定什么时候,我应该从一个类,我应该把/组织它应该删除

我在搜索一些材料和代码示例,但大多数材料我发现,而不是让它更容易理解,使其难以理解。

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函数将在通道连接类内部,如果验证失败,将被调用

例如:

  1. public void UserJoin(User user)
  2. {
  3. if (verify.CanJoin(user))
  4. {
  5. messages.Greeting(user);
  6. }
  7. else
  8. {
  9. this.kick(user);
  10. }
  11. }

如果你们可以在这里借给我一个容易理解的在线和免费的C#材料,或者通过显示我如何分割引用的示例,如果可能的话一些示例代码,建议等等。

让我们从 Single Responsibility Principle(SRP)实际意思是什么开始:

类应该只有一个理由改变。

这有效地意味着每个对象(类)应当具有单个责任,如果一个类具有多个责任,这些责任变得耦合并且不能被独立地执行,即一个变化可以影响甚至在特定实现中破坏另一个。

一个肯定必须读这是源本身(从“Agile Software Development,Principles,Patterns,and Practices”的pdf章):The Single Responsibility Principle

话说,你应该设计你的类,所以他们最好只做一件事,做一件好事。

首先想想你有什么“实体”,在你的例子中,我可以看到用户和频道以及它们之间通信的媒介(“消息”)。这些实体彼此之间具有一定的关系:

>用户具有他已经加入的多个频道
>一个频道有多个用户

这也自然地导致以下功能列表:

>用户可以请求加入频道。
>用户可以向已加入的频道发送消息
>用户可以离开频道
>频道可以拒绝或允许用户的请求加入
>频道可以踢用户
>频道可以向该频道中的所有用户广播消息
>频道可以向个别用户发送问候消息
渠道

SRP是一个重要的概念,但不应该独立 – 对于您的设计同样重要的是Dependency Inversion Principle(DIP)。要将其纳入设计中,请记住,用户,消息和通道实体的特定实现应取决于抽象或接口,而不是特定的具体实现。为此,我们从设计接口而不是具体类开始:

  1. public interface ICredentials {}
  2.  
  3. public interface IMessage
  4. {
  5. //properties
  6. string Text {get;set;}
  7. DateTime TimeStamp { get; set; }
  8. IChannel Channel { get; set; }
  9. }
  10.  
  11. public interface IChannel
  12. {
  13. //properties
  14. ReadOnlyCollection<IUser> Users {get;}
  15. ReadOnlyCollection<IMessage> MessageHistory { get; }
  16.  
  17. //abilities
  18. bool Add(IUser user);
  19. void Remove(IUser user);
  20. void BroadcastMessage(IMessage message);
  21. void UnicastMessage(IMessage message);
  22. }
  23.  
  24. public interface IUser
  25. {
  26. string Name {get;}
  27. ICredentials Credentials { get; }
  28. bool Add(IChannel channel);
  29. void Remove(IChannel channel);
  30. void ReceiveMessage(IMessage message);
  31. void SendMessage(IMessage message);
  32. }

这个列表没有告诉我们是什么原因这些功能被执行。我们最好把“为什么”(用户管理和控制)的责任放在一个单独的实体中 – 这样,如果“为什么”改变,用户和频道实体不必改变。我们可以利用战略模式和DI这里,并可以有任何具体的实现IChannel取决于一个IUserControl实体,给我们“为什么”。

  1. public interface IUserControl
  2. {
  3. bool ShouldUserBeKicked(IUser user,IChannel channel);
  4. bool MayUserJoin(IUser user,IChannel channel);
  5. }
  6.  
  7. public class Channel : IChannel
  8. {
  9. private IUserControl _userControl;
  10. public Channel(IUserControl userControl)
  11. {
  12. _userControl = userControl;
  13. }
  14.  
  15. public bool Add(IUser user)
  16. {
  17. if (!_userControl.MayUserJoin(user,this))
  18. return false;
  19. //..
  20. }
  21. //..
  22. }

你看到在上面的设计SRP甚至不是接近完美,即IChannel仍然依赖于抽象IUser和IMessage。

最后,应该努力实现灵活,松耦合的设计,但总是要做出折衷,灰色区域也取决于您希望应用程序改变的位置。

SRP在我看来极端,导致非常灵活,但也碎片和复杂的代码,可能不是那么容易理解作为简单但有点更紧密耦合的代码

事实上,如果两个责任总是在同一时间改变,你可以说,不应该把它们分成不同的类,因为这将导致马丁,“无需复杂的气味”。对于从不改变的责任也是如此 – 行为是不变的,并且没有必要分裂它。

这里的主要思想是,你应该做出一个判断呼叫,你看到责任/行为可能在未来独立地改变,这种行为是相互依赖的,并且总是在同一时间改变(“拴在一起”)并且哪种行为首先不会改变。

猜你在找的设计模式相关文章