zoukankan      html  css  js  c++  java
  • 设计模式(七大原则)

    1、设计模式相关概念

    (1)重要性

    设计模式(design pattern)对软件设计中普片存在的问题所提出的解决方案(不拘泥于某种语言),可以增强项目的扩展性、维护性,因为设计模式不是为了软件的功能的实现,而是站在软件的设计的角度

    (2)目的

    增强可维护性、重用性、灵活性、可靠性(增加或减少新功能后对原有的功能没有影响),实现高内聚低耦合

    2、设计模式的七大原则

    (1)概念

    设计模式设计的依据

    (2)七大原则

    • 单一职责

    例如:一个类只负责一项职责,如果一个类有多个职责,那么在修改其中一个职责的时候可能会对其他的职责造成影响,就应该将不同的职责分配到不同的类中。

    类级别:

      有一个交通工具类中有一个run方法,那么所有的交通工具都可以调用run方法,汽车、火车等,但是,飞机调用run方法可能就会不合理了,因为飞机是在天上飞的。此时有一个解决方案就是再创建一个飞行器类,火车和汽车调用陆地上的交通工具类的run方法,飞机调用飞行器的run方法

    方法级别(没有完全遵守单一职责原则,只有在类级别的是真正的单一职责原则):

    将不同的职责放到不同的类中做到的单一职责需要的改动较大,可以采用在一个类中定义不同的方法的方式实现单一职责原则,就是不同的方法实现不同的职责,使用类的同一个对象调用不同方法即可(在类中的方法足够少的时候可以违反单一职责原则)。

    好处:

    降低代码的复杂度,一个类只负责一个原则(如:权限类只负责权限相关的方法和属性,与角色无关)

    提高代码的可读性、可维护性和内聚性

    降低变更引起的风险

    • 接口隔离原则

     

     上面的接口设计存在一个问题,Class3通过接口Inter调用Class1的方法的时候只用到了前三个方法后面的两个方法是多余的

     

      上面的UML图中对接口进行了拆分,使得Class1和Class2中的方法都是Class3和Class4所需要使用的方法,这样就符合了接口的隔离原则。也就是说一个类在通过接口调用另外一个接口的实现类的方法的时候这个实现类应该是最小的(没有多余的方法)

    • 依赖倒转

    高层模块不应该依赖低层模块,二者都应该依赖其抽象,抽象不应该依赖细节,细节应该依赖抽象

    中心思想是面向接口编程

    例如:员工有一个接收消息的方法,这个时候此方法就需要调用Emai类中的发送Email的方法,如果还需要手机短信和微信的接收消息的方法,那么就需要新增类并在员工类中添加方法,在调用的时候需要传递的是Email类的一个对象。

    public String getMessage(Email email)

    可以再添加一个消息发送的接口,Email、微信、手机短信类都实现这个接口,此时如果添加其它的有关消息发送的类也只需要添加一个该接口的实现类即可。客户端不用修改代码

    public String getMessage(IMessage messge)

    依赖倒转原则的注意事项:

      低层模块尽量要有抽象类或接口,或者两者都有

      变量的声明类型尽量是抽象类或接口,这样我们的变量引用和实际对象之间就存在一个缓冲(例如:字类在继承父类的方法的时候可以重写父类的方法,对方法的功能进行优化),利于程序的扩展和优化

      继承的时候遵循里氏替换原则

    • 里氏替换

      父类中有一个计算两个数的差的方法,子类的一个计算两个数的和的方法与父类中的方法重名了(无意中重写了父类的方法),通常的避免此种情况发生的做法是让原来的父类和子类都继承一个更通俗的基类,原有的继承关系去掉,采用依赖、聚合、组合等关系。里氏替换准则要求我们尽量不要重写父类中的方法(原文中说:继承必须确保超类所拥有的性质在子类中仍然成立)

      子类对父类的方法进行重写在运用多态的时候回出错,在没有重写的情况下使用多态调用的是父类中的方法,在字类重写了父类的方法的时候运行的是字类的方法,在客户端调用的时候容易出现错误

    • 子类必须实现父类的抽象方法,但不得重写父类的非抽象方法,但是可以增加自己的方法
    • 当子类覆盖或实现父类的方法时,方法的前置条件(即方法的形参)要比父类方法的输入参数更宽松。
    • 当子类的方法实现父类的抽象方法时,方法的后置条件(即方法的返回值)要比父类更严格。

      也就是说将A类和B类共有的内容放到Base类中,将A和B的关系变为依赖、聚合、组合等关系,A类和B类的耦合性就降低了。列如:麻雀继承抽象类鸟,但是公鸡要是想继承抽象类是不能继承抽象方发fly的,此时重写该方法就会违背里氏替换原则。可以让鸟和公鸡都继承动物类,鸟的字类有麻雀等

    组合:B类调用A类的方法,可以在B类中创建一个A类的对象

    private A a =new A();
    • 开闭原则

      一个软件实体,如:类、模块和函数应该对扩展开放(供应方),对修改关闭(使用方),用抽象构建框架(抽象类和接口),用实现扩展细节。当软件需要变化的时候,尽量通过扩展软件来实现变化而不是通过修改已有的代码来实现变化。 实现开放封闭原则的核心思想就是对抽象编程,而不对具体编程,因为抽象相对稳定。让类依赖于固定的抽象,所以修改就是封闭的。而通过面向对象的继承和多态机制,又可以实现对抽象类的继承,通过覆写其方法来改变固有行为,实现新的拓展方法,所以就是开放的。

      例如:定义一个图形的抽象类,类中有一个draw方法,其它图形可以继承抽象类重写draw方法,在绘制图形的类的方法中只需要传递父类类型的参数(使用方是不需要改变的),当再扩展的的时候修改也是较小的。

    • 迪米特法则(最少知道原则)

      一个A类如果依赖(继承、聚合等关系)于B类,要保证他们之间的耦合度尽量降低,B类除了暴漏一个public方法,不对外泄露任何信息。核心是降低类与类之间的耦合度。依赖者:只依赖的对象,被依赖者:只暴漏应该暴漏的方法

      如果是作为成员变量、方法的参数或方法的返回值就称为直接朋友,如果出现在局部作用域就不是直接朋友

    • 合成复用

    尽量使用合成/聚合,而不是使用继承

    3、设计模式类型

    (1) 创建型:如何创建对象

    单例、抽象工厂、工厂方法、原型、建造者

    (2)结构型:如何将类或对象按某种布局组成更大的结构

    适配器、桥接、装饰、组合、外观、享元、代理

    (3)行为型:类或对象之间怎样相互协作共同完成单个对象都无法单独完成的任务,以及怎样分配职责

    模板方法、命令、访问者、迭代器、观察者、中介者、备忘录、解释器、状态、策略、责任链

    每个人都会有一段异常艰难的时光 。 生活的压力 , 工作的失意 , 学业的压力。 爱的惶惶不可终日。 挺过来的 ,人生就会豁然开朗。 挺不过来的 ,时间也会教你 ,怎么与它们握手言和 ,所以不必害怕的。 ——杨绛
  • 相关阅读:
    Python for Infomatics 第14章 数据库和SQL应用四(译)
    展望2017
    bing的简单英文字典工具
    自我安慰
    Python for Infomatics 第14章 数据库和SQL应用三(译)
    Python for Infomatics 第14章 数据库和SQL应用二(译)
    Python for Infomatics 第14章 数据库和SQL应用一(译)
    希望父亲早日恢复
    Python for Infomatics 第13章 网页服务四(译)
    Python for Infomatics 第13章 网页服务三(译)
  • 原文地址:https://www.cnblogs.com/zhai1997/p/14389676.html
Copyright © 2011-2022 走看看