文章目录
创建型模式
单例模式 -- 确保对象唯一性
例子
用TaskManager类。通过以下三步进行重构
- 为了确保TaskManager实例的唯一性,禁止外部直接new来创建对象。需将构造函数改为
private
- 类变成私有的了,所以外部访问该类对象,需要类内建TaskManager类型的私有
静态
成员变量tm。供外部访问 - 增加一个公有的静态方法、外界去使用tm 去实例化。 [注意 该方法要public]
得到:
单例模式有3个要点:
- 某个类只能有一个实例;
- 它必须自行创建这个实例;
- 它必须自行向整个系统提供这个实例。
上述代码在多线程时候,会出现 创建多个实例
。提供两种解决方式
优化
饿汉式
定义静态变量的时候实例化单例类
懒汉式
不自行实例化,延时加载。
采取双标志
- 为了避免多个钱程同时调用getInstonce ( )方法,可以使用关键守synchronized
- 如果使用双重检查锁定来实现懒汉式单例类,需要在静态成员变量instonce之前增加修饰符volatile,被volatile修饰的成员变量可以确保多个线程都能够正确处理
优缺点
优点: 提供了对唯一实例的受控访问,可以严格控制客户怎么样访问它
缺点:没有抽象层,难以扩展; 单例类职责过重,一定程度违背单一职责原则;
使用场景
- 客户调用类的单个实例只允许使用一个公共访问点。除了该公共访问点,不能通过其他途径访问该实例。
- 系统要求提供一个唯一的序列号生成器或贵源管理器,或着需要考虑赉源消耗太大而只允许创建一个对象。
提示:以下是本篇文章正文内容,下面案例可供参考
简单工厂模式
例子:
图表库举例:
完整代码:
Chart接口充当抽象产品类,其子类HistogromChort、 PieChart和Linehart充当具体产品类,Chart-Factory充当工厂类。
优化
每更换一个Chart对象都需要修改客户端代码中静态工方法的参数,客户端代码将要重新编译。
可以将参数写到XML中,代码中只需要读取配置文件字符。
优缺点
优点
(1) 工厂类包含必要的判断逻辑,决定在什么时候创建哪一个产品类的实例。客户端仅仅"消费"产品。简单工厂模式实现了对象创建和使用的分离。
(2)客户端无须知道所创建的具体产品类的类名,只需要知道具体产品类所对应的参数即可。
(3)通过引入配置文件,可以在不修改任向客户端代码更换和增加新的具体产品类。
缺点
(1) 由于工厂类集中了所有产品的创建逻辑,职责过重。
(2)使用简单工厂模式势必会增加系统中类的个数(引入了新的工丁厂类。
(3)系统扩展困难。一旦添加新产品就不得不修改工厂逻辑。
适用场景
- 工厂类负责创建的对象比较少。由于创建的对象较少,不会造成工厂方法中的业务逻辑太过复杂。
- 客户端只知道传入工丁厂类的参数,对于如同创建对象并不关心。
工厂方法模式 -- 多态工厂的实现
简单工厂模式下存在
- 工厂类过于庞大,包了大量的f...else...代码,导致维护和测试难度增大。
- 系统扩展不灵活,如果增加新类型的日志记录器,必须修改静态工厂方法的业务逻辑,违反了开闭原则。
简单工厂模式只有一个工厂 需要知道每个产品创建细节
由此工厂方法产生:
例子
图表库举例:
ConcreteFactory 具体工厂; Factory 抽象工厂
ConcreteProduct 具体产品 与 具体工厂一一应对; Product 抽象产品
完整代码:
优缺点
优点
- 用户只需要关心所需产品对应的工厂,无须关心创建细节,甚至无须知道具体产品类的类名。
- 它能够让工厂可以自主确定创建同种产品对象,而如同创建这个对象的细节则究全封装在具体工厂内部。
- 加入新产品时,无须修改抽象工厂和抽象产品提供的接口,无须修改客户端,也无须修改其他的具体工厂和具体产品,而只要添加
缺点
- 在添加新产品时,需要编写新的具体产品类,而且还要提供与之对应的具体工厂类,在一定程度上增加了系统的复杂度。
- 考虑到系统的可扩展性,需要引入抽象层,在客户端代码中均使用抽象层进行定义,增加了系统的抽象性和理解难度
优化
如同简单工厂一样,引入XML配置文件进行优化
适用场景
- 客户端不知道其所需要的对象的类。在工厂方法模式中,客户端不需要知道具体产品类的类名,只需要知道所对应的工厂即可,具体的产品对象由具体工厂类创建,可将具体工厂类的类名存储在配置文件或数据库中。
- 抽象工厂类通过其子类来指定创建哪个对象。在工厂方法模式中,抽象工厂类只需要提供一个创建产品的接口,而由其子类来确定具体要创建的对象,利用面向对象的多态性和里氏代换原则
抽象工厂模式 -- 产品族的创建
对于工厂方法,增加新的功能时,虽然不需要修改哦代码,但是需要增加大量的类,每个新增具体组件都要增加一个具体工厂。
对于具体工厂模式:
- 具体工厂负责生产具体产品,需要创建9个具体类
对于抽象工厂模式:
- 可抽象为产品等级结构
==> 电器工厂: 可生产电视机、电冰箱、空调 - 可抽象为产品族
==> 海尔工厂: 可生产海尔电视机、海尔电冰箱、海尔空调
需要创建三个工厂类即可
例子
结构图
AbstractFactory 抽象工厂
ConcreteFactory 具体工厂
AbstractProduct 抽象产品
ConcreteProduct 具体产品
抽象工厂中声明了多个工厂方法,用于创建不同类型的产品 :
每个具体的工厂方法可以返回一个特定的产品对象
具体工厂内的所有产品构成了产品族
优缺点
优点 :
(1) 抽象工厂模式隔离了具体类的生成,使得客户并不需要知道什么被创建。
(2)能够保证客户端始终只使用同一个产品族中的对象。
(3)增加新的产品族很方便,无须修改已有系统,符合开闭原则。
缺点 :
增加新的产品等级结构麻烦,需要对原有系统进行较大的修改,甚至需要修改抽象层代码,这显然会带来较大的不便,违背了开闭原则。
适用场景
(1)一个系统不应当依赖于产品类实例如同被创建、组合和表达的细节,这对于所有类型的工厂模式都是很重要的,用户无须关心对象的创建过程,将对象的创建和使用解耦。
(2)系统中有多于一个的产品族,而每次只使用其中某一个产品族。以通过配置文件等方式来使得用户可以动态改变产品族,也可以很方便地增加新的产品族。
(3).属于同一个产品族的产品将在一起使用,这一约束必须在系统的设讨中体现出来。同一个产品族中的产品可以是没有任向关系的对象,
但是它们都具有一些共同的约束。例如同一操作系统下的按钮和文本柜,按钮与文本框之间没有直接关系,但都属于操作系统
总结
简单工厂: 唯一工厂类,一个产品抽象类,工厂类的创建方法依据入参判断并创建具体产品对象。
工厂方法: 多个工厂类,一个产品抽象类,利用多态创建不同的产品对象,避免了大量的f-else判断。
抽象工厂: 多个工厂类,多个产品抽象类,产品子类分徂,同一个工厂实现类创建同术中的不同产品,减少了工厂子类的数量。