设计模式的种类
设计模式有23种,分为三类:
- 创建型模式:
- 单例模式、抽象工厂模式
- 原型模式、建造者模式、工厂模式
- 结构型模式
- 适配器模式、桥接模式、装饰模式、组合模式
- 外观模式、享元模式、代理模式
- 行为型模式
- 模板方法模式、命令模式、访问者模式
- 迭代器模式、观察者模式、中介者模式
- 备忘录模式、解释器模式、状态模式
- 策略模式、责任链模式
设计模式七大原则
设计模式的核心思想
- 找出代码中的可变化之处,并独立出来,不要和固定代码混在一起
- 针对接口编程, 不要针对实现编程
- 为了交互对象之间的松耦合设计而努力
耦合度比较
- 泛化(继承)==实现>组合>聚合>关联>依赖
1. 单一职责
一个类A负责多个职责时,要将A的粒度分解成对应职责的类,对应单个职责,在后期对某个职责进行更改时,不会对其他职责造成影响。降低类的复杂度
2. 接口隔离
一个类不应该依赖不需要的接口,即一个类对另一个类的以来应该建立在最小接口上,当要以来的接口中有不需要的部分,就应该将大的接口拆分成小接口,保证依赖的接口都是需要的
3. 依赖倒置
抽象不要依赖细节,细节要依赖抽象
低层模块最好是依赖抽象,抽象中不要有具体操作,具体操作交给细节
继承要遵守里氏替换原则
抽象--》接口或者抽象类
细节--》实现类
-
依赖关系的三种传递方式
-
接口传递
interface IOpenAndClose{ public void open(ITV tv); } interface ITV{ public void play(); } //实现接口 class OpenAndClose implements IOpenAndClose{ public void open(ITV tv){ tv.play(); } }
-
构造方法传递
interface IOpenAndClose{ public void open(); } interface ITV{ public void play(); } //实现接口 class OpenAndClose implements IOpenAndClose{ private ITV tv; public OpenAndClose(ITV tv){ //使用构造器 this.tv = tv; } public void open(){ this.tv.play(); } }
-
setter传递
interface IOpenAndClose{ public void open(ITV tv); public void setTv(ITV tv); } interface ITV{ public void play(); } //实现接口 class OpenAndClose implements IOpenAndClose{ private ITV tv; public void setTv(ITV tv){ //调用setter方法 this.tv = tv; } public void open(){ this.tv.play(); } }
-
4.里氏替换原则
正确使用继承:所有引用基类的方法必须能透明的使用其子类的对象。子类中不要轻易重写父类的方法,可以通过聚合,组合,依赖的方法来解决问题,让子类和父类不再继承,而是共同继承一个更加基础的base类,关于父类中子类需要的方法,可以通过依赖或者继承来获取对象并调用方法,可以降低耦合
普通的继承
遵守里氏替换的改进
5.开闭原则
提供方(被依赖)--》开放扩展
使用方(依赖)--》修改关闭
如图:paint为使用方,三个类型类是提供方,当我们要添加新的绘画类型时,不仅要创建新的类,还要在paint中添加新的方法,这样自违背了开闭原则,代码扩展性也很低
以下优化遵守了开闭原则,将具体的各个类型的draw方法实现在各自的实现类中,paint依赖抽象,只需要调用Shape对象的draw方法,对应调用各自实现类的draw方法,这样就达到目的,使用方无需更改。
6. 迪米特法则(直接朋友法则/最少知道原则)
直接朋友:B是A的成员变量,B是A中方法的入参,B是A中方法的返回值类型
以上三种情况称为B是A的直接朋友,其它的为陌生类
迪米特法则:陌生类最好不要以局部变量的形式出现在类的内部;以降低类与类之间的耦合
对于被依赖的类不管有多复杂,都封装在类的内部,对外只提供public方法,不要泄露任何信息;
7.合成复合原则
尽量使用聚合和合成,不要使用继承
以下为依赖,组合,聚合的类图