定义
一个类或者模块只复杂完成一个职责。也就是说,不要设计大而全的类,要设计力度小,功能单一的类。一个类包含两个以上和业务不相干的功能,应该将他拆分多个功能更加单一,粒度更加细化的类。
比如一个类力既含有订单的一些操作,又包含用户的一些操作,而订单和用户是两个独立的业务领域模型,我们将两个不相干的功能放到同一个类中,那就违反了单一原则。为了满足单一原则,我们需要将这个类分为两个粒度更细的类。: 订单类和用户类。
如何判断类的职责是否单一
从刚刚的这个列子来看,单一职责看似不难应用,那是因为我举的例子,比较极端,一眼九年呢给看出订单和用户好不相干,但大部分情况下,类里的方法是否归为同一类,还归为不相关的两个功能,并不是那么容易判断。在真实的软件开发中,对于一个类是否职责单一的判断,很难拿捏。我们举一个贴近现实的例子。
public class UserInfo { private long userId; private String username; private String email; private String telephone; private long createTime; private long lastLoginTime; private String avatarUrl; private String provinceOfAddress; // 省 private String cityOfAddress; // 市 private String regionOfAddress; // 区 private String detailedAddress; // 详细地址 // ... 省略其他属性和方法... }
对于这个问题有两种不同的观点。一种观点是,UserINfo 类包含的都是跟用户相关的信息,所有的属性和方法都隶属于用户业务模型。满足单一模型;另一种观点在UserInfo 中,所赞的比重比较高,可以拆分为独立的userAddress ,UserInfo只保留Address 之外的其他信息。拆分之后两个类的职责更加单一
那种观点更对,实际上,要从中做出选择,我们不能脱离具体的应用场景。如果在这个社交产品中,用户的地址跟其他的信息一样,我们单纯的用来展示。那么UserInfo 的设计就是合理的。但是如果这个社交产品发展的非常好。之后又在产品中添加了电商模块,
用户的地址信息会在电商物流中,那么我们最好件该地址从UserInfo 中拆分出来。独立成用户的物流信息。
我们在进一步延申,如果这个社交产品发展的越来越好,公司内部又开发出了更多其他产品,公司希望支持统一账号胸痛,也就是用户一个账号。可以在其他狄梵刚登陆。 这个时候,我们需要继续对UserInfo 进行拆分,比如email telephone 独立出来 。
从这个雷子,我们可以看出,不同的应用场景,不同的阶段的需求的背景下,对同一个类的职责的单一的判断,可能都不是一样的。 在某些长江活当下的需求背景下,一个类的设计可能满足了单一原则,但是换一个场景,可能就不满足了。
除此之外,从不同的业务层去看待同一个类的设计,对类的单一原则也会又不同的认识,比如例子中的UserInfolei,我们从用户的层面来看,userInfo 包含的信息属于用户满足单一原则,如果我们从更细分的地址信息,登录认证信息,等等这些更细的粒度业务层面来看那么usreInfo 就应该继续拆分。
综上所述,评价一个类的职责是否足够单一,我们并没有一个非常明确的、可以量化的标 准,可以说,这是件非常主观、仁者见仁智者见智的事情。实际上,在真正的软件开发中, 我们也没必要过于未雨绸缪,过度设计。所以,我们可以先写一个粗粒度的类,满足业务需 求。随着业务的发展,如果粗粒度的类越来越庞大,代码越来越多,这个时候,我们就可以 将这个粗粒度的类,拆分成几个更细粒度的类。这就是所谓的持续重构(后面的章节中我们 会讲到)。
现实中的判断标准,类中的代码行数,函数或属性过多,会影响代码的可读性和可维护性,我们就需要考虑对类进行拆分。
类如果依赖饿其他类过多,或者依赖类的其他类过多,不符合低内聚,低耦合的设计思想,我们就要考虑对类进行拆分。
私有方法过多,我们烤炉是否可以件将私有方法独立到新的类中,设置为public ,供更多的类使用。
比较难给类起一个合适的名字,很难用一个业务名称概况,或者用一些笼统的Manager Context 之类的名词命名,说民跟这个类的职责定义肯能不够清晰。
比如上边的UserInfo 又一半的内容都在操作Addresses 那么可以将他拆分出来。
对于我们开发中,类的行数,不要超过200 ,函数的个数不要多余10 个。
单一原则是不是越单一越好
为了满足单一职责原则,是不是把类拆得越细就越好呢?答案是否定的。我们还是通过一个 例子来解释一下。Serialization 类实现了一个简单协议的序列化和反序列功能,如果我们想让类的职责更加单一,我们对 Serialization 类进一步拆分,拆分成一个只负责 序列化工作的 Serializer 类和另一个只负责反序列化工作的 Deserializer 类。虽然经过拆分之后,Serializer 类和 Deserializer 类的职责更加单一了,但也随之带来了新 的问题。如果我们修改了协议的格式,数据标识从“UEUEUE”改为“DFDFDF”,或者序 列化方式从 JSON 改为了 XML,那 Serializer 类和 Deserializer 类都需要做相应的修改, 代码的内聚性显然没有原来 Serialization 高了。而且,如果我们仅仅对 Serializer 类做了 协议修改,而忘记了修改 Deserializer 类的代码,那就会导致序列化、反序列化不匹配, 程序运行出错,也就是说,拆分之后,代码的可维护性变差了。
标签:String,private,我们,拆分,设计模式,单一,职责 From: https://www.cnblogs.com/dousil/p/18036469