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

来源:互联网 发布:新致软件java笔试题 编辑:程序博客网 时间:2024/06/11 18:49

前面一章说的是工厂方法模式,我们知道工厂方法模式中只有一个抽象产品角色并且具体工厂角色与具体产品角色是一一对应的。

今天要说的抽象工厂角色与具体工厂角色的区别就在于这里,抽象工厂角色可以有多个抽象产品角色,每个抽象产品角色下可派生出多个具体产品角色,

工厂角色结构没有变化,还是一个抽象工厂角色派生出多个具体工厂角色,但是一个具体工厂角色里面可以创建多个具体产品角色了。

举个例子:

我们在组装电脑的时候经常要选择一系列的配件,比如CPU、主板等。选择CPU的时候面临一些问题,比如品牌、型号、针脚数目等;选择主板也面临同样的一些问

题。当我们选择完CPU和主板之后开始组装电脑,但是装机前还要考虑CPU和主板的配套问题。也就是说,装机方案是有整体性的,选择的硬件之间是有关联的。

下面我们分别应用简单工厂模式和抽象工厂模式来进行装机,通过这个例子观察抽象工厂模式与工厂模式有哪些异同。

简单工厂模式装机:

抽象的CPU和主板代码:

package hirain.simple.cpu;/** * CPU的接口 */public interface CPUService{    /**     * CPU具有运算的功能     */    public void calculate();}
package hirain.simple.mainboard;public interface MainBoardService {    /**     * 主板可以安装CPU     */    public void installCPU();}

具体的CPU和主板产品代码:

CPU有AMD的CPU和INTEL的CPU

package hirain.simple.cpu;/** * AMD的CPU实现 */public class AMDCPU implements CPUService{    /**     * CPU的针脚数目     */    private int pins = 0;    /**     * 构造方法,传入CPU的针脚数目     * @param pins CPU的针脚数目     */    public AMDCPU(int pins){       this.pins = pins;    }    public void calculate() {       System.out.println("Intel CPU针脚数目="+pins);    }}
package hirain.simple.cpu;/** *Intel的CPU实现 */public class IntelCPU implements CPUService{    /**     * CPU的针脚数目     */    private int pins = 0;    /**     * 构造方法,传入CPU的针脚数目     * @param pins CPU的针脚数目     */    public IntelCPU(int pins){       this.pins = pins;    }    public void calculate() {       System.out.println("Intel CPU针脚数目="+pins);    }}
主板有技嘉的主板和微星的主板

package hirain.simple.mainboard;/** * 技嘉的主板 */public class GAMainboard implements MainBoardService {    /**     * CPU插槽的孔数     */    private int cpuHoles = 0;    /**     * 构造方法,传入CPU插槽的孔数     * @param cpuHoles CPU插槽的孔数     */    public GAMainboard(int cpuHoles){       this.cpuHoles = cpuHoles;    }    public void installCPU() {       System.out.println("技嘉主板CPU插槽孔数="+cpuHoles);    }}
package hirain.simple.mainboard;/** * 微星的主板 */public class MSIMainboard implements MainBoardService{    /**     * CPU插槽的孔数     */    private int cpuHoles = 0;    /**     * 构造方法,传入CPU插槽的孔数     * @param cpuHoles CPU插槽的孔数     */    public MSIMainboard(int cpuHoles){       this.cpuHoles = cpuHoles;    }    public void installCPU() {       System.out.println("技嘉主板CPU插槽孔数="+cpuHoles);    }}
工厂有两个:分别是获取CPU的工厂和获取主板的工厂

