美文网首页
《设计模式》——单一职责原则

《设计模式》——单一职责原则

作者: 半寿翁 | 来源:发表于2019-08-04 13:06 被阅读0次

先扯两句

咳咳,发现的不要说啊,而且打死我也不会承认的,这次的扯竟然是后补的,其实到现在也不知道该扯写什么,只是不扯不好发目录啊,所以《设计模式》——目录,好了,闲言少叙,我们进入正题。

单一职责原则

《设计模式之禅第2版》设计模式之禅的第一个标题就是“我是‘牛’类,我可以担任多职吗”。

image

看到这就不禁想到公司的状况,就比如作为一个Android工程师,如果不仅让我开发Android,还要从需求调研、到原型设计、再到测试、发布都一个人干。就好像一个“牛”类一般,身兼多职,可是工资不变又不给多发福利。而且“牛”类还有一个弊端就是越“牛”就越“牛”,领导有事第一个想到让你解决,你承担的工作也越来越多。当然相对的,做得越多错得越多,被领导批的也越多。多多少少这个“牛”类都会有所怨言,然后工作积极性下降,导致项目越做越糙。最后不是自己受不了离职滚蛋了,就是公司忍不了开了这个“牛”类。或者双方不离不弃,最后一起堕入地狱。
image

所以作为一个成熟的公司,一定要做到分工明确,哪怕是趋向分工明确专职专岗,专人做事更专业有效率,做多少事拿多少钱也没那么多怨言。而一个成熟的项目自然也是如此,因此就引出了“单一职责原则”。

把整个项目想想成为一个公司,然后我们每一个职员在工作中则负责各司其职。回到前面所说的工作量:
  • 需求分析:需求调研
  • 产品经理:原型设计
  • 开发人员:程序开发
  • 测试人员:测试
  • 运营人员:发布

当然,上面的区分就好像是猫吃鱼、狗吃肉、奥特曼打小怪兽一样太简单浅显了。关于单一职责原则当然还有一些较为复杂的分类,举一个依据书中类推的例子:

image
大半夜我突然惊醒,想对暗恋一天的妹子表白,于是拿起手机拨打对方的电话

“我喜欢你”

"滚!嘟嘟嘟……"

我挂掉心碎流泪。
这个过程中,就表白而言,共有四个过程:暗恋妹子、表白、接受反馈、情绪变化。

所以封装一个打电话的单一职责接口就是:
public interface IPerson {
    /**
     * 暗恋一个女孩
     *
     * @param phoneNum 对方手机号
     */
    void loveSomeGirl(Object girl);
    
    /**
     * 表白
     *
     * @param loveWord 情话
     */
    void confession(String loveWord);
    
    /**
     * 接受反馈
     *
     * @param screwYou 滚
     */
    void acceptFeedback(String screwYou);
    
    /**
     * 情绪变化——心碎
     */
    void emotionalChanges();
}

不过这么封装真的对吗?以前是没觉得什么不对,不过刚刚被拒绝的心碎之余,闲来无事翻翻书就会发现这是不对的。

暗恋妹子、心碎的情绪变化,都是我个人的事情,毕竟看个小说也可以哭好久。可表白和接受反馈却必须要有一个活生生的女孩来进行互动。

因此依据单一职责原则,这里可以使用一种更加清晰的封装方式:

/**
 * 可以独自完成的事
 */
public interface IManAlone {
    /**
     * 暗恋一个女孩
     *
     * @param phoneNum 对方手机号
     */
    void loveSomeGirl(Object girl);
    
    /**
     * 情绪变化——心碎
     */
    void emotionalChanges();
}
/**
 * 需要互动的事
 */
public interface IManInteraction {
    /**
     * 表白
     *
     * @param loveWord 情话
     */
    void confession(String loveWord);
    
    /**
     * 接受反馈
     *
     * @param screwYou 滚
     */
    void acceptFeedback(String screwYou);
}

然后:

public class Me implements IManAlone, IManInteraction{

    @Override
    public void acceptFeedback(String screwYou) {
        // TODO Auto-generated method stub
        
    }

    @Override
    public void loveSomeGirl(Object girl) {
        // TODO Auto-generated method stub
        
    }

    @Override
    public void confession(String loveWord) {
        // TODO Auto-generated method stub
        
    }

    @Override
    public void emotionalChanges() {
        // TODO Auto-generated method stub
        
    }
}

当然,之前单一的IPerson接口的封装也不是完全的错误,而且在实际项目中,时间紧任务中,我们往往也确实是这么封装的,只是说在纯“理论”、纯“学术”的角度来说,根据行为模式拆分后的接口更加合理一些而已。

下面列举一下单一职责原则的优点:

  • <b>类的复杂性降低,实现上面职责都有清晰明确的定义</b>(如果我们想要创建一个只会默默暗恋不会表白的死宅,只需要实现IManAlone接口,而创建一个只会表白而不会喜欢对方,也不会被结果影响的花花公子时,只需要实现IManInteraction即可)
  • <b>可读性提高,复杂性降低</b>(看到接口就知道这个人是死宅、花花公子、还有一些普通人)
  • 可维护性提高(依据是能独自完成的,还是需要交互的去维护即可)
  • <b>变更实现的风险降低</b>(需求变更对于程序员来说可以说是常态,尤其是领导的需求全靠拍大腿的公司,更是变态般的常态,因此单一职责封装而言,变更需求后相应的调整会少好多。还是上面的例子,如果一个人被拒绝后不只是情绪变化,还伴有假睡避世、化悲愤为食量等行为的变化时,我们只需要调整ManAlone接口,而由于接口调整,难免实现类也要改变。不过我们只需要修改死宅和普通人,因为花花公子不需要事先IManAlone接口,所以不需要调整)

当然,上面所属的都是相当理想的情况下了,但实际项目中,必然存在着多多少少的不确定性,比如:

  1. 你不用管,我们先出一版看看
  2. 这个是新需求,客户明天要
  3. 这有上面难的,不就是让张三的三叔公的外孙女的同桌的父亲的前女朋友的小舅子的胖侄女没有权限追他吗
  4. ……

对于如上种种,我们没有时间、没有精力、甚至于对于一些外包思维来说,也没有必要去做那么详细的单一职责原则。对于某些只重眼前利益,不看后期可维护性的领导也更不可能说让你因为个上面单一职责而耽误了他儿子的奶粉钱。

image

所以,在可能的情况下,对自己的代码有严格追求的大家,在实际项目中,还是建议使用这一原则的。没有过多追求的,也建议有时间的时候稍微优化一下自己的代码,毕竟万一领导哪天又拍大腿想到一个什么GOOD IDEA,我们也不能为此重构项目不是。

最后祝大家早日日进斗金,然后给老头子我介绍女朋友!

相关文章

网友评论

      本文标题:《设计模式》——单一职责原则

      本文链接:https://www.haomeiwen.com/subject/mqtydctx.html