工厂方法模式:
定义:定义用于创建对象的接口,让子类确定要实例化哪个类,工厂方法将类实例化延迟到该子类。
类型:创建类模式
类图:
类图知识点:
1 .类图分为三个部分,依次为类名、属性、方法
2 .以结尾的作为评论信息
3 .修饰符表示公共,-表示私有,#表示保护,没有表示可以看到任何包。
4 .带下划线的属性或方法表示静态。
工厂方法的模式代码
接口I产品{
公共语音产品方法(;
}
classproductimplementsiproduct {
公共语音产品方法(
System.out.println (产品);
}
}
接口I factory {
公共I产品创建产品(;
}
classfactoryimplementsifactory {
公共I产品创建产品(
返回新产品(;
}
}
公共类客户端{
publicstaticvoidmain (字符串[ ] args ) {
IFactory factory=new Factory (;
iproduct prodect=factory.create product (;
prodect.productMethod (;
}
}
工厂模式:
首先,我们需要谈谈工厂模式。 工厂模式根据抽象度分为三种:简单工厂模式(也称为静态工厂模式)、正文
描述的工厂方法模型,以及抽象工厂模型。 工厂模式是编程中常用的模式。 主要优点包括:
能够清晰编码结构,有效封装变化。 在编程中,产品类实例化可能复杂多样,通过工厂
模型封装了产品的实例化,使调用方不必在意产品的实例化过程,只需依赖工厂就能得到自己
想要的产品。
在呼叫方屏蔽具体的产品类。 使用工厂模式时,调用方只需要关心产品接口,具体实现请参考优化
使用者不需要在意。 更改具体实现对调用方没有任何影响。
降低结合度。 产品类的实例化通常很复杂,需要依赖于对调用方来说完全没有的许多类
如果使用工厂方法,则必须知道它只是实例化产品类并将其传递给调用方。 来呼叫方
我说产品依赖的类都是透明的。
工厂方法模式:
从工厂方法模式的类图中可以看到,工厂方法模式有四个元素:
工厂接口。 工厂接口是工厂方法模型的核心,它与调用方直接交互以提供产品。 在实际的编程中,有时
使用抽象类作为与调用方交互的接口在本质上是相同的。
工厂实现。 在编程中,工厂的实现是决定如何实例化产品、实现扩展的方法,决定需要多少种产品、需要多少
具体工厂很少。
产品界面。 产品接口的主要目的是定义产品规格,所有产品实现都必须遵循产品接口定义的规格。 产品
接口是调用方最关心的,产品接口定义的优劣直接决定了调用方代码的稳定性。 同样,也可以使用产品接口
虽然用抽象类代替,但请注意不要违反鲜艳的月份更换原则。
产品实现。 实现产品接口的具体类决定了产品在客户端中的具体行为。
前面提到的简单工厂模式与工厂方法模式非常相似。 区别在于,简单工厂只有三个要素。 他没有工厂的接口,而且
对产品的方法一般是静态的。 由于没有工厂接口,工厂实现的扩展性方面有点弱,工厂方法模式的
关于简化版、简单工厂型号,我带来了这里。
应用场景:
无论是单纯工厂模式、工厂方法模式还是抽象工厂模式,他们都有相似的特性,所以他们的适用场景也很相似
请参阅。
首先,作为创建类模式的方法,只要是需要生成复杂对象的地方,就可以使用工厂方法模式。 有需要注意的地方
也就是说,复杂的对象适合使用factory模型,但简单的对象(特别是只能通过new创建的对象)不需要使用factory
模式。 工厂模型需要部署工厂类,这增加了系统的复杂性。
其次,工厂模式是典型的解耦模式,ygdwx定律在工厂模式中表现得特别明显。 如果呼叫方需要自己组装产品
要增加依赖关系,请考虑使用工厂模型。 对象之间的结合度大幅降低。
再次,
由于工厂模式是依靠抽象架构的,它把实例化产品的任务交由实现类完成,扩展性比较好。也就是说,当需要系统有比较好的扩展性时,可以考虑工厂模式,不同的产品用不同的实现工厂来组装。
典型应用
要说明工厂模式的优点,可能没有比组装汽车更合适的例子了。场景是这样的:汽车由发动机、轮、底盘组
成,现在需要组装一辆车交给调用者。假如不使用工厂模式,代码如下:
class Engine {
public void getStyle(){
System.out.println("这是汽车的发动机");
}
}
class Underpan {
public void getStyle(){
System.out.println("这是汽车的底盘");
}
}
class Wheel {
public void getStyle(){
System.out.println("这是汽车的轮胎");
}
}
public class Client {
public static void main(String[] args) {
Engine engine = new Engine();
Underpan underpan = new Underpan();
Wheel wheel = new Wheel();
ICar car = new Car(underpan, wheel, engine);
car.show();
}
}
可以看到,调用者为了组装汽车还需要另外实例化发动机、底盘和轮胎,而这些汽车的组件是与调用者无关
的,严重违反了ygdwx法则,耦合度太高。并且非常不利于扩展。另外,本例中发动机、底盘和轮胎还是比较具
体的,在实际应用中,可能这些产品的组件也都是抽象的,调用者根本不知道怎样组装产品。假如使用工厂方法
的话,整个架构就显得清晰了许多。
interface IFactory {
public ICar createCar();
}
class Factory implements IFactory {
public ICar createCar() {
Engine engine = new Engine();
Underpan underpan = new Underpan();
Wheel wheel = new Wheel();
ICar car = new Car(underpan, wheel, engine);
return car;
}
}
public class Client {
public static void main(String[] args) {
IFactory factory = new Factory();
ICar car = factory.createCar();
car.show();
}
}
使用工厂方法后,调用端的耦合度大大降低了。并且对于工厂来说,是可以扩展的,以后如果想组装其他的汽
车,只需要再增加一个工厂类的实现就可以。无论是灵活性还是稳定性都得到了极大的提高。
抽象工厂模式:
抽象工厂模式
定义:为创建一组相关或相互依赖的对象提供一个接口,而且无需指定他们的具体类。
类型:创建类模式
类图:
抽象工厂模式与工厂方法模式的区别:
抽象工厂模式是工厂方法模式的升级版本,他用来创建一组相关或者相互依赖的对象。他与工厂方法模式的区别
就在于,工厂方法模式针对的是一个产品等级结构;而抽象工厂模式则是针对的多个产品等级结构。在编程
中,通常一个产品结构,表现为一个接口或者抽象类,也就是说,工厂方法模式提供的所有产品都是衍生自同一
个接口或抽象类,而抽象工厂模式所提供的产品则是衍生自不同的接口或抽象类。
在抽象工厂模式中,有一个产品族的概念:所谓的产品族,是指位于不同产品等级结构中功能相关联的产品组成
的家族。抽象工厂模式所提供的一系列产品就组成一个产品族;而工厂方法提供的一系列产品称为一个等级结
构。我们依然拿生产汽车的例子来说明他们之间的区别。
在上面的类图中,两厢车和三厢车称为两个不同的等级结构;而2.0排量车和2.4排量车则称为两个不同的产品
族。再具体一点,2.0排量两厢车和2.4排量两厢车属于同一个等级结构,2.0排量三厢车和2.4排量三厢车属于另
一个等级结构;而2.0排量两厢车和2.0排量三厢车属于同一个产品族,2.4排量两厢车和2.4排量三厢车属于另一
个产品族。
明白了等级结构和产品族的概念,就理解工厂方法模式和抽象工厂模式的区别了,如果工厂的产品全部属于同一
个等级结构,则属于工厂方法模式;如果工厂的产品来自多个等级结构,则属于抽象工厂模式。在本例中,如果
一个工厂模式提供2.0排量两厢车和2.4排量两厢车,那么他属于工厂方法模式;如果一个工厂模式是提供2.4排量
两厢车和2.4排量三厢车两个产品,那么这个工厂模式就是抽象工厂模式,因为他提供的产品是分属两个不同的等
级结构。当然,如果一个工厂提供全部四种车型的产品,因为产品分属两个等级结构,他当然也属于抽象工厂模
式了。
interface IProduct1 {
public void show();
}
interface IProduct2 {
public void show();
}
class Product1 implements IProduct1 {
public void show() {
System.out.println("这是1型产品");
}
}
class Product2 implements IProduct2 {
public void show() {
System.out.println("这是2型产品");
}
}
interface IFactory {
public IProduct1 createProduct1();
public IProduct2 createProduct2();
}
class Factory implements IFactory{
public IProduct1 createProduct1() {
return new Product1();
}
public IProduct2 createProduct2() {
return new Product2();
}
}
public class Client {
public static void main(String[] args){
IFactory factory = new Factory();
factory.createProduct1().show();
factory.createProduct2().show();
}
}
抽象工厂模式的优点
抽象工厂模式除了具有工厂方法模式的优点外,最主要的优点就是可以在类的内部对产品族进行约束。所谓的产
品族,一般或多或少的都存在一定的关联,抽象工厂模式就可以在类内部对产品族的关联关系进行定义和描
述,而不必专门引入一个新的类来进行管理。
抽象工厂模式的缺点
产品族的扩展将是一件十分费力的事情,假如产品族中需要增加一个新的产品,则几乎所有的工厂类都需要进行
修改。所以使用抽象工厂模式时,对产品等级结构的划分是非常重要的。
适用场景
当需要创建的对象是一系列相互关联或相互依赖的产品族时,便可以使用抽象工厂模式。说的更明白一点,就是
一个继承体系中,如果存在着多个等级结构(即存在着多个抽象类),并且分属各个等级结构中的实现类之间存
在着一定的关联或者约束,就可以使用抽象工厂模式。假如各个等级结构中的实现类之间不存在关联或约束,则
使用多个独立的工厂来对产品进行创建,则更合适一点。
总结
无论是简单工厂模式,工厂方法模式,还是抽象工厂模式,他们都属于工厂模式,在形式和特点上也是极为相似
的,他们的最终目的都是为了解耦。在使用时,我们不必去在意这个模式到底工厂方法模式还是抽象工厂模
式,因为他们之间的演变常常是令人琢磨不透的。经常你会发现,明明使用的工厂方法模式,当新需求来临,稍
加修改,加入了一个新方法后,由于类中的产品构成了不同等级结构中的产品族,它就变成抽象工厂模式了;而
对于抽象工厂模式,当减少一个方法使的提供的产品不再构成产品族之后,它就演变成了工厂方法模式。
所以,在使用工厂模式时,只需要关心降低耦合度的目的是否达到了。
第 1 章 23 种设计模式 | 15