创建型模式
定义:对类的实例化过程进行了抽象,能够将软件模块中对象的创建和对象的使用进行分离。为了使软件的结构更加清晰,外界对于这些对象只需要知道他们共同的接口,而不需要知道具体的实现细节,是整个系统的设计更加符合单一职责的原则。
简单工厂模式
1 模式结构
- Factory: 工厂角色
- Product: 抽象产品角色
- ConcreteProduct: 具体产品角色
2 优点
- 实现责任的分割,它提供了专门的工厂类用于生产对象。
- 客户端无须知道所创建具体产品类的类名,只须知道具体产品类所对应的参数即可
- 通过引入配置文件,可以在不修改任何客户端代码的情况下更换和增加新的具体产品类
3 缺点
- 由于工厂类集中了所有产品的创建逻辑,一旦不能正常工作,整个系统都要收到影响
- 系统扩展困难,一旦添加产品就不得不修改工厂逻辑,在产品类型较多时,不利于系统的扩展和维护
- 简单工厂模式使用了静态工厂方法,造成工厂角色无法形成基于继承的等级结构
工厂方法模式
1 模式动机
为了弥补简单工厂模式的缺点,即扩展新的产品类的时候,需要修改工厂类的代码,违反了开闭原则,我们首先定义一个抽象工厂类,在定义具体的工厂类,实现在抽象工厂类中定义的方法,这种抽象化的结果使这种结构可以在不修改具体工厂类的情况下引进新的产品。这种特性使得工厂方法模式具有超越简单工厂模式的优越性,更加符合开闭原则。
2 模式结构
- Product : 抽象产品
- ConcreteProduct : 具体产品
- Factory : 抽象工厂
- ConcreteFactory : 具体工厂
3 优点
工厂方法模式在简单工厂模式优点的基础上,另外一个优点是在系统中加入新产品时,无需修改抽象工厂和抽象产品提供的接口,无需修改客户端,无需修改具体工厂和具体产品,而只需要添加一个具体工厂和具体产品即可。这样的系统可扩展性更强,更加符合开闭原则
4 缺点
- 增加系统的复杂度
- 考虑到系统的可扩展性,引入抽象层,在客户端代码中均须使用抽象层进行定义,增加了系统的抽象性和理解难度,且在实现时可能需要用到DOM、反射等技术,增加了系统的实现难度
抽象工厂模式
1 模式动机
在工厂方法模式中具体工厂负责生产具体的产品,每一个具体工厂对应一个具体的产品,工厂方法也具有唯一性,但是有时候我们需要一个工厂可以提供多个产品对象,而不是单一的产品对象。
抽象工厂模式与工厂方法模式最大的区别是:工厂方法模式对应的是一个产品等级结构,而抽象工厂模式则需要面对的是多个产品等级结构。
2 模式结构
- AbstractFactory : 抽象工厂
- ConcreFactory : 具体工厂
- AbstractProduct : 抽象产品
- ConcreFactory : 具体产品
3 优点
抽象工厂模式在工厂方法模式优点的基础上,还有当一个产品族中的多个对象被设计成一起工作时,他能保证客户端只使用同一个产品族中的对象,这对一些需要根据当前环境来制定其行为的软件系统来说,是一种非常实用的设计模式
4 缺点
开闭原则的倾斜性,增加新工厂和新产品族容易,增加新的产品等级结构麻烦。
建造者模式
1 模式动机
建造者模式可以将部件和其组装过程进行分开,用户只需要指定一个复杂对象的类型就可以得到该对象,而无需知道其内部复杂的构造细节
2 模式结构
- Builder : 抽象建造者
- ConcreBuilder : 具体建造者
- Director : 指挥者
- Product : 产品
3 模式分析
该模式结构中引入了指挥类,该类的作用分为两部分
- 隔离了用户和生产过程
- 负责控制产品的生产过程
4 优点
- 在建造者模式中,用户不必知道产品的内部细节,将产品本身与产品的创建过程解耦,使得相同的创建过程可以创建不同的产品
- 用户使用不同的具体建造者就可以得到不同的产品
- 将复杂产品的创建过程分解在不同的方法中,使创建过程更加清晰,也方便使用程序来控制创建过程。
- 增加新的具体创建者无需修改原有类库的代码,指挥者类正对抽象建造者编程,系统方便扩展,符合关闭原则
5 缺点
- 建造者模式创建的产品一般具有较多的共同点,其组成部分相似。如果产品差异过大,不适合使用建造者模式,因此适用范围有限制
原型模式
1 模式动机
再软件系统中,有些对象的创建过程较为复杂,并且有时候需要频繁创建,原型模式通过给出一个原型对象来指明所要创建对象的类型,然后用复制这个对象原型的办法来创建出更多同类型的对象,这就是原型模式的意图所在。
2 模式结构
- ProtoType : 抽象原型类
- ConcreteProtoType : 具体原型类
- Clinet : 客户端
3 优点
简化对象的创建过程,通过一个已有的实例可以提高新实例的创建效率
4 缺点
需要为每一个类配备一个克隆方法,而且这个克隆方法需要对类的功能进行通盘考虑,这对全新的类不难,但对已有类进行改造时,不一定是一件容易的事,必须修改其源代码,违背了“开闭原则”
单例模式
1 模式动机
对于系统中的某些类来说,只有一个实例很重要。例如系统中可以存在多个打印任务,但同时只能由一个正在工作的打印任务。一个系统只能有一个系统管理器和文件管理系统。一个系统只能有一个计时工具
2 模式定义
单例模式确保某一个类只有一个实例,而且自行实例化并且向整个系统提供这个实例。单例模式的三个要点是:
- 某个类只能有一个实例
- 必须自行创建这个实例
- 必须自行向整个系统提供这个实例
3 模式结构
- Singleton : 单例类
在这里插入图片描述
4 模式分析
- 单例类拥有一个私有构造函数,确保用户无法通过new关键词直接实例化它
- 单例类拥有一个静态私有成员变量和静态公有的工厂方法,该工厂方法检验实例的存在性并实例化自己,然后存储在静态成员变量中,以确保只有一个实例被创建
5 优点
- 提供了对唯一实例的受控访问
- 由于系统内存中只存在一个对象,因此可以节约系统资源
6 缺点
- 单例类没有抽象层,因此单例类的扩展存在很大的问题
- 单例类职责过重,既充当工厂角色,提供工厂方法。又充当产品角色,提供业务方法
扩展
- 饿汉式单例
- 懒汉式单例
饿汉式单例在自己被加载时就将自己实例化,但从资源利用效率角度上来说,这个比懒汉式单例稍差一些,从速度核反应时间角度来说,比懒汉式单例要好一些。