单一职责在.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、多用一些经典的设计模式来让方法彼此隔离,互不干扰