简单工厂、工厂方法、抽象工厂设计模式笔记分享
文章目录
前言
简单工厂、工厂方法、抽象工厂三种设计模式都属于创建型设计模式,根据作用范围划分,简单工厂、工厂方法属于类模式;抽象工厂属于对象模式;由于简单工厂只是对类的创建进行同一的管理(用工厂类进行抉择创建什么对象)是一种编码的调整,所以简单工厂并不属于GoF 23种设计模式之一。
创建型模式关注对象的创建过程,致力于将对象的创建和使用分离,使创建的细节对使用透明,“外界调用者只负责管理如何调用对象,对象创建者(对象实例化)只负责对象的实例化”,使整个系统的设计更符合单一职责原则。
本文将结合实例详细阐述以上三种设计模式的思想。
提示:以下是本篇文章正文内容,下面案例可供参考
一、简单工厂模式
1. 模式定义
根据参数的不同返回不同的实例。专门定义一个类来负责创建其他类的实例,被创建的实例通常都具有共同的父类。
2. 模式结构
Factory 类对象创建公有方法factoryMethod() ,更具输入的参数创建并返回相应类型的对象。
从本质上看,简单工厂方法只是将对象的实例化过程封装到一起,属于代码层面的调整。在新增具体产片类时依然需要相应修改Factory类内容,但简单工厂方法有效地将对象实例化过程整合在一起,提高了代码的可读性和可维护性。
3. 实例分析
把大象、恐龙装进冰箱时,首先需要实例化大象和恐龙对象,使用简单工厂方法类图分析如下
Animal 、 Dinosaur 、 Elephant 类内容较为简单不在列举,下面主要列举AnimalFactory 类种的内容
Public class AnimalFactory{
public Animal ProduceAnimal(string name){
if(name.equals("dinosaur")){
return Dinosaur();
}
else if (name.equals("Elephant"){
return Elephant();
}
esle{
throw new Exception("对不起,您想要的动物我们没有哦!!")
}
}
}
如上述代码所描述,factory 类只是将具有相同特点的对象实例化过程进行真整合,如果需要增加新的Animal子类需要修改 AniamlFactory 的ProduceAniaml 成员函数,不符合开闭原则,工厂方法通过对具体工厂类的划分有效解决了简单工厂的问题。
工厂方法还请详见下文。
二、工厂方法模式
1. 模式定义
工厂方法模式又称为工厂模式,又叫虚拟构造器模式或者多态工厂模式,属于类创建模式。和简单工厂模式不同,在工厂方法模式中工厂类作为一个父类负责定义创建商品的公共接口,具体的工厂子类负责实现接口、实例化具产品对象。
将产品类的实例化过程操作延迟到工厂子类中完成,通过产品子类确定究竟应该实例化哪个具体的产品类。
2. 模式结构
Factory 抽象工厂定义 生产产品的接口,一般定义成一个抽象类,使继承Factory的子类都必须实现Factory中的抽象方法。
ConcreteProduct 具体工厂类 继承Factory,实现Factory中定义的抽象方法,返回具体的产品对象
3. 实例分析
把大象放进冰箱,创建大象对象后,如何使程序在符合开闭原则的前提下支持对恐龙等其他动物对象的实例化?
工厂模式在产品部分的结构与简单工厂模式没有太大的区别,依然是继承Animal 子类的方式 保持程序的可扩展性,工厂类部分增加具体的工厂子类完成具体的产品“生产” ,工厂父类只负责同一接口的定义。
每个具体的工厂可以只负责单一种类产品的生产,在扩展更多具体产品时也无需修改之前的代码,只需要增加具体工厂类和具体产品类即可。显然工厂方法模式能够更符合开闭原则,具有更好的可扩展性。
在工厂方法中产品和工厂两个分区都是利用了父类定义接口、子类具体实现的结构 同时客户端调用使用子类对象给父类定义变量赋值的里氏代换思想从而使程序具有很强的扩展性。但由于结构相对复杂,类的个数增加很多,系统的复杂程度也随之增加,在系统运行时也必定会增加额外开销。
AnimalFactory 类内容:
public interface Aniaml{
public Aninal ProduceAniaml();
}
DinosaurFactory 类内容:
public class DinosaurFactory implements AnimalFactory{
public Aniaml ProduceAniaml(){
return Dinosaur();
}
}
其他类内容较为简单不再赘述
抽象工厂模式
1. 模式定义
抽象工厂模式时工厂方法的泛化版,提供一个创建一系列相关或相互依赖对象的接口,而无需指定他们具体的类,抽象工厂模式又称为Kit 模式,属于对象创建模式。
用人话说就是一个具体的工厂可以生产多种具有一定相关性的产品
下面引入两个概念:
产品等级结构: 产品的继承结构,如一个抽象类时电视机,其子类是海尔电视机、海信电视机、长虹电视机,则抽象电视机与具体品牌的电视机之间构成了一个产品等级结构。
产品族: 产品族指同一个工厂生产的,位于不同产品等级结构的一组商品,如海尔电视机、海尔冰箱、海尔空调属于一个产品族,都由海尔工厂生产。
2. 模式结构
AbstractFactory 抽象工厂类: 和工厂方法不同,在抽象工厂模式中,抽象工厂类不止定义了一个方法,而是定义了一组方法,每个方法对应一个产品结构。
ConcreteFactory具体工厂 实现抽象工厂中定义的方法,生成一组具体的产品,这些产品生成一个产品族,每一个产品都属于一个产品等级结构。
AbstractProduct 抽象产品 定义了一个产品等级结构的共性业务特点和方法。
ConcreteProduct 具体产品 实现抽象产品定义的业务方法。
3. 实例分析
不同系统的图形环境配置: Windows、Unix、Linux 系统下个界面组件样式
整体类图结构如上图,windows、unix、Linux 具体工厂继承抽象工厂,可以“生产”相应系统下的Text和Button对象。Text和其子类以及Button和其子类构成产品等级结构,同一个具体工厂生产的产品如WindowsText 和WindowsButton构成一个产品族。
需要注意的是: 抽象工厂方法虽然扩充了具体工厂所能生产的产品类型,实际应用的频率也比较高,但抽象工厂方法在某些方面并不符合开闭原则!!
抽象工厂模式在增加新的产品等级结构时需要修改AbstractFactory以及ConcreteFactory类代码,违反开闭原则。但抽象工厂模式新建具体工厂,。无需修改原本代码,增加具体的类即可符合开闭原则。抽象工厂模式在遵循开闭原则时具有倾向性:倾向于增加产品族,而不支持增加产品等级结构。
总结
以上是对简单工厂、工厂方法、抽象工厂模式的理解,三者各有优势但也分别存在问题。现做如下总结:
- 简单工厂: 思想简单,封装了同一类对象的实例化过程,易于理解;对象实例化过程过于集中,但不符合开闭原则和单一职责原则。
- 工厂方法: 将对象实例化过程推迟至具体工厂中进行,使各具体工厂职责单一,且符合开闭原则,可扩展性强;但类结构较为复杂,更容易发生类爆炸现象。
- 抽象工厂: 扩充了子类工厂的产品生产种类,使子类工厂可以生产一个产品族的所有产品,能够一定程度上缓解类爆炸的问题;但抽象工厂模式对于开闭原则的遵守具有倾向性并不完全遵守,更倾向于增加和扩展产品族,扩展产品等级结构则需要修改代码不符合开闭原则