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

要想正确的理解设计模式,首先必须明确它是为了解决什么问题而提出来的。

抽象工厂设计模式概念:

针对抽象工厂这个设计模式,我查找了不少资料,感觉只有涉及产品级别和产品族的才是理解了抽象工厂设计模式的精髓,工厂方法模式针对的是一个产品等级结构;而抽象工厂模式针对的是多个产品等级结构。有些观点认为抽象工厂模式是为了解决客户端代码与工厂类的耦合问题,我认为这种观点的解决方案只是简单工厂模式的一个应用,而这种观点认为的抽象工厂模式是:

工厂模式+简单工厂模式=抽象工厂模式,这是不正确。

针对的问题:

针对多个产品等级结构。相对工厂模式针对的是一个产品等级结构。

例子描述

我们通过一个简单的例子来解释抽象设计模式,同时这个例子贯穿全文:

—————————————————————————————————————————————————————————

组装电脑,我们在组装电脑的时候,通常需要选择一系列的配件,比如CPU、硬盘、内存、主板、电源、机箱等。为讨论使用简单点,只考虑选择CPU和主板的问题。

  事实上,在选择CPU的时候,面临一系列的问题,比如品牌、型号、针脚数目、主频等问题,只有把这些问题都确定下来,才能确定具体的CPU。

  同样,在选择主板的时候,也有一系列问题,比如品牌、芯片组、集成芯片、总线频率等问题,也只有这些都确定了,才能确定具体的主板。

  选择不同的CPU和主板,是每个客户在组装电脑的时候,向装机公司提出的要求,也就是我们每个人自己拟定的装机方案。

  在最终确定这个装机方案之前,还需要整体考虑各个配件之间的兼容性。比如:CPU和主板,如果使用Intel的CPU和AMD的主板是根本无法组装的。因为Intel的CPU针脚数与AMD主板提供的CPU插口不兼容,就是说如果使用Intel的CPU根本就插不到AMD的主板中,所以装机方案是整体性的,里面选择的各个配件之间是有关联的。

  对于装机工程师而言,他只知道组装一台电脑,需要相应的配件,但是具体使用什么样的配件,还得由客户说了算。也就是说装机工程师只是负责组装,而客户负责选择装配所需要的具体的配件。因此,当装机工程师为不同的客户组装电脑时,只需要根据客户的装机方案,去获取相应的配件,然后组装即可。

—————————————————————————————————————————————————————————

两个基本概念:

在学习抽象工厂具体实例之前需要了解2个基本概念:产品族和产品等级。

所谓产品族,是指位于不同产品等级结构中,功能相关联的产品组成的家族。比如AMD的主板、芯片组、CPU组成一个家族,Intel的主板、芯片组、CPU组成一个家族。

而这两个家族都来自于三个产品等级:主板、芯片组、CPU。一个等级结构是由相同的结构的产品组成,示意图如下:

针对上述的例子进行程序设计,采用工厂模式和抽象工厂模式有什么区别?

工厂模式:

上面所给出的三个不同的等级结构具有平行的结构。因此,如果采用工厂方法模式,就势必要使用三个独立的工厂等级结构来对付这三个产品等级结构。由于这三个产品等级结构的相似性,会导致三个平行的工厂等级结构。随着产品等级结构的数目的增加,工厂方法模式所给出的工厂等级结构的数目也会随之增加。如下图:

抽象工厂模式:

通过上面两幅图,可以看出,一个工厂等级结构可以创建出分属于不同产品等级结构的一个产品族中的所有对象。显然,这时候抽象工厂模式比简单工厂模式、工厂方法模式更有效率。对应于每一个产品族都有一个具体工厂。而每一个具体工厂负责创建属于同一个产品族,但是分属于不同等级结构的产品。

用抽象工厂模式设计类图如下:

源代码如下:

抽象组件Cpu

public interface Cpu {
	public void calculate();
}

具体组件IntelCpu和AmdCpu

public class IntelCpu implements Cpu {
	private int pins;	//表示CPU的脚针数
	public IntelCpu(int pins){
		this.pins = pins;
	}
	@Override
	public void calculate() {
		System.out.println("Intel CPU的脚针数目:"+pins);
	}

}
public class AmdCpu implements Cpu {
	private int pins;
	public AmdCpu(int pins){
		this.pins = pins;
	}
	@Override
	public void calculate() {
		System.out.println("CMD CPU的脚针数目:"+pins);
	}

}

抽象组件MainBoard

public interface MainBoard {
	public void installCpu();
}

具体组件IntelMainBoard和AmdMainBoard

public class IntelMainBoard implements MainBoard {
	private int cpuHoles;	//表示主板上的CPU插槽孔数,对应脚针数
	public IntelMainBoard(int cpuHoles){
		this.cpuHoles = cpuHoles;
	}
	@Override
	public void installCpu() {
		System.out.println("Intel主板上的CPU插槽孔数:"+cpuHoles);
	}

}
public class AmdMainBoard implements MainBoard {
	private int cpuHoles;
	public AmdMainBoard(int cpuHoles){
		this.cpuHoles = cpuHoles;
	}
	@Override
	public void installCpu() {
		System.out.println("AMD主板上的CPU插槽孔数:"+cpuHoles);
	}

}

设置抽象工厂AbstractFactory,不负责制造具体的产品:

public interface AbstractFactory {
	/**
	 * 创建Cpu对象
	 * @return Cpu对象
	 */
	public Cpu createCpu();
	/**
	 * 创建MainBoard对象
	 * @return MainBoard对象
	 */
	public MainBoard creatMainBoard();
}

设计具体工厂,对应生成Intel和Amd品牌的CPU和主板

/**
 * 用来创建与Intel相关的所有产品
 */
public class IntelFactory implements AbstractFactory {
	@Override
	public Cpu createCpu() {
		// TODO Auto-generated method stub
		return new IntelCpu(555);
	}
	@Override
	public MainBoard creatMainBoard() {
		// TODO Auto-generated method stub
		return new IntelMainBoard(555);
	}

}
/**
 * 用来创建AMD下系列产品
 */
public class AmdFactory implements AbstractFactory {

	@Override
	public Cpu createCpu() {
		return new AmdCpu(8888);
	}
	@Override
	public MainBoard creatMainBoard() {
		return new AmdMainBoard(8888);
	}

}

我们的装机工程师只需要进行装机操作,但是具体装哪一个系列的产品,由用户来决定:

ComputerEngineer

public class ComputerEngineer {
	private Cpu cpu = null;
	private MainBoard mainBoard = null;

	public void makeComputer(AbstractFactory af){
		//1.准备装机的硬件
		this.prepareHardWares(af);
		//2.组装机器
		//3.测试机器
		//4.交付客户
	}
	public void prepareHardWares(AbstractFactory af){
		this.cpu = af.createCpu();				//准备CPU,但是不关心是什么CPU
		this.mainBoard = af.creatMainBoard();	//准备主板,也不关心是什么主板
		//查看槽孔是否和脚针数目匹配
		this.cpu.calculate();
		this.mainBoard.installCpu();
	}
}

客户端Client

public class Client {

	public static void main(String[] args) {
		ComputerEngineer cEngineer = new ComputerEngineer();
		AbstractFactory intelFactory = new IntelFactory();	//客户选定某类具体工厂,工厂负责成产匹配的组件
		cEngineer.makeComputer(intelFactory);				//工程师开始组装
	}

}

抽象工厂的功能是为一系列相关对象或相互依赖的对象创建一个接口。一定要注意,这个接口内的方法不是任意堆砌的,而是一系列相关或相互依赖的方法。比如上面例子中的主板和CPU,都是为了组装一台电脑的相关对象。不同的装机方案,代表一种具体的电脑系列。

由于抽象工厂定义的一系列对象通常是相关或相互依赖的,这些产品对象就构成了一个产品族,也就是抽象工厂定义了一个产品族。

  这就带来非常大的灵活性,切换产品族的时候,只要提供不同的抽象工厂实现就可以了,也就是说现在是以一个产品族作为一个整体被切换。

使用情形:

1.一个系统不应当依赖于产品类实例如何被创建、组合和表达的细节,这对于所有形态的工厂模式都是重要的。

2.这个系统的产品有多于一个的产品族,而系统只消费其中某一族的产品。

3.同属于同一个产品族的产品是在一起使用的,这一约束必须在系统的设计中体现出来。(比如:Intel主板必须使用Intel CPU、Intel
     芯片组)

4.系统提供一个产品类的库,所有的产品以同样的接口出现,从而使客户端不依赖于实现。

优点:

1、 分离接口和实现

  客户端使用抽象工厂来创建需要的对象,而客户端根本就不知道具体的实现是谁,客户端只是面向产品的接口编程而已。也就是说,客户端从具体的产品实现中解耦。

2、 使切换和添加产品族变得容易

  因为一个具体的工厂实现代表的是一个产品族,比如上面例子的从Intel系列到AMD系列只需要切换一下具体工厂。我也可以再添加一个新的装机方案,一个新的产品族,都是很方便的。

不足:

不容易扩展新的产品等级,比如我要加一个硬盘、内存什么的。那么就需要修改抽象工厂,这样就会导致修改所有的工厂实现类。

(原文地址:http://blog.csdn.net/zhshulin/article/details/38349211

设计模式——抽象工厂模式学习,布布扣,bubuko.com

时间: 08-01

设计模式——抽象工厂模式学习的相关文章

创建型-抽象工厂模式学习

1.抽象工厂模式的意图: 提供一个创建一系列相关或相互依赖对象的接口,而无需指定它们具体的类. 2.抽象工厂模式的适用性: 一个系统要独立于它的产品的创建.组合和表示时. 一个系统要由多个产品系列中的一个来配置时. 当你要强调一系列相关的产品对象的设计以便进行联合使用时. 当你提供一个产品类库,而只想显示它们的接口而不是实现时. 3.场景描述: 考虑一个生产多种不同风格的家具的工厂(FurnitureFactory),不同风格的家具系列可以提供不同的门.窗.地板等的组合,为同一所住房可以提供不同

设计模式-抽象工厂模式(C#)

设计模式--抽象工厂模式(JAVA) 在抽象工厂模式中,一个具体工厂可以生产一组相关的具体产品,这样的一组产品成为产品族,产品族中的每一个产品都属于某一个产品继承等等级结构.当系统所提供的工厂生产的具体产品并不是一个简单的对象,而是多个位于不同产品等级结构.属于不同类型的具体产品时就可以使用抽象工厂模式. 抽象工厂模式与工厂方法模式最大的区别在于,工厂方法模式针对的是一个产品等级结构,而抽象工厂模式需要面对多个产品等级结构,一个工厂等级结构可以负责多个不同产品等级结构中的产品对象的创建,当一个工

JAVA设计模式--抽象工厂模式

抽象工厂设计模式 1.系统中有多个产品族,而系统一次只可能消费其中一族产品2.同属于同一个产品族的产品以其使用.来看看抽象工厂模式的各个角色(和工厂方法的如出一辙):抽象工厂角色: 这是工厂方法模式的核心,它与应用程序无关.是具体工厂角色必须实现的接口或者必须继承的父类.在java中它由抽象类或者接口来实现.具体工厂角色:它含有和具体业务逻辑有关的代码.由应用程序调用以创建对应的具体产品的对象.在java中它由具体的类来实现.抽象产品角色:它是具体产品继承的父类或者是实现的接口.在java中一般

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

抽象工厂模式(Abstract Factory Pattern)是属于创建型的设计模式,意在创造一个抽象的工厂,而后再由实例化出的具体的工厂来进行生产. 何时使用:系统的产品有多于一个的产品族,而系统只消费其中某一族的产品. 应用实例:工作了,为了参加一些聚会,肯定有两套或多套衣服吧,比如说有商务装(成套,一系列具体产品).时尚装(成套,一系列具体产品),甚至对于一个家庭来说,可能有商务女装.商务男装.时尚女装.时尚男装,这些也都是成套的,即一系列具体产品.假设一种情况(现实中是不存在的,要不然

24种设计模式--抽象工厂模式【Abstract Factory Pattern】

女娲造人,人是造出来了,世界是热闹了,可是低头一看,都是清一色的类型,缺少关爱.仇恨.喜怒哀乐等情绪,人类的生命太平淡了,女娲一想,猛然一拍脑袋,忘记给人类定义性别了,那怎么办?抹掉重来,然后就把人类重新洗牌,准备重新开始制造人类. 由于先前的工作已经花费了很大的精力做为铺垫,也不想从头开始了,那先说人类(Product 产品类)怎么改吧,好,有了,给每个人类都加一个性别,然后再重新制造,这个问题解决了,那八卦炉怎么办?只有一个呀,要么生产出全都是男性,要不都是女性,那不行呀,有了,把已经有了一

Java与设计模式-抽象工厂模式

首先说明,文章较长,保证你有耐心看完肯定能懂,没耐心直接点×即可. 抽象工厂模式,是创建型设计模式之一.抽象型工厂模式适合产品确定,产品线不确定的类型,怎么讲?通过一个具体例子来讲一下吧.例如某电脑厂商要生产电脑,也就是电脑这个产品确定,而电脑配置不确定,这种情况可以用抽象工厂模式来解决.类图如图所示: 代码实现完全结合UML类图,结合图就可以完成系统创建. 本实例里是抽象类ComputerFactory(对应UML类图中的AbstractFactory): package com.factor

设计模式:抽象工厂模式

原文地址:http://leihuang.org/2014/12/03/abstract-factory/ Creational 模式 物件的产生需要消耗系统资源,所以如何有效率的产生.管理 与操作物件,一直都是值得讨论的课题, Creational 模式即与物件的建立相关,在这个分类下的模式给出了一些指导原则及设计的方向.下面列举到的全属于Creational 模式 Simple Factory 模式 Abstract Factory 模式 Builder 模式 Factory Method

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

一.引言 在上一专题中介绍了工厂方法模式,工厂方法模式是为了克服简单工厂模式的缺点而设计出来的,简单工厂模式的工厂类随着产品类的增加需要增加额外的代码),而工厂方法模式每个具体工厂类只完成单个实例的创建,所以它具有很好的可扩展性.但是在现实生活中,一个工厂只创建单个产品这样的例子很少,因为现在的工厂都多元化了,一个工厂创建一系列的产品,如果我们要设计这样的系统时,工厂方法模式显然在这里不适用,然后抽象工厂模式却可以很好地解决一系列产品创建的问题,这是本专题所要介绍的内容. 二.抽象工厂详细介绍

c++设计模式-----抽象工厂模式

抽象工厂模式 要创建一组相关或者相互依赖的对象 作用:提供一个创建一系列相关或相互依赖对象的接口,而无需指定它们具体的类. UML类图 抽象基类: 1)AbstractProductA.AbstractProductB:分别代表两种不同类型的产品,由具体的产品派生类对其实现 2)AbstractFactory:抽象工厂类,提供创建两种产品的接口CreateProductA和CreateProductB,由派生的各个具体工厂类对其实现 说明: AbstractFactory模式关键就是将这一组对象