单一职责在.NET中
单一职责是降低耦合度的指导思想,适用于一个微服务,一个类型,一个方法。
微服务层:
微服务一般按业务的领域来进行拆分:药房微服务就是药房的业务,护士站微服务就是护士站的业务,广义上没有什么问题,但对于一些共用业务,就犯难了,究竟放在那个微服务里?还是合并两个微服务?其实这里就单一,把共用的抽离出来,不一定做成另一个微服务,可以统一做成类库,供两个微服务调用,如果业务有细微差别,可以通过设计模式来灵活解决异构情况。
类型:
这里的类型,一般指复杂类型:如结构体(struct),接口(interface),抽类(abstract class),实例化类(class),记录(record)。这此类型内部,重要的成员有属性,方法,正是这些成员的规划,是决定这些类型是否职责单一的重要指标。
比如下面的用户类型,这样的定义是不没有错误的,对于一些小型项目,这样定义是最经济的。
/// <summary> /// 用户 /// </summary> class User { /// <summary> /// 用户名 /// </summary> public string UserName { get; set; } /// <summary> /// 密码 /// </summary> public string Password { get; set; } /// <summary> /// 性名 /// </summary> public string Name { get; set; } /// <summary> /// 性别 true男,false为女 /// </summary> public bool Sex { get; set; } /// <summary> /// 职务 /// </summary> public string Position { get; set; } /// <summary> /// 生日 /// </summary> public DateTime Birthday { get; set; } }
如果从单一职责考虑,这个类可以分为三个类,如下:
/// <summary> /// 用户 /// </summary> class User { /// <summary> /// 用户名 /// </summary> public string UserName { get; set; } /// <summary> /// 密码 /// </summary> public string Password { get; set; } } /// <summary> /// 人员职务 /// </summary> class Position { /// <summary> /// 职务名称 /// </summary> public string PositionName { get; set; } } /// <summary> /// 人员 /// </summary> class Person { /// <summary> /// 人员编号 /// </summary> public string PersonNo { get; set; } /// <summary> /// 性名 /// </summary> public string Name { get; set; } /// <summary> /// 性别 true男,false为女 /// </summary> public bool Sex { get; set; } /// <summary> /// 年龄 /// </summary> public int Age { get; set; } /// <summary> /// 用户 /// </summary> public User User { get; set; } /// <summary> /// 职务 /// </summary> public Position[] Positions { get; set; } }
分开以后,虽然代码增多了,但每个类的作用就单一了,用户就是用户,人员就是人员,职务分出来当其扩展时其他类型也不受影响。
方法:
越往下层,单一职责的把握越困难,特别是在写一个方法的时候,单一的这个单位很模糊,怎么就算单一?
比如写一个发送数据模块,主要分部分:组织数据,发送数据,也就对应两个方法BuildData,SendData,可能在组织数据时发现,有些数据得作转换,比如时间,类型等,这时可以在BuildData里作转换,当然也可以把转换这部分抽离出来,组成一个TransformData,纠结的是,有时转换数据只要一行代码,如果按单一职责思想应该分离出来,但看到分离的代码觉得差强人意,有没有一个标准呢?
这里我给出我自己的标准(仅代表自己的认识):
1、在纠结一个方法要不要拆开时,第一考虑是业务的单一性
2、有些业务之间当前状态统一的,要联想下一步状态,或下一阶段,这种状态是否持续(不要关心这个状态在现实中什么时间到来)
3、多用一些经典的设计模式来让方法彼此隔离,互不干扰
《asp.net core精要讲解》 https://ke.qq.com/course/265696
《asp.net core 3.0》 https://ke.qq.com/course/437517
《asp.net core项目实战》 https://ke.qq.com/course/291868
《基于.net core微服务》 https://ke.qq.com/course/299524