对于接口,我们在设计的时候一定要做到单一,但是对于实现类就需要多方面考虑了。生搬硬套单一职责原则会引起类的剧增,给维护带来非常多的麻烦,而且过分细分类的职责也会人为地增加系统的复杂性。本来一个类可以实现的行为硬要拆成两个类,然后再使用聚合或组合的方式耦合在一起,人为制造了系统的复杂性。所以原则是死的,人是活的,这句话很有道理。
单一职责原则很难在项目中得到体现,非常难,为什么?在国内,技术人员的地位和话语权都比较低,因此在项目中需要考虑环境,考虑工作量,考虑人员的技术水平,考虑硬件的资源情况,等等,最终妥协的结果是经常违背单一职责原则。而且,我们中华文明就有很多属于混合型的产物,比如筷子,我们可以把筷子当做刀来使用,分割食物;还可以当叉使用,把食物从盘子中移动到口中。而在西方的文化中,刀就是刀,叉就是叉,你去吃西餐的时候这两样肯定都是有的,刀就是切割食物,叉就是固定食物或者移动食物,分工很明晰。这种文化的差异很难一步改造过来,但是我相信随着技术的深入,单一职责原则必然会深入到项目的设计中,而且这个原则是那么的简单,简单得不需要我们更加深入地思考,单从字面上大家都应该知道是什么意思,单一职责嘛!
单一职责适用于接口、类,同时也适用于方法,什么意思呢?一个方法尽可能做一件事情,比如一个方法修改用户密码,不要把这个方法放到“修改用户信息”方法中,这个方法的颗粒度很粗,比如图1-7中所示的方法。
图1-7 一个方法承担多个职责
在IUserManager中定义了一个方法changeUser,根据传递的类型不同,把可变长度参数changeOptions修改到userBO这个对象上,并调用持久层的方法保存到数据库中。在我的项目组中,如果有人写了这样一个方法,我不管他写了多少程序,花了多少工夫,一律重写!原因很简单:方法职责不清晰,不单一,不要让别人猜测这个方法可能是用来处理什么逻辑的。比较好的设计如图1-8所示。
通过类图可知,如果要修改用户名称,就调用changeUserName方法;要修改家庭地址,就调用changeHomeAddress方法;要修改单位电话,就调用changeOfficeTel方法。每个方法的职责非常清晰明确,不仅开发简单,而且日后的维护也非常容易,大家可以逐渐养成这样的习惯。
图1-8 一个方法承担一个职责
所以,如果对接口、类、方法使用了单一职责原则,那么快乐的就不仅仅是你了,还有你的项目组成员,大家可以轻松而又愉快地进行开发;还有你的老板,减少了因为变更引起的工作量,减少了无谓的人员和资金消耗。当然,最快乐的也许就是你了,因为加官晋爵可能等着你哟!