大话设计模式
设计模式¶
类图¶
面向对象设计六大原则¶
单一职责原则¶
开放封闭原则¶
依赖倒置原则¶
迪米特法则¶
单例模式¶
饿汉模式¶
- 构造器私有化
- 在类内部直接创建
static
对象 - 提供返回实例的
static
方法,不创建对象也会有该实例
1 2 3 4 5 6 7 8 9 10 11 12 |
|
懒汉模式¶
- 构造器私有化
- 定义
static
实例 - 提供返回该实例的
static
方法,当用户调用时才创建对象并返回
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 |
|
简单工厂模式¶
该模式主要负责解决对象的创建问题,工厂类负责根据不同的需求生产对象。
优点:
- 客户端免于负责创建产品的责任。
- 可以不修改客户端代码增加产品,提高系统灵活性。
缺点:
- 工厂类集中了所有创建对象的逻辑,容易对系统造成影响。
- 一旦商品发生增减,就要修改工厂类破坏封装性。
使用场景:
- 所需创建对象数量较少,改动少
- 客户端无需关心对象的创建
工厂方法模式¶
优点:
- 向客户隐藏了哪种具体产品类被实例化这一细节。
- 加入新产品时,无需修改抽象工厂和抽象产品提供的接口,有非常良好的扩展性。
缺点:
- 在添加新产品时,还要提供对应的具体工厂类,系统中类的个数将成对增加,增加了系统的复杂度。
- 将逻辑判断移到客户端进行,增加客户端负担。这个可以用反射解决。
使用场景:
同工厂模式。
策略模式¶
在简单工厂模式的基础上,将创建产品的责任又放回客户端,采用多态,Context
中使用父类参数,传入子类对象做出自己的行为。
优点:
-
算法可以自由切换,扩展性好
-
采用多态,避免使用多重条件判断
缺点:
- 客户端要负责创建产品,功能重
- 所有策略类都需要对外暴露
使用场景:
-
若一个系统里面有许多类,它们之间的区别仅在于它们的行为,使用策略模式可以动态地让一个对象在许多行为中选择一种行为。
-
一个系统需要动态地在几种算法中选择一种。
- 如果一个对象有很多的行为,如果不用恰当的模式,这些行为就只好使用多重的条件选择语句来实现。
改进:简单工厂模式和策略模式结合
将对象的创建放在Context
类中,再使用多态做出对象各自的行为。
装饰模式¶
若没有Component
,那么可以让Decorator
继承ConcreteComponent
。若只有一个ConcreteDecorator
,那就没必要加Decorator
类。
就是对于 人-衣服-裤子-鞋子 的组合,先创建人对象,让衣服包裹人,然后让裤子包裹衣服,鞋子包裹裤子:
优点:
- 有效地把类的核心职责和装饰功能区分开,且去除了重复逻辑
- 为已有的功能动态地添加更多的功能
缺点:
- 装饰顺序很重要,多层装饰复杂容易出错
使用场景:
-
对象的创建过程是不稳定的,就像搭配衣服一样可以有好几种组合方式
-
扩展一个类的功能
-
动态增加功能,动态撤销
代理模式¶
优点:
-
代理模式能将代理对象与真实被调用的目标对象分离。
-
一定程度上降低了系统的耦合度,扩展性好。
-
可以起到保护目标对象的作用。
-
可以对目标对象的功能增强。
缺点:
-
代理模式会造成系统设计中类的数量增加。
-
在客户端和目标对象增加一个代理对象,会造成请求处理速度变慢。
-
增加了系统的复杂度。
使用场景:
- 远程代理:
-
虚拟代理:推迟真正所需对象实例化时间. 在需要真正的对象工作之前, 如果代理对象能够处理, 那么暂时不需要真正对象来出手
-
安全代理:即上图中提到的情况,用于控制真实对象的访问权限
-
智能指针
原型模式¶
(注意,Java中已有实现好的 Prototype
接口,叫 Cloneable
,但由于它是浅拷贝,所以类中存在其他对象时,要在最内层对象实现该接口,其他部分逐变量拷贝)
优点:
- 使用原型模式创建对象比直接new一个对象在性能上要好的多,因为Object类的clone方法是一个本地方法,它直接操作内存中的二进制流,特别是复制大对象时,性能的差别非常明显。
- 简化对象的创建。
缺点:
- 使用原型模式时不能够有
final
对象,因为带有final
类型的对象无法进行拷贝。 Object
类的clone
方法是浅拷贝,对于复杂的数据类型只能够另行拷贝。- 使用原型模式复制对象不会调用类的构造方法,而是通过调用 Object 类的 clone 方法来完成的,它直接在内存中复制数据,所以不会调用类的构造方法。单例模式中,只要将构造方法设置为私有的访问权限,就可以实现单例。但是
clone
方法直接无视私有访问权限,单例模式和原型模式在使用过程中是冲突的,需要特别注意。
使用场景:
- 性能和安全要求的场景。
- 通过 new 产生一个对象非常繁琐。
- 一个对象多个修改者的场景。
- 在实际项目中,原型模式很少单独出现,一般是和工厂方法模式一起出现,通过 clone 的方法创建一个对象,然后由工厂方法提供给调用者。
模板方法模式¶
代码:
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 |
|
优点:
- 把不便的行为搬到超类,去除子类的重复代码,提高代码的复用性,符合开闭原则。
- 将不同的代码不同的子类中,通过对子类的扩展增加新的行为,提高代码的扩展性。
缺点:
- 每一个抽象类都需要一个子类来实现,这样导致类的个数增加,间接地增加了系统实现的复杂度。
- 继承关系自身缺点,如果父类添加新的抽象方法,所有子类都要改一遍。
使用场景:
- 一系列步骤构成的过程,从高层次看是相同的,但是细节的实现上不同。