面向对象设计的6个设计原则,23个经典设计模式
设计原则
1.单一职责原则
定义:不要存在多于一个导致类变更的原因。通俗的说,即一个类只负责一项职责。
问题由来:类T负责两个不同的职责:职责P1,职责P2。当由于职责P1需求发生改变而需要修改类T时,有可能会导致原本运行正常的职责P2功能发生故障。
解决方案:遵循单一职责原则。分别建立两个类T1、T2,使T1完成职责P1功能,T2完成职责P2功能。这样,当修改类T1时,不会使职责P2发生故障风险;同理,当修改T2时,也不会使职责P1发生故障风险。
2.里氏替换原则
定义1:如果对每一个类型为 T1的对象 o1,都有类型为 T2 的对象o2,使得以 T1定义的所有程序 P 在所有的对象 o1 都代换成 o2 时,程序 P 的行为没有发生变化,那么类型 T2 是类型 T1 的子类型。
定义2:所有引用基类的地方必须能透明地使用其子类的对象。
问题由来:有一功能P1,由类A完成。现需要将功能P1进行扩展,扩展后的功能为P,其中P由原有功能P1与新功能P2组成。新功能P由类A的子类B来完成,则子类B在完成新功能P2的同时,有可能会导致原有功能P1发生故障。
解决方案:当使用继承时,遵循里氏替换原则。类B继承类A时,除添加新的方法完成新增功能P2外,尽量不要重写父类A的方法,也尽量不要重载父类A的方法
只要父类能出现的地方,其子类就应该能出现。也就是用子类替换父类后,保证程序照样运行。
里氏替换原则通俗的来讲就是:子类可以扩展父类的功能,但不能改变父类原有的功能,否则可能导致原来的功能出错。
3.依赖倒置原则
依赖倒置原则基于这样一个事实:相对于细节的多变性,抽象的东西要稳定的多。以抽象为基础搭建起来的架构比以细节为基础搭建起来的架构要稳定的多。在 java中,抽象指的是接口或者抽象类,细节就是具体的实现类,使用接口或者抽象类的目的是制定好规范和契约,而不去涉及任何具体的操作,把展现细节的任 务交给他们的实现类去完成。
依赖倒置原则的核心思想是面向接口编程
4.接口隔离原则
定义:客户端不应该依赖它不需要的接口;一个类对另一个类的依赖应该建立在最小的接口上。
问题由来:类A通过接口I依赖类B,类C通过接口I依赖类D,如果接口I对于类A和类B来说不是最小接口,则类B和类D必须去实现他们不需要的方法。
解决方案:将臃肿的接口I拆分为独立的几个接口,类A和类C分别与他们需要的接口建立依赖关系。也就是采用接口隔离原则
接口细化,也就是接口中的方法要尽量少。
5.迪米特法则
定义:一个对象应该对其他对象保持最少的了解。
问题由来:类与类之间的关系越密切,耦合度越大,当一个类发生改变时,对另一个类的影响也越大。
解决方案:尽量降低类与类之间的耦合。
也称为最少知识原则,其定义为:一个对象应当对其他对象有最少的了解。也就是一个类中不要有过多的其他类。
6.开闭原则
定义:一个软件实体如类、模块和函数应该对扩展开放,对修改关闭。
问题由来:在软件的生命周期内,因为变化、升级和维护等原因需要对软件原有代码进行修改时,可能会给旧代码中引入错误,也可能会使我们不得不对整个功能进行重构,并且需要原有代码经过重新测试。
解决方案:当软件需要变化时,尽量通过扩展软件实体的行为来实现变化,而不是通过修改已有的代码来实现变化。
一个软件实体(如类,模块,和函数)应该对扩展开放,对修改关闭。
设计模式
一、创建型模式
1. 抽象工厂(abstract factory)
2. 生成器(builder)
3. 工厂方法(factory method)
4. 原型(prototype)
5. 单件(singleton)
二、结构型模式
1. 适配器(adapter)
2. 桥接(bridge)
3. 组成(composite)
4. 装饰(decorator)
5. 外观(facade)
6. 享元(flyweight)
7. 代理(proxy)
三、行为模式
1. 职责链(chain of responsibility)
2. 命令(command)
3. 解释器(interpreter)
4. 迭代器(iterator)
5. 中介者(mediator)
6. 备忘录(memento)
7. 观察者(observer)
8. 状态(state)
9. 策略(strategy)
10. 模版方法(template method)
11. 访问者(visitor)