`

设计模式——抽象工厂模式

阅读更多

写在前面

看了一下自己的博客,从15年开通(那时候大三)到现在(刚刚毕业)已经1年半了,大三开始就一直忙着各种比赛,靠熟人朋友接一些小项目,然后去年大四一年就来杭州实习,开发一个新的物流项目,然后从长沙到杭州,也遇到了很多老朋友,然后经常出去玩一玩就把博客放一边了,今天回过头来看,发现当年要写的面向对象设计模式的系列居然还一直没有更新,觉得深感惭愧,虽说这类型的在网上已经不少了,但总归来说对自己未来的发展还是有帮助的,所以打算还是坚持下来,继续写下去了。

 

言归正传,今天要介绍的是设计模式中的抽象工厂模式,属于创建型模式。在工厂方法模式中具体工厂负责生产具体的产品,每一个具体工厂对应一种具体产品,工厂方法也具有唯一性,一般情况下,一个具体工厂中只有一个工厂方法或者一组重载的工厂方法。但是有时候我们需要一个工厂可以提供多个产品对象,而不是单一的产品对象。这个时候工厂方法模式就显得不那么好用了。

 

一、抽象工厂模式动机

为了更清晰地理解抽象工厂模式,需要先引入两个概念:

1.产品等级结构:产品等级结构即产品的继承结构,如一个抽象类是电视机,其子类有海尔电视机、海信电视机、TCL电视机,则抽象电视机与具体品牌的电视机之间构成了一个产品等级结构,抽象电视机是父类,而具体品牌的电视机是其子类。

2.产品族:在抽象工厂模式中,产品族是指由同一个工厂生产的,位于不同产品等级结构中的一组产品,如海尔电器工厂生产的海尔电视机、海尔电冰箱,海尔电视机位于电视机产品等级结构中,海尔电冰箱位于电冰箱产品等级结构中。 

产品族与产品等级结构的关系可用下面这张图来说明:



 这个时候我们再来看一个例子,还是上一篇工厂方法模式文章中电视机那个例子,假设海尔公司除了生产电视机外,还生产空调,TCL公司也可以生产空调,这个时候如果使用工厂方法模式的话,就不能把就得再来个新的空调产品工厂,而这两个工厂(电视机工厂和空调工厂)彼此间没有联系,而实际情况是,空调和电视都是由海尔生产或者海信生产的,这时候抽象工厂模式的优势就来了。

 

二、抽象工厂模式定义

抽象工厂模式(Abstract Factory Pattern):提供一个创建一系列相关或相互依赖对象的接口,而无须指定它们具体的类。抽象工厂模式又称为Kit模式,属于对象创建型模式。

 

三、抽象工厂模式的结构

抽象工厂模式包含如下角色:

AbstractFactory:抽象工厂

ConcreteFactory:具体工厂

AbstractProduct:抽象产品

Product:具体产品



 

 

四、模式分析

抽象工厂模式需要具备以下几点:

1.当系统所提供的工厂所需生产的具体产品并不是一个简单的对象,而是多个位于不同产品等级结构中属于不同类型的具体产品时需要使用抽象工厂模式。

2.抽象工厂模式是所有形式的工厂模式中最为抽象和最具一般性的一种形态。

3.抽象工厂模式与工厂方法模式最大的区别在于,工厂方法模式针对的是一个产品等级结构,而抽象工厂模式则需要面对多个产品等级结构,一个工厂等级结构可以负责多个不同产品等级结构中的产品对象的创建 。当一个工厂等级结构可以创建出分属于不同产品等级结构的一个产品族中的所有对象时,抽象工厂模式比工厂方法模式更为简单、有效率。

抽象工厂模式示意图如下:


 

五、实例分析

还是拿电器厂的例子来说,一个电器工厂可以产生多种类型的电器,如海尔工厂可以生产海尔电视机、海尔空调等,TCL工厂可以生产TCL电视机、TCL空调等,相同品牌的电器构成一个产品族,而相同类型的电器构成了一个产品等级结构,现使用抽象工厂模式模拟该场景。

分析该场景我们可以知道,海尔和TCL是具体的工厂,所以需要有一个共有的抽象工厂出来,同时每个工厂都可以生产电视和空调,所以电视和空调就是每个工厂的产品族,而海尔的电视和TCL的电视又构成了产品的等级结构,所以需要电视和空调的共有抽象类。

1.抽象产品类——电视(接口)

 

public interface Television {
	public void show();
}
 
2.抽象产品类——空调(接口)

 

 

public interface AirConditioner {
	public void changeTemperature();
}
 
3.用于生产一个产品族的抽象工厂类(接口)

 

 

public interface EFactory {
	public Television produceTelevison();
	public AirConditioner produceAirConditioner();
}
 
4.具体的产品类——海尔电视、海尔空调、TCL电视、TCL空调

 

 

public class HaierTelevision implements Television {
	@Override
	public void show() {
		System.out.println("我是海尔电视");
	}
}
 
public class HaierAirConditioner implements AirConditioner {
	@Override
	public void changeTemperature() {
		System.out.println("海尔空调调整温度了");
	}
}
 
public class TCLTelevision implements Television {
	@Override
	public void show() {
		System.out.println("我是TCL电视");
	}
}
 
public class TCLAirConditioner implements AirConditioner {
	@Override
	public void changeTemperature() {
		System.out.println("TCL空调调整温度了");
	}
}
 

 

5.具体的工厂类——海尔产品族生产车间和TCL产品族生产车间

 

public class HaierFactory implements EFactory {

	@Override
	public Television produceTelevison() {
		return new HaierTelevision();
	}

	@Override
	public AirConditioner produceAirConditioner() {
		return new HaierAirConditioner();
	}

}
 
public class TCLFactory implements EFactory {

	@Override
	public Television produceTelevison() {
		return new TCLTelevision();
	}

	@Override
	public AirConditioner produceAirConditioner() {
		return new TCLAirConditioner();
	}

}
 
6.创建客户端进行测试

 

 

public class Test {

	public static void main(String[] args) {
		// 声明一个抽象工厂
		EFactory eFactory;
		// 声明一个抽象的产品族,即:声明一个电视机抽象类和一个空调抽象类
		Television tv;
		AirConditioner airConditioner;
		// 创建具体的工厂子类,如海尔生产这个产品族,并向上转型给父类
		eFactory = new HaierFactory();
		// 调用生产的方法
		tv = eFactory.produceTelevison();
		airConditioner = eFactory.produceAirConditioner();
		// 调用产品自己的方法
		tv.show();
		airConditioner.changeTemperature();
	}
	
}
 7.模式优势

 

通过以上6点,我们用抽象工厂模式设计了一个模拟电视和空调产品族的场景,现在假设我们需要更改产品族,不再使用海尔(即第6点中的HaierFactory对象),而是需要改成TCL来生产产品族,此时,我们只需要把具体的工厂类替换成TCLFactory即可,具体可看以下代码:

 

public class Test {

	public static void main(String[] args) {
		// 声明一个抽象工厂
		EFactory eFactory;
		// 声明一个抽象的产品族,即:声明一个电视机抽象类和一个空调抽象类
		Television tv;
		AirConditioner airConditioner;
		// 创建具体的工厂子类,如TCL生产这个产品族,并向上转型给父类
		eFactory = new TCLFactory();
		// 调用生产的方法
		tv = eFactory.produceTelevison();
		airConditioner = eFactory.produceAirConditioner();
		// 调用产品自己的方法
		tv.show();
		airConditioner.changeTemperature();
	}
	
}
可以发现,此时我们只需要改eFactory = new HaierFactory();这一行代码,将HaierFactory()改成TCLFatory()即可。如果使用java的反射机制和XML文档的结合,还可以这么写:

 

tvf = (EFactory)XMLUtil.getBean(); //getBean()的返回类型

这样一来只需要修改XML中的名字,连java文件都不需要改动,很好的符号了“开闭原则”。

 

六、抽象工厂模式缺点

当一个产品族中的多个对象被设计成一起工作时,抽象工厂模式能够保证客户端始终只使用同一个产品族中的对象。这对一些需要根据当前环境来决定其行为的软件系统来说,是一种非常实用的设计模式。但是,在添加新的产品对象时,难以扩展抽象工厂来生产新种类的产品,这是因为在抽象工厂角色中规定了所有可能被创建的产品集合,要支持新种类的产品就意味着要对该接口进行扩展,而这将涉及到对抽象工厂角色及其所有子类的修改,显然会带来较大的不便。具体如下:

(1) 增加产品族:对于增加新的产品族,工厂方法模式很好的支持了“开闭原则”,对于新增加的产品族,只需要对应增加一个新的具体工厂即可,对已有代码无须做任何修改。

(2) 增加新的产品等级结构:对于增加新的产品等级结构,需要修改所有的工厂角色,包括抽象工厂类,在所有的工厂类中都需要增加生产新产品的方法,不能很好地支持“开闭原则”。

 

抽象工厂模式的这种性质称为“开闭原则”的倾斜性,抽象工厂模式以一种倾斜的方式支持增加新的产品,它为新产品族的增加提供方便,但不能为新的产品等级结构的增加提供这样的方便。



最后,当抽象工厂模式中每一个具体工厂类只创建一个产品对象,也就是只存在一个产品等级结构时,抽象工厂模式退化成工厂方法模式;当工厂方法模式中抽象工厂与具体工厂合并,提供一个统一的工厂来创建产品对象,并将创建对象的工厂方法设计为静态方法时,工厂方法模式退化成简单工厂模式。

 

谢谢您的关注和阅读,文章不当之处还请您不吝赐教~~~微笑微笑微笑

  • 大小: 23.1 KB
  • 大小: 29.5 KB
  • 大小: 83.8 KB
分享到:
评论

相关推荐

    软件设计模式——抽象工厂

    在学习和应用抽象工厂模式时,理解其核心思想——封装变化和解耦,以及如何在实际项目中选择合适的场景使用这一模式,是非常关键的。对于软件工程专业的学生来说,掌握这一模式不仅可以提升编程能力,还能提高对软件...

    设计模式实现——抽象工厂模式结构实现

    抽象工厂模式是设计模式中的一种创建型模式,它提供了一种创建对象集合的接口,而无需指定具体的类。这种模式允许客户端使用一个通用接口来创建一组相关或相互依赖的对象,而无需关心它们的具体实现。在Java或其他...

    Android之大话设计模式——:抽象工厂模式借鉴.pdf

    Android之大话设计模式——:抽象工厂模式借鉴.pdf

    Android之大话设计模式——:抽象工厂模式参考.pdf

    Android之大话设计模式——:抽象工厂模式参考.pdf

    格斗类游戏软件——抽象工厂模式

    抽象工厂模式是一种设计模式,属于创建型模式,它提供了一种创建对象集合的方式,这些对象来自相关联的产品家族,而且每个对象都属于不同的抽象产品类。在“格斗类游戏软件”的场景中,这个模式可以帮助我们根据玩家...

    c#工厂模式——简单工厂,抽象工厂,单件模式实例

    抽象工厂模式则更进一步,它提供了一个创建一系列相关或相互依赖对象的接口,而无需指定它们的具体类。在多线程或者跨平台的C#应用中,抽象工厂可以帮助我们隔离产品族,使得更换产品族变得容易。例如,我们可以有...

    c#工厂模式——简单工厂_抽象工厂实例

    根据应用场景的不同,工厂模式可以进一步分为简单工厂模式、工厂方法模式以及抽象工厂模式。 #### 二、简单工厂模式 简单工厂模式是最基础的工厂模式实现方式,它的主要特点是使用一个工厂类来负责创建所有产品...

    设计模式——简单工厂模式

    **设计模式——简单工厂模式** 简单工厂模式是创建型设计模式的一种,它提供了一种创建对象的最佳方式。在简单工厂模式中,一个专门的类(称为工厂类)负责创建对象,客户端无需知道所创建的对象的具体类,只需要...

    Python设计模式之抽象工厂模式原理与用法详解

    本文实例讲述了Python设计模式之抽象工厂模式原理与用法。...设计模式——抽象工厂模式 抽象工厂模式(Abstract Factory Pattern):提供一个创建一系列相关或相互依赖对象的接口,而无需指定它们的类 import sys #抽

    设计模式——工厂方法模式

    工厂方法模式是面向对象设计模式中的一种,它属于创建型模式,主要解决的是当系统需要创建的对象具有多种类型,而具体创建哪种类型的对象在运行时才能确定的问题。在这个压缩包中,`FactoryMethod`可能包含了Java...

    设计模式——简单工厂 VS 工厂方法

    工厂方法模式则更进一步,它属于抽象工厂模式的一种特殊形式。在这个模式中,我们定义一个创建对象的接口,但让子类决定实例化哪一个类。工厂方法将类的实例化推迟到子类。这样,工厂方法模式使得系统在不指定具体...

    NET设计模式之抽象工厂模式[归纳].pdf

    通过更换模具,同一台设备可以快速切换生产不同车型的零件,这就是抽象工厂模式的核心思想——封装变化。 在虚拟案例中,我们有一个名为Softo的软件系统,用于计算员工的工资。在中国,员工工资的计算规则是固定的...

    实验二 简单工厂模式.zip_31QS_C#_设计模式——简单工厂模式_设计模式实验

    简单工厂模式是软件设计模式中的一种基础模式,它属于创建型模式,主要解决对象的创建问题,降低了客户端代码与具体产品类之间的耦合度。在本实验中,我们将深入理解和应用C#语言实现简单工厂模式。 简单工厂模式的...

    抽象工厂模式+工厂方法模式+策略模式+类图实现手机加工厂

    本文将探讨三个重要的设计模式:抽象工厂模式、工厂方法模式以及策略模式,并结合一个实际的场景——手机加工厂,来具体阐述它们的应用。 首先,我们来看**抽象工厂模式**。这个模式主要用于创建相关或依赖对象的...

    Java设计模式-抽象工厂

    **Java设计模式——抽象工厂** 在软件工程中,设计模式是一种在特定场景下解决常见问题的模板或蓝图。抽象工厂模式是设计模式中的一种结构型模式,它提供了一个创建对象族的接口,但允许子类决定实例化哪一个类。这...

    SETema5:软件设计模式——抽象工厂

    抽象工厂模式是软件设计模式中的一种,它是工厂方法模式的扩展,主要解决的是当系统需要创建一系列相关或相互依赖的对象时,而无需指定它们的具体类。这种模式的关键在于提供一个接口,使得客户端可以创建一系列相关...

    设计模式——GFour

    创建型模式主要关注对象的创建过程,包括单例模式、工厂模式、抽象工厂模式、建造者模式和原型模式。它们旨在提供一种方式来封装对象的创建,使得系统对对象的实例化过程更加灵活,同时降低类间的耦合度。 结构型...

    几个设计模式c++实现源码

    以下是对标题和描述中提到的三个设计模式——抽象工厂模式、适配器模式和外观模式的详细解释: 1. 抽象工厂模式: 抽象工厂模式是一种创建型设计模式,它提供一个接口来创建相关或依赖对象的家族,而无需指定它们的...

    从哲学角度学习设计模式-抽象工厂

    总的来说,"从哲学角度学习设计模式-抽象工厂"这个主题旨在将哲学思考融入到软件设计中,通过抽象工厂模式,我们不仅可以理解如何构建灵活、可扩展的系统,还能体会到哲学思想如何影响并指导我们的编程实践。...

Global site tag (gtag.js) - Google Analytics