再谈GOF设计模式的设计原则

设计模式的目的:代码重用性、可读性、可扩展性、可靠性、使程序呈现高内聚+低耦合

一、单一职责原则:实现的类职责要单一
    1.应该有且仅有一个原因引起类的变更。
    
    如果一个类承担多个职责的后果:
        1.一个职责的变化可能会削弱或者抑制这个类实现其他职责的能力;
        2.当客户端需要该对象的某一个职责时,不得不将其他不需要的职责全都包含进来,从而造成冗余代码或代码的浪费。
    
二、依赖倒置原则:在高层模块中,以抽象为基础搭建稳定的框架,把实现细节的任务交给实现类去完成
    1.高层模块(调用方,稳定)不应依赖低层模块(被调用方,变化),高层和低层模块应该依赖抽象(稳定);
    2.抽象不应依赖细节(变化),细节应该依赖抽象。
    
    依赖倒置原则的主要作用:降低类间的耦合性、提高系统稳定性、减少并行开发引起的风险、提高代码的可读性和可维护性
    依赖导致原则的关系传递方式(三种):接口传递、构造函数传递、setter方式传递
    依赖倒置原则注意事项和细节:
        1.低层模块尽量都要有抽象类或接口,或者两者都有,程序稳定性更好;
        2.变量的声明类型尽量是抽象类或者接口,这样能使用多态,是的基类指针或者引用,指向派生类的对象;
        3.继承时遵循里氏替换原则
    
三、接口隔离原则:设计接口精简单一
    1.客户端不应该依赖它不需要的接口;
    2.类间的依赖关系应建立在最小的接口上。
    
    单一职责原则和接口隔离原则的对比:
    1.单一职责原则注重的是职责;约束的对象是类,它是针对程序中的实现和细节;
    2.接口隔离原则注重的是对接口依赖的隔离;约束的对象是接口,主要针对抽象和程序整体框架的构建。
    
    接口隔离原则实现方法:
    1.接口尽量小,但要有限度:一个接口只服务于一个子模块或业务逻辑;
    2.为依赖接口的类定制服务:只提供调用者需要的方法,屏蔽不需要的方法;
    3.了解环境,拒绝盲从:每个项目或产品都有选定的环境因素,环境不同,接口拆分的标准就不同深入了解业务逻辑;
    4.提高内聚,减少对外交互:使接口用最少的方法去完成最多的事情。
    
    
四、里氏替换原则:不要破坏继承体系
    1.子类型能够替换父类型:程序中使用父类对象的地方,能够透明地使用其子类对象替换;
    2.使用继承时,子类尽量不要重写父类的方法;
    3.在适当情况下,可以通过聚合、组合、依赖来解决问题
    
    里氏替换原则主要作用:
    1.是对开闭原则的补充,是对实现抽象化的具体步骤的规范;
    2.它克服了继承中重写父类造成的可复用性变差的缺点;
    3.动作正确性的保证:类的扩展不会给已有系统引入新的错误,降低了代码出错的可能性。
    
五、开闭原则:      解耦、单一、高内聚就是开闭原则的精神纲领;
    1.对扩展开放,对修改封闭;用抽象构建框架,用实现扩展细节;
    2.当软件发生变化时,尽量通过扩展软件实体行为来实现变化,而不是通过修改已有代码来实现变化;
    3.遵循其它设计原则,以及使用设计模式的目的就是遵循开闭原则。
    
    开闭原则的主要作用:
    1.对软件测试的影响:只需要测试通过扩展代码实现完成的模块;
    2.可以提高代码的可复用性:粒度越小,被复用的可能性就越大:在OOP中,根据原子和抽象编程可以提高代码的可复用性;
    3.可以提高代码的可维护性:稳定性高、可延续性强,从而易于扩展和维护。
    
    开闭原则实现方法:抽象约束、封装变化(通过接口或者抽象类定义一个相对稳定的抽象层,将相同的可变因素封装在相同的具体实现中)

六、迪米特法则(最少知道原则):  要降低耦合度,只与朋友关系进行通信。
    1.一个对象应该对其他对象保持最少了解;
    2.类与类关系越密切,耦合度越大;
    3.一个类对自己依赖的类遵循最少知道原则,对于被依赖的类不管多复杂,都尽量将逻辑封装在类的内部,对外除了提供public方法,不泄露其他任何信息;
    4.只与朋友关系进行通信:对象之间的耦合就说明二者有朋友关系。耦合方式有很多,依赖、关联、组合、聚合等。陌生的类最好不要以局部变量的形式出现在类的内部。

七、优先使用组合,而不是类继承:
    1.对象组合属于黑箱复用,类继承属于白箱复用;
    2.类继承在某种程度上破坏了封装性,子类父类耦合度高;
    3.对象组合则要求被组合的对象具有良好定义的接口,耦合度低。
    
    组合和继承的对比:
    1.组合维持了类的封装性(成分对象的内部细节,新对象看不见);继承破坏了类的封装性(父类的实现细节暴露给子类);
    2.组合的两个类耦合度低(只能使用成分对象的接口);继承关系的父子类耦合度高(父类的任何改变都会引起子类发生变化);
    3.组合的灵活性高(运行时多态进行);继承的灵活性低受限(静态,编译时已经确定,运行时不能发生改变)。
    
八、封装变化点:
    1.使用封装来创建对象之间的分界层,让设计师可以在分界层的一侧进行修改,而不会对另一侧产生不良的影响,从而实现层次间的松耦合。
    
九、针对接口编程、而不是针对实现编程
    1.不将变量类型声明为某一个特定的具体类,而是声明为某个接口;
    2.客户程序无需获知对象的具体类型,只需要知道对象所具有的的接口;
    3.减少系统中的各部分的依赖关系,从而实现“高内聚,松耦合”的类型设计方案。

你可能感兴趣的:(C/C++,设计模式,设计模式,c++)