package hirain.simple.factory;import hirain.simple.cpu.AMDCPU;import hirain.simple.cpu.CPUService;import hirain.simple.cpu.IntelCPU;/** * 创建CPU的简单工厂 */public class CPUFactory {    /**     * 创建CPU接口对象的方法     * @param type 选择CPU类型的参数     * @return CPU接口对象的方法     */    public static CPUService createCPU(int type){    CPUService cpu = null;       //根据参数来选择并创建相应的CPU对象       if(type==1){           cpu = new IntelCPU(1156);       }else if(type==2){           cpu = new AMDCPU(939);       }       return cpu;    }  }
package hirain.simple.factory;import hirain.simple.mainboard.GAMainboard;import hirain.simple.mainboard.MSIMainboard;import hirain.simple.mainboard.MainBoardService;/** * 创建主板的简单工厂 */public class MainboardFactory {    /**     * 创建主板接口对象的方法     * @param type 选择主板类型的参数     * @return 主板接口对象的方法     */    public static MainBoardService createMainboard(int type){    MainBoardService mainboard = null;       //根据参数来选择并创建相应的主板对象       if(type==1){           mainboard = new GAMainboard(1156);       }else if(type==2){           mainboard = new MSIMainboard(939);       }       return mainboard;    }}
装机人代码:

package hirain.simple.person;import hirain.simple.cpu.CPUService;import hirain.simple.factory.CPUFactory;import hirain.simple.factory.MainboardFactory;import hirain.simple.mainboard.MainBoardService;/** * 装机工程师的类 */public  class Person {    /**     * 定义组装机器需要的CPU     */    private CPUService cpu= null;    /**     * 定义组装机器需要的主板     */    private MainBoardService 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.createCPU(cpuType);       this.mainboard = MainboardFactory.createMainboard(mainboardType);       //测试一下配件是否好用       this.cpu.calculate();       this.mainboard.installCPU();    }}
客户端代码:

package hirain.simple;import hirain.simple.person.Person;public class Client {    public static void main(String[] args) {       //创建装机工程师对象    Person person = new Person();       //告诉装机工程师自己选择的配件,让装机工程师组装电脑    person.makeComputer(2,1);    }}
通过上述代码我们可以发现问题:

电脑有可能组装不上,CPU和主板有可能是不配套的,也就是说,简单工厂和工厂方法模式只关心单个产品的创建,而不在乎产品之间是否存在着依赖关系。

所以,抽象工厂模式应运而生,专程来解决类似问题。

我们看一下抽象工厂模式的实现代码:

首先抽象产品和具体产品的代码是不变的。

工厂代码有变化:

package hirain.abstract1.factory;import hirain.abstract1.cpu.CPUService;import hirain.abstract1.mainboard.MainBoardService;/** * 抽象工厂的接口,声明创建抽象产品对象的操作 */public interface AbstractFactory {    /**     * 创建CPU的对象     * @return CPU的对象     */    public CPUService createCPU();    /**     * 创建主板的对象     * @return 主板的对象     */    public MainBoardService createMainboard();}
package hirain.abstract1.factory;import hirain.abstract1.cpu.CPUService;import hirain.abstract1.cpu.IntelCPU;import hirain.abstract1.mainboard.GAMainboard;import hirain.abstract1.mainboard.MainBoardService;/** * 装机方案一:Intel 的CPU + 技嘉的主板 * 这里创建CPU和主板对象的时候,是对应的,能匹配上的 */public class Schema1 implements AbstractFactory{public CPUService createCPU() {return new IntelCPU(1135);}public MainBoardService createMainboard() {return new GAMainboard(1135);}}
package hirain.abstract1.factory;import hirain.abstract1.cpu.AMDCPU;import hirain.abstract1.cpu.CPUService;import hirain.abstract1.mainboard.MSIMainboard;import hirain.abstract1.mainboard.MainBoardService;/** * 装机方案二:AMD的CPU + 微星的主板 * 这里创建CPU和主板对象的时候,是对应的,能匹配上的 */public class Schema2 implements AbstractFactory{    public CPUService createCPU() {       return new AMDCPU(939);    }    public MainBoardService createMainboard() {       return new MSIMainboard(939);    }  }
装机人代码:

package hirain.abstract1.person;import hirain.abstract1.cpu.CPUService;import hirain.abstract1.factory.AbstractFactory;import hirain.abstract1.mainboard.MainBoardService;/** * 装机工程师的类 */public  class Person {    /**     * 定义组装机器需要的CPU     */    private CPUService cpu= null;    /**     * 定义组装机器需要的主板     */    private MainBoardService mainboard = null;     /**     * 装机过程     * @param schema 客户选择的装机方案     */    public void makeComputer(AbstractFactory schema){       //1:首先准备好装机所需要的配件       prepareHardwares(schema);       //2:组装机器            //3:测试机器            //4:交付客户    }    /**     * 准备装机所需要的配件     * @param schema 客户选择的装机方案     */    private void prepareHardwares(AbstractFactory schema){       //这里要去准备CPU和主板的具体实现,为了示例简单,这里只准备这两个       //可是,装机工程师并不知道如何去创建,怎么办呢?             //使用抽象工厂来获取相应的接口对象       this.cpu = schema.createCPU();       this.mainboard = schema.createMainboard();             //测试一下配件是否好用       this.cpu.calculate();       this.mainboard.installCPU();    }}
客户端代码

package hirain.abstract1;import hirain.abstract1.factory.AbstractFactory;import hirain.abstract1.factory.Schema2;import hirain.abstract1.person.Person;public class Client {    public static void main(String[] args) {       //创建装机工程师对象       Person person = new Person();       //客户选择并创建需要使用的装机方案对象       AbstractFactory schema = new Schema2();       //告诉装机工程师自己选择的装机方案,让装机工程师组装电脑       person.makeComputer(schema);    }}
实际工作过程中这个模式也没用到过,也不知道以后会不会用到,说下抽象工厂和工厂模式的区别吧:

1、工厂方法是一个抽象产品,可以派生出多个具体产品;抽象工厂是多个抽象产品,每个产品可以派生出多个具体产品.

2、工厂方法每个具体工厂类只能创建一个具体产品类对象.抽象工厂每个具体工厂类可以创建多个具体产品类对象.


















0 0