- 浏览: 534741 次
- 性别:
- 来自: 杭州
文章分类
最新评论
-
wa114d:
楼主工作几年了,好厉害
一个面试官对面试问题的分析 -
wobuxiaole:
Good,非常好
30岁前男人需要完成的事 -
小逗逗:
Good,非常好
30岁前男人需要完成的事 -
invincibleLiu:
好帖,要顶!(别投我隐藏啊,这是对BBS最原始一种支持)
Java:synchronized修饰符在静态方法与非静态方法上的区别 -
fayedShih:
第三题,不知道对不对
import java.util.con ...
企业牛逼面试题目 高手进来讨论答题
抽象工厂模式(Abstract Factory)
1.1 场景问题
1.1.1 选择组装电脑的配件
举个生活中常见的例子——组装电脑,我们在组装电脑的时候,通常需要选择一系列的配件,比如:CPU、硬盘、内存、主板、电源、机箱等等。为了使讨论简单点,只考虑选择CPU和主板的问题。
事实上,我们在选择CPU的时候,面临一系列的问题,比如:品牌、型号、针脚数目、主频等问题,只有把这些都确定下来,才能确定具体的CPU。
同样,在选择主板的时候,也有一系列的问题,比如:品牌、芯片组、集成芯片、总线频率等问题,也只有这些都确定了,才能确定具体的主板。
选择不同的CPU和主板,是每个客户去组装电脑的时候,向装机公司提出的要求,也就是我们每个人自己拟定的装机方案。
在最终确定这个装机方案之前,还需要整体考虑各个配件之间的兼容性,比如:CPU和主板,如果CPU针脚数和主板提供的CPU插口不兼容,是无法组装的。也就是说,装机方案是有整体性的,里面选择的各个配件之间是有关联的。
对于装机工程师而言,他只知道组装一台电脑,需要相应的配件,但是具体使用什么样的配件,还得由客户说了算。也就是说装机工程师只是负责组装,而客户负责选择装配所需要的具体的配件。因此,当装机工程师为不同的客户组装电脑时,只需要按照客户的装机方案,去获取相应的配件,然后组装即可。
现在需要使用程序来把这个装机的过程,尤其是选择组装电脑配件的过程实现出来,该如何实现呢?
1.1.2 不用模式的解决方案
考虑客户的功能,需要选择自己需要的CPU和主板,然后告诉装机工程师自己的选择,接下来就等着装机工程师组装机器了。
对装机工程师而言,只是知道CPU和主板的接口,而不知道具体实现,很明显可以用上简单工厂或工厂方法模式,为了简单,这里选用简单工厂吧。客户告诉装机工程师自己的选择,然后装机工程师会通过相应的工厂去获取相应的实例对象。
(1)先来看看CPU和主板的接口,先看CPU的接口定义,示例代码如下:
再看看主板的接口定义,示例代码如下:
(2)接下来看看具体的CPU实现,先看Intel的CPU实现,示例代码如下:
再看看AMD的CPU实现,示例代码如下:
(3)接下来看看具体的主板实现,先看技嘉的主板实现,示例代码如下:
再看看微星的主板实现,示例代码如下:
(4)接下来看看创建CPU和主板的工厂,先看创建CPU的工厂实现,示例代码如下:
再看看创建主板的工厂实现,示例代码如下:
(5)接下来看看装机工程师的实现,示例代码如下:
(6)看看此时的客户端,应该通过装机工程师来组装电脑,客户需要告诉装机工程师他选择的配件,示例代码如下:
运行结果如下:
1.1.3 有何问题
看了上面的实现,会感觉到很简单嘛,通过使用简单工厂来获取需要的CPU和主板对象,然后就可以组装电脑了。有何问题呢?
虽然上面的实现,通过简单工厂解决解决了:对于装机工程师,只知CPU和主板的接口,而不知道具体实现的问题。但还有一个问题没有解决,什么问题呢?那就是这些CPU对象和主板对象其实是有关系的,是需要相互匹配的。而在上面的实现中,并没有维护这种关联关系,CPU和主板是由客户随意选择的。这是有问题的。
比如在上面实现中的客户端,在调用makeComputer时,传入参数为(1,2),试试看,运行结果就会如下:
观察上面的结果,你就会看出问题来了,客户选择的CPU的针脚是1156针的,而选择的主板上的CPU插孔却只有939针,根本无法组装。这就是没有维护配件之间的关系造成的。
该怎么解决这个问题呢?
1.1 场景问题
1.1.1 选择组装电脑的配件
举个生活中常见的例子——组装电脑,我们在组装电脑的时候,通常需要选择一系列的配件,比如:CPU、硬盘、内存、主板、电源、机箱等等。为了使讨论简单点,只考虑选择CPU和主板的问题。
事实上,我们在选择CPU的时候,面临一系列的问题,比如:品牌、型号、针脚数目、主频等问题,只有把这些都确定下来,才能确定具体的CPU。
同样,在选择主板的时候,也有一系列的问题,比如:品牌、芯片组、集成芯片、总线频率等问题,也只有这些都确定了,才能确定具体的主板。
选择不同的CPU和主板,是每个客户去组装电脑的时候,向装机公司提出的要求,也就是我们每个人自己拟定的装机方案。
在最终确定这个装机方案之前,还需要整体考虑各个配件之间的兼容性,比如:CPU和主板,如果CPU针脚数和主板提供的CPU插口不兼容,是无法组装的。也就是说,装机方案是有整体性的,里面选择的各个配件之间是有关联的。
对于装机工程师而言,他只知道组装一台电脑,需要相应的配件,但是具体使用什么样的配件,还得由客户说了算。也就是说装机工程师只是负责组装,而客户负责选择装配所需要的具体的配件。因此,当装机工程师为不同的客户组装电脑时,只需要按照客户的装机方案,去获取相应的配件,然后组装即可。
现在需要使用程序来把这个装机的过程,尤其是选择组装电脑配件的过程实现出来,该如何实现呢?
1.1.2 不用模式的解决方案
考虑客户的功能,需要选择自己需要的CPU和主板,然后告诉装机工程师自己的选择,接下来就等着装机工程师组装机器了。
对装机工程师而言,只是知道CPU和主板的接口,而不知道具体实现,很明显可以用上简单工厂或工厂方法模式,为了简单,这里选用简单工厂吧。客户告诉装机工程师自己的选择,然后装机工程师会通过相应的工厂去获取相应的实例对象。
(1)先来看看CPU和主板的接口,先看CPU的接口定义,示例代码如下:
/** * CPU的接口 */ public interface CPUApi { /** * 示意方法,CPU具有运算的功能 */ public void calculate(); }
再看看主板的接口定义,示例代码如下:
/** * 主板的接口 */ public interface MainboardApi { /** * 示意方法,主板都具有安装CPU的功能 */ public void installCPU(); }
(2)接下来看看具体的CPU实现,先看Intel的CPU实现,示例代码如下:
/** *Intel的CPU实现 */ public class IntelCPU implements CPUApi{ /** * CPU的针脚数目 */ private int pins = 0; /** * 构造方法,传入CPU的针脚数目 * @param pins CPU的针脚数目 */ public IntelCPU(int pins){ this.pins = pins; } public void calculate() { System.out.println("now in Intel CPU,pins="+pins); } }
再看看AMD的CPU实现,示例代码如下:
/** * AMD的CPU实现 */ public class AMDCPU implements CPUApi{ /** * CPU的针脚数目 */ private int pins = 0; /** * 构造方法,传入CPU的针脚数目 * @param pins CPU的针脚数目 */ public AMDCPU(int pins){ this.pins = pins; } public void calculate() { System.out.println("now in AMD CPU,pins="+pins); } }
(3)接下来看看具体的主板实现,先看技嘉的主板实现,示例代码如下:
/** * 技嘉的主板 */ public class GAMainboard implements MainboardApi { /** * CPU插槽的孔数 */ private int cpuHoles = 0; /** * 构造方法,传入CPU插槽的孔数 * @param cpuHoles CPU插槽的孔数 */ public GAMainboard(int cpuHoles){ this.cpuHoles = cpuHoles; } public void installCPU() { System.out.println("now in GAMainboard,cpuHoles=" +cpuHoles); } }
再看看微星的主板实现,示例代码如下:
/** * 微星的主板 */ public class MSIMainboard implements MainboardApi{ /** * CPU插槽的孔数 */ private int cpuHoles = 0; /** * 构造方法,传入CPU插槽的孔数 * @param cpuHoles CPU插槽的孔数 */ public MSIMainboard(int cpuHoles){ this.cpuHoles = cpuHoles; } public void installCPU() { System.out.println("now in MSIMainboard,cpuHoles=" +cpuHoles); } }
(4)接下来看看创建CPU和主板的工厂,先看创建CPU的工厂实现,示例代码如下:
/** * 创建CPU的简单工厂 */ public class CPUFactory { /** * 创建CPU接口对象的方法 * @param type 选择CPU类型的参数 * @return CPU接口对象的方法 */ public static CPUApi createCPUApi(int type){ CPUApi cpu = null; //根据参数来选择并创建相应的CPU对象 if(type==1){ cpu = new IntelCPU(1156); }else if(type==2){ cpu = new AMDCPU(939); } return cpu; } }
再看看创建主板的工厂实现,示例代码如下:
/** * 创建主板的简单工厂 */ public class MainboardFactory { /** * 创建主板接口对象的方法 * @param type 选择主板类型的参数 * @return 主板接口对象的方法 */ public static MainboardApi createMainboardApi(int type){ MainboardApi mainboard = null; //根据参数来选择并创建相应的主板对象 if(type==1){ mainboard = new GAMainboard(1156); }else if(type==2){ mainboard = new MSIMainboard(939); } return mainboard; } }
(5)接下来看看装机工程师的实现,示例代码如下:
/** * 装机工程师的类 */ public class ComputerEngineer { /** * 定义组装机器需要的CPU */ private CPUApi cpu= null; /** * 定义组装机器需要的主板 */ private MainboardApi mainboard = null; /** * 装机过程 * @param cpuType 客户选择所需CPU的类型 * @param mainboardType 客户选择所需主板的类型 */ public void makeComputer(int cpuType,int mainboardType){ //1:首先准备好装机所需要的配件 prepareHardwares(cpuType,mainboardType); //2:组装机器 //3:测试机器 //4:交付客户 } /** * 准备装机所需要的配件 * @param cpuType 客户选择所需CPU的类型 * @param mainboardType 客户选择所需主板的类型 */ private void prepareHardwares(int cpuType,int mainboardType){ //这里要去准备CPU和主板的具体实现,为了示例简单,这里只准备这两个 //可是,装机工程师并不知道如何去创建,怎么办呢? //直接找相应的工厂获取 this.cpu = CPUFactory.createCPUApi(cpuType); this.mainboard = MainboardFactory.createMainboardApi( mainboardType); //测试一下配件是否好用 this.cpu.calculate(); this.mainboard.installCPU(); } }
(6)看看此时的客户端,应该通过装机工程师来组装电脑,客户需要告诉装机工程师他选择的配件,示例代码如下:
public class Client { public static void main(String[] args) { //创建装机工程师对象 ComputerEngineer engineer = new ComputerEngineer(); //告诉装机工程师自己选择的配件,让装机工程师组装电脑 engineer.makeComputer(1,1); } }
运行结果如下:
now in Intel CPU,pins=1156 now in GAMainboard,cpuHoles=1156
1.1.3 有何问题
看了上面的实现,会感觉到很简单嘛,通过使用简单工厂来获取需要的CPU和主板对象,然后就可以组装电脑了。有何问题呢?
虽然上面的实现,通过简单工厂解决解决了:对于装机工程师,只知CPU和主板的接口,而不知道具体实现的问题。但还有一个问题没有解决,什么问题呢?那就是这些CPU对象和主板对象其实是有关系的,是需要相互匹配的。而在上面的实现中,并没有维护这种关联关系,CPU和主板是由客户随意选择的。这是有问题的。
比如在上面实现中的客户端,在调用makeComputer时,传入参数为(1,2),试试看,运行结果就会如下:
now in Intel CPU,pins=1156 now in MSIMainboard,cpuHoles=939
观察上面的结果,你就会看出问题来了,客户选择的CPU的针脚是1156针的,而选择的主板上的CPU插孔却只有939针,根本无法组装。这就是没有维护配件之间的关系造成的。
该怎么解决这个问题呢?
发表评论
-
对于单例模式的一点想法
2011-03-04 11:12 893单例模式很普遍,对于S ... -
研磨设计模式之命令模式-1
2010-09-14 09:29 986命令模式也是开发中常见的一个模式,也不是太难,比较简单,下面来 ... -
研磨设计模式之工厂方法模式-5
2010-09-13 14:33 9313.3 平行的类层次结构 ... -
研磨设计模式之工厂方法模式-4
2010-09-13 14:17 716... -
研磨设计模式之工厂方法模式-3
2010-09-10 17:28 8603 模式讲解 3.1 认识工厂方法模式 (1)模式的功能 ... -
研磨设计模式之工厂方法模式-2
2010-09-08 10:30 11082 解决方案 2.1 工厂方法模式来解决 ... -
研磨设计模式之工厂方法模式-1(来自chjavach)
2010-09-08 10:20 1090做Java一晃就十年了,最 ... -
设计模式学习笔记(十二)—Builder建造者模式
2008-11-13 10:25 950Builder模式定义:将一个复杂对象的构建与它的表示分离, ... -
设计模式学习笔记(十一)—Prototype原型模式
2008-11-13 10:12 925Prototype模式的意图是: ... -
设计模式学习笔记(七)—Observer观察者模式
2008-11-13 09:47 917《设计模式》一书对Observer是这样描述的:定义对象间的一 ... -
设计模式学习笔记(六)—Decorator装饰模式
2008-11-12 17:04 876《设计模式》一书对Decorator是这样描述的: 动态地给一 ... -
设计模式学习笔记(五)—Abstract Factory抽象工厂模式
2008-11-12 16:47 886GOF《设计模式》一书对Abstract Factory模式是 ... -
设计模式学习笔记(四)—Bridge桥接模式
2008-11-12 16:40 910《设计模式》一书对Bridge是这样描述的: 将抽象与其实现解 ... -
设计模式学习笔记(三)—-Strategy策略模式
2008-11-12 16:17 1123GOF《设计模式》一书对Strategy模式是这样描述的: ... -
设计模式学习笔记(二)—-Adapter适配器模式
2008-11-12 15:50 986GOF《设计模式》一书对Adapter模式是这样描述的: ... -
设计模式学习笔记(一)--Facade外观模式
2008-11-12 15:48 919GOF《设计模式》一书对Facade模式是这样描述的: ... -
设计模式学习笔记(十)—Factory Method模式
2008-11-12 15:25 962《设计模式》一书对Factory Method模式是这样描述的 ... -
设计模式学习笔记(九)—Singleton模式
2008-11-12 15:22 860《设计模式》一书对Singleton模式是这样描述的:保证一个 ... -
设计模式学习笔记(八)—Template Method模式
2008-11-12 15:03 1058factory模式(包括简单工厂和抽象工厂),Strategy ...
相关推荐
《研磨设计模式》完整覆盖GoF讲述的23个设计模式并加以细细研磨。初级内容从基本讲起,包括每个模式的定义、功能、思路、结构、基本实现、运行调用顺序、基本应用示例等,让读者能系统、完整、准确地掌握每个模式,...
《研磨设计模式》完整覆盖GoF讲述的23个设计模式并加以细细研磨。初级内容从基本讲起,包括每个模式的定义、功能、思路、结构、基本实现、运行调用顺序、基本应用示例等,让读者能系统、完整、准确地掌握每个模式,...
《研磨设计模式》完整覆盖GoF讲述的23个设计模式并加以细细研磨。初级内容从基本讲起,包括每个模式的定义、功能、思路、结构、基本实现、运行调用顺序、基本应用示例等,让读者能系统、完整、准确地掌握每个模式,...
《研磨设计模式》完整覆盖GoF讲述的23个设计模式并加以细细研磨。初级内容从基本讲起,包括每个模式的定义、功能、思路、结构、基本实现、运行调用顺序、基本应用示例等,让读者能系统、完整、准确地掌握每个模式,...
《研磨设计模式》完整覆盖GoF讲述的23个设计模式并加以细细研磨。初级内容从基本讲起,包括每个模式的定义、功能、思路、结构、基本实现、运行调用顺序、基本应用示例等,让读者能系统、完整、准确地掌握每个模式,...
《研磨设计模式》完整覆盖GoF讲述的23个设计模式并加以细细研磨。初级内容从基本讲起,包括每个模式的定义、功能、思路、结构、基本实现、运行调用顺序、基本应用示例等,让读者能系统、完整、准确地掌握每个模式,...
《研磨设计模式》完整覆盖GoF讲述的23个设计模式并加以细细研磨。初级内容从基本讲起,包括每个模式的定义、功能、思路、结构、基本实现、运行调用顺序、基本应用示例等,让读者能系统、完整、准确地掌握每个模式,...
《研磨设计模式》完整覆盖GoF讲述的23个设计模式并加以细细研磨。初级内容从基本讲起,包括每个模式的定义、功能、思路、结构、基本实现、运行调用顺序、基本应用示例等,让读者能系统、完整、准确地掌握每个模式,...
《研磨设计模式》完整覆盖GoF讲述的23个设计模式并加以细细研磨。初级内容从基本讲起,包括每个模式的定义、功能、思路、结构、基本实现、运行调用顺序、基本应用示例等,让读者能系统、完整、准确地掌握每个模式,...
《研磨设计模式》书中的例子 --第二章:简单工厂 本质:选择实现 --第三章:外观模式(Facade) 本质:封装交互,简化调用 --第四章:适配器模式(Adapter) 本质:转换匹配,复用功能 --第五章:单例模式(Singleton) ...