抽象工厂模式(Abstract Factory)

工厂模式的总结

1)还没有工厂时代:假如还没有工业革命,如果一个客户要一款宝马车,一般的做法是客户去创建一款宝马车,然后拿来用。
2)简单工厂模式:后来出现工业革命。用户不用去创建宝马车。因为客户有一个工厂来帮他创建宝马.想要什么车,这个工厂就可以建。比如想要宝马系列车。工厂就创建这个系列的车。即工厂可以创建产品。
3)工厂方法模式时代:为了满足客户,车系列越来越多,奔驰等系列,一个工厂无法创建所有的车系列。于是由单独分出来多个 具体的工厂。每个具体工厂创建一种系列。即具体工厂类只能创建一个具体产品。
4)抽象工厂模式时代:随着客户的要求越来越高,车进行分类,分为商务车和运动车两个族

1. 模式定义

装机方案是有整体性的,里面选择的各个配件是有关联的。

要解决的问题:要创建一系列的产品对象,而且这一系列对象是构建新的对象所需要的组成部分,也就是这一系列被创建的对象相互之间是有约束的。

抽象工厂模式的定义:
提供一个创建一系列相关或相互依赖对象的接口,而无需指定它们具体的类。

2. UML图

代码:

/** * 抽象工厂的接口,声明创建抽象产品对象的操作 */
public interface AbstractFactory {
    /** * 创建CPU的对象 * @return CPU的对象 */
    public CPUApi createCPUApi();
    /** * 创建主板的对象 * @return 主板的对象 */
    public MainboardApi createMainboardApi();
}

/** * 装机方案一:Intel 的CPU + 技嘉的主板 * 这里创建CPU和主板对象的时候,是对应的,能匹配上的 */
public class Schema1 implements AbstractFactory{
    public CPUApi createCPUApi() {
        return new IntelCPU(1156);
    }
    public MainboardApi createMainboardApi() {
        return new GAMainboard(1156);
    }   
}

/** * 装机方案二:AMD的CPU + 微星的主板 * 这里创建CPU和主板对象的时候,是对应的,能匹配上的 */
public class Schema2 implements AbstractFactory{
    public CPUApi createCPUApi() {
        return new AMDCPU(939);
    }
    public MainboardApi createMainboardApi() {
        return new MSIMainboard(939);
    }   
}

/** * CPU的接口 */
public interface CPUApi {
    /** * 示意方法,CPU具有运算的功能 */
    public void calculate();
}

/** * 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);
    }
}

/** *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);
    }
}

/** * 主板的接口 */
public interface MainboardApi {
    /** * 示意方法,主板都具有安装CPU的功能 */
    public void installCPU();   
}

/** * 微星的主板 */
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);
    }
}

/** * 技嘉的主板 */
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 ComputerEngineer {
    /** * 定义组装机器需要的CPU */
    private CPUApi cpu= null;
    /** * 定义组装机器需要的主板 */
    private MainboardApi 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.createCPUApi();
        this.mainboard = schema.createMainboardApi();

        //测试一下配件是否好用
        this.cpu.calculate();
        this.mainboard.installCPU();
    }
}

public class Client {
    public static void main(String[] args) {
        //创建装机工程师对象
        ComputerEngineer engineer = new ComputerEngineer();
        //客户选择并创建需要使用的装机方案对象
        AbstractFactory schema = new Schema1();
        //告诉装机工程师自己选择的装机方案,让装机工程师组装电脑
        engineer.makeComputer(schema);
    }
}

3.研磨设计模式

抽象工厂的功能是:为一系列相关或相互依赖的对象创建一个接口

抽象工厂模式的本质是:选择产品簇的实现。

DAO:数据访问对象,Data Access Object
通过它来解决访问数据对象所面临的一系列问题,比如数据源不同,存储类型不同,访问方式不同,供应商不同,版本不同等,这些不同会造成访问数据的实现上差别不同。
1. 数据源:存放于数据库的数据源,存放于本地的数据源和远程服务器上的数据源
2. 存储类型:关系型数据库,面向对象数据库,XML
3. 访问方式不同:JDBC, MyBatis

业务对象以统一的方式来访问DAO,DAO需要抽象和封装所有对数据的访问,DAO承担和数据仓库交互的职责,即访问数据所面临的所有问题,都需要DAO在内部来自行解决。

可扩展的工厂:
如果添加新的对象时,就需要在抽象工厂里面添加一个方法,导致其实现类都需要改变

/** * 可扩展的抽象工厂的接口 */
public interface AbstractFactory {
    /** * 一个通用的创建产品对象的方法,为了简单,直接返回Object * 也可以为所有被创建的产品定义一个公共的接口 * @param type 具体创建的产品类型标识 * @return 创建出的产品对象 */
    public Object createProduct(int type);
}

/** * 装机方案一:Intel 的CPU + 技嘉的主板 * 这里创建CPU和主板对象的时候,是对应的,能匹配上的 */
public class Schema1 implements AbstractFactory{
    public Object createProduct(int type) {
        Object retObj = null;
        //type为1表示创建CPU,type为2表示创建主板
        if(type==1){
            retObj = new IntelCPU(1156);
        }else if(type==2){
            retObj = new GAMainboard(1156);
        }
        return retObj;
    }   
}

/** * 装机方案二:AMD的CPU + 微星的主板 * 这里创建CPU和主板对象的时候,是对应的,能匹配上的 */
public class Schema2 implements AbstractFactory{
    public Object createProduct(int type) {
        Object retObj = null;
        //type为1表示创建CPU,type为2表示创建主板
        if(type==1){
            retObj = new AMDCPU(939);
        }else if(type==2){
            retObj = new MSIMainboard(939);
        }
        return retObj;
    }   
}


/** * 装机方案三:Intel 的CPU + 技嘉的主板 + 现代的内存 */
public class Schema3 implements AbstractFactory{
    public Object createProduct(int type) {
        Object retObj = null;
        //type为1表示创建CPU,type为2表示创建主板,type为3表示创建内存
        if(type==1){
            retObj = new IntelCPU(1156);
        }else if(type==2){
            retObj = new GAMainboard(1156);
        }
        //创建新添加的产品
        else if(type==3){
            retObj = new HyMemory();
        }
        return retObj;
    }
}

/** * 装机工程师的类 */
public  class ComputerEngineer {
    /** * 定义组装机器需要的CPU */
    private CPUApi cpu= null;
    /** * 定义组装机器需要的主板 */
    private MainboardApi mainboard = null;
    /** * 定义组装机器需要的内存 */
    private MemoryApi memory = null;

    /** * 装机过程 * @param schema 客户选择的装机方案 */
    public void makeComputer(AbstractFactory schema){
        //1:首先准备好装机所需要的配件
        prepareHardwares(schema);
        //2:组装机器

        //3:测试机器

        //4:交付客户
    }
    /** * 准备装机所需要的配件 * @param schema 客户选择的装机方案 */
    private void prepareHardwares(AbstractFactory schema){
        //这里要去准备CPU和主板的具体实现,为了示例简单,这里只准备这两个
        //可是,装机工程师并不知道如何去创建,怎么办呢?

        //使用抽象工厂来获取相应的接口对象
        this.cpu = (CPUApi)schema.createProduct(1);
        this.mainboard = (MainboardApi)schema.createProduct(2);
        this.memory = (MemoryApi)schema.createProduct(3);

        //测试一下配件是否好用
        this.cpu.calculate();
        this.mainboard.installCPU();
        if(memory!=null){
            this.memory.cacheData();
        }
    }
}


你可能感兴趣的:(抽象工厂模式(Abstract Factory))