面向对象的七大原则
开闭原则
定义:软件实体应当对扩展开放,对修改关闭。
即,当应用的需求发生改变时,不修改软件实体的源代码或者二进制代码的前提下,可以扩展模块的功能,使其满足新的需求。
软件实体指:
- 项目中划分出地模块
- 类和接口
- 方法
开闭原则的作用
开闭原则是面向对象设计的终极目标,其作用如下:
1.降低软件测试的复杂性
如果软件实体遵守开闭原则,在软件测试时,只需要对扩展的代码进行测试即可,因为原有代码没有修改,任然可以正常运行。
2.提高代码的可复用性
程序粒度越小,可复用性越高。在满足开闭原则下,新功能都是的通过扩展代码来满足的,其原有代码不受污染,原有具有的功能更纯粹。
3.提供软件的可维护性
满足开闭原则的软件,其稳定性和延续性强,从而易于扩展和维护。
里氏替换原则的作用
- 里氏替换原则是实现开闭原则的重要方式之一。
- 它克服了继承中重写父类造成的可复用性变差的缺点。
- 它是动作正确性的保证。即类的扩展不会给已有的系统引入新的错误,降低了代码出错的可能性。
- 加强程序的健壮性,同时变更时可以做到非常好的兼容性,提高程序的维护性、可扩展性,降低需求变更时引入的风险。
开闭原则的实现方法
通过“抽象约束、封装变化”来实现开闭原则,即通过接口或抽象类为软件实体定义一个相对稳定的抽象层,而将相同的可变因素封装在具体的实现类中。
只要抽象层定义得合理,可以基本保持软件架构的稳定。当软件需要新增功能时,只需要根据需求重新派生一个实现类来扩展即可。
里氏替换原则
定义:继承必须确保超类拥有的性质子类中仍然成立(Inheritance should ensure that any property proved about supertype objects also holds for subtype objects)。
通俗来讲就是,子类可以扩展父类的功能,但不能改变父类原有的功能。即,子类继承父类时,除添加新的方法完成新的功能外,不要去重写父类的方法。
实现方法:
- 子类可以实现父类的抽象方法,但不能覆盖父类的非抽象方法。
- 子类可以增加自己特有的方法。
- 子类的方法重载(不是重写)父类的方法时,方法的前置条件(即方法的输入参数)要比父类的方法更宽松。
- 当子类的方法实现父类的方法时(重载/重写或实现抽象方法),方法的后置条件(即方法的返回值)要比父类的方法更严格或相等。
通过重写父类方法来完成新的功能虽然简单,但是会导致整个框架的可复用性差,特别是运用多态比较频繁时,程序出错的概率会非常大。
如果程序违背了里氏替换原则,则继承类的对象在基类出现的地方会出现运行错误。这时其修正方法是:取消原来的继承关系,重新设计它们之间的关系。
正方形不是长方形
依赖倒置原则
面向接口编程,不要面向实现编程
抽象不依赖细节,细节依赖于抽象
单一职责原则
控制类的粒度大小、将对象解耦、提高其内聚性
一个方法只做一件事
接口隔离原则
为各个类建立它们需要的专用接口
迪米特法则
只与你的朋友交谈,不跟陌生人说话
合成复用原则
尽量先使用组合或者聚合等关联关系来实现,其次才考虑使用继承关系来实现