zoukankan      html  css  js  c++  java
  • 《设计模式》杂记之单一职责原则

    最近买了本设计模式的书,名字叫《设计模式之禅》。这是我第一本设计模式的书,看了几章了感觉自己受益匪浅,所以想就把自己感觉到比较有意思的设计模式知识分享给大家。

    首先说一下我们程序员为什么要学习设计模式把!下面是引用书上的原话:

    你是程序员,没有问题,通过学习设计模式能够让你写出更加高效,优雅的代码;

    你是架构师,那更好,设计模式可让你设计出健壮,稳定,高效的系统,并且自动地预防未来业务变化可能对系统带来的影响;

    你是项目经理,也OK,设计模式可以让你的工期大大缩短,让你的项目团队队员快速地理解你的意图,最终的成果就是优质的项目:高可靠性,高稳定性,高效率和低维护成本。

    那么我们看完这几行话后,是不是有一种很想学习设计模式的感觉呢?反正我看完这几行话后特别想把书读完啊!呵呵~~~

    好了,额不再废话啦!开始切入正题吧!

    设计模式分为6大设计原则和23中设计模式。6大设计原则分别是:单一职责原则;里氏替换原则;依赖倒置原则;接口隔离原则;迪米特法则;开闭原则。23种设计模式分别是:单例模式;工厂方法模式;抽象工厂模式;模板方法模式;建造者模式;原型模式;中介者模式;命令模式;责任链模式;装饰模式;策略模式;适配器模式;迭代器模式;组合模式;观察者模式;门面模式;备忘录模式;访问者模式;状态模式;解释器模式;享元模式;桥梁模式。

    这篇博文,我想主要介绍一下6大设计原则中的单一职责原则。

    单一职责原则的英文名称是Single Responsibility Principle,简称SRP。这个设计原则备受争议,那么争议之处在哪里呢?就是对职责的定义,什么是类的职责,以及怎么划分类的职责。

    RBAC模型(Role-Based Access Control),基于角色的访问控制,通过分配和取消角色来完成用户权限的授予和取消,使动作主体(用户)与资源的行为(权限)分离。下面我们来看一个类图:

     

    通过这个接口的设计,我们可以发现有一些问题,因为用户的属性和用户的行为没有分开。我们应该把用户的信息抽取成一个BO(Bussness Object,业务对象),把行为抽取成一个Biz(Business Logiz,业务逻辑),那么我们就可以对这个类图进行修改:

     

    我们重新拆分成两个接口,IUserBO负责收集和反馈用户的属性信息,IUserBiz负责用户的行为,完成用户信息的维护和变更。

    分清职责后的代码就可以如下:

    IUserBiz userInfo = new UserInfo();

        //实现业务对象

        IUserBO userBO = (IUserBO)userInfo;

        userBO.setPassword("wzk");

        //实现业务逻辑

        IUserBiz userBiz = (IUserBiz)userInfo;

        userBiz.deleteUser();

    上面我把一个接口分成两个接口的动作。就是依赖了单一职责原则,所以单一职责我就可以理解为:应该有且仅有一个原因引起类的变更。

    下面我们还是通过一个电话通话的例子来进一步说明单一职责原则,大家都知道我们在通电话的时候会有以下过程发生:拨号,通话,回应,挂机。这个接口类图如下:

     

    这样我们的代码就可以这样写:

    //拨通电话

            void dial(string phoneNumber);

            //通话

            void chat(object o);       

            //通话完毕挂话

            void huagup();

    这是书中一段源代码,我开始认为这个接口是符合单一职责原则的,但是仔细分析后,发现它其实包含了两个职责:一个是协议管理,一个是数据传送。dial()和hangup()两个方法实现的是协议管理,分别负责拨号接通和挂机;chat()实现的是数据的传送。那么我们在现实生活当中协议接通和数据传送都会发生变化,所以我们可以将接口拆分成两个接口,类图如下:

     

    这个类图就完全符合单一职责原则的要求了,每个接口职责分明,结构清晰,那么我们的手机类要把ConnectionManager和DataTransfer组合一块才能使用。组合是一种强耦合关系,都有共同的生命周期,我们使用这个强耦合关系不仅不如使用接口实现的方式,并且还增加了类的复杂性。下面我们就来修改一下这个类图:

     

    这样子设计就变成了,一个类实现了两个接口,把两个职责融合在一个类中。

    那么通过上面的例子,说明单一职责原则有什么好处呢?引用书上一段话吧!

    (1)       类的复杂性降低,实现什么职责都有清晰明确的定义。

    (2)       可读性提高。

    (3)       可维护性提高。

    (4)       变更引起的风险降低。

    注意:

    单一职责原则提供了一个编写程序的标准,用“职责”或“变化原因”来衡量接口或类设计得是否优良,但是“职责”或“变化原因”都是不可度量的,因项目而异,因环境而异。

    对于接口,我们在设计得时候一定要做到单一,但是对于实现类就需要考虑多方面因素了。生搬硬套单一职责原则会引起类的剧增,给维护带来非常多的麻烦,过分细分类的职责也会人为地增加系统的复杂性。

    还有就是类的单一职责可能会受很多因素的制约。比如说:项目工期,成本,人员技术水平,硬件情况,网络情况等因素。所以说对于单一职责原则,引用作者一句话就是:接口一定要做到单一职责,类的设计尽量要做到只有一个原因引起变化。

  • 相关阅读:
    在IE和Firfox获取keycode
    using global variable in android extends application
    using Broadcast Receivers to listen outgoing call in android note
    help me!virtual keyboard issue
    using iscroll.js and iscroll jquery plugin in android webview to scroll div and ajax load data.
    javascript:jquery.history.js使用方法
    【CSS核心概念】弹性盒子布局
    【Canvas学习笔记】基础篇(二)
    【JS核心概念】数据类型以及判断方法
    【问题记录】ElementUI上传组件使用beforeupload钩子校验失败时的问题处理
  • 原文地址:https://www.cnblogs.com/wzk89/p/2015506.html
Copyright © 2011-2022 走看看