java高级设计模式之抽象工厂模式

前言:这一篇介绍抽象工厂模式,我把它的定义,本质,何时选用等记下来。实例因为类太多,只贴重要的几个,别的就不贴了。是一个组装电脑的实例,当然,配件只有主板和cpu。不同的主板对应不同的CPU,这两个接口具有联系。

定义:

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


认识抽象工厂模式
1、模式的功能
    抽象工厂的功能是为一系列相关对象或相互依赖的对象创建一个接口。
    从某种意义上看,抽象工厂其实是一个产品系列,或者是产品簇
2、实现成接口
    AbstractFactory在JAVA中通常实现成为接口,大家不要被名称误导了,以为是实现城抽象类
3、使用工厂方法
    AbstractFactory定义了创建产品所需要的接口,具体的实现是在实现类里面,通常在实现类里面就需要
    选择多种更具体的实现,所以AbstractFactory定义的创建产品的方法可以看成是工厂方法,而这些工厂
    方法的具体实现就延迟到了具体的工厂里面。也就是说工厂方法来实现抽象工厂。
4、切换产品簇
    抽象工厂定义了一个产品簇,因此切换产品簇的时候提供了不同的抽象工厂就好了。
5、定义可扩展的工厂
    有一种相对灵活,但是不太安全的改进方式来解决这个问题,思路如下:
    抽象工厂里面不需要定义那么多方法,定义一个方法就可以了,给这个方法设置一个参数,通过这个参数来判断具体
    创建什么产品对象;由于只有一个方法,在返回类型上就不能是具体的某个产品类型了,只能是所有的产品对象都继承
    或者实现的这么一个类型,比如让所有的产品都实现某个接口,或者干脆使用Object类型
6、抽象工厂和DAO
    一、DAO知识回顾
    1、DAO:数据访问对象,是Data Access Object首字母的简写
    2、DAO是JEE中的一个标准模式,通过它来解决访问数据对象所面临的一系列问题,比如:数据源不同,存储类型不同、访问方式不同、
    供应商不同、版本不同等等,这些不同会造成访问数据的实现上差别很大
    3、DAO需要抽象和封装所有对数据的访问,DAO承担和数据仓库交互的职责,这也意味着,访问数据所面临的所有问题,都需要DAO在内部
    来自行解决
    二、DAO和抽象工厂的关系
    在实现DAO模式的时候,最常见的实现策略就是使用工厂的策略,而且多是通过抽象工厂模式来实现,当然在使用抽象工厂模式来实现的
    时候,可以结合工厂方法模式,因此DAO模式和抽象工厂模式有很大的联系。
    三、DAO模式采用工厂方法模式来实现的策略,采用抽象工厂模式
7、抽象工厂模式的优缺点
    1、分离接口和实现
    2、使得切换产品簇变得容易
    3、不太容易扩展新的产品
    4、容易造成类层次复杂
8、抽象工厂的本质
    抽象工厂模式的本质是:选择产品簇的实现
9、何时选用抽象工厂模式
    1:如果希望一个系统独立于它的产品的创建,组合和表示的时候,换句话说,希望一个系统知识知道产品的接口,而不关心实现的时候
    2:如果一个系统要由多个产品系列中的一个来配置的时候,换句话说,就是可以动态的切换产品簇的时候。
    3:如果要强调一系列相关产品的接口,以便联合使用它们的时候。

备注:

cpu的接口有两个实现,主板接口也有两个实现,分别是不同的cpu和不同的主板。装机方案也有两个,这里贴了一个。这里用户选择的时候不是选择哪个cpu,哪个主板了。而是选择一整套方案。免得用户选的cpu和主板不对应。

实例部分代码:

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


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

/**
 * 抽象工厂的接口,声明创建抽象产品对象的操作
 */
public interface AbstractFactory {
    /**
     * 创建CPU的对象
     */
    public CPUApi createCPUApi();
    /**
     * 创建主板的对象
     */
    public MainboardApi createMainboardApi();
}
/**
 * 装机工程师类
 */
public class ComputerEngineer {
    /**
     * 定义组装机器需要的CPU
     */
    private CPUApi cpu = null;
    /**
     * 定义组装机器需要的主板
     */
    private MainboardApi mainboard = null;
    /**
     * 装机过程
     */
    public void makeComputer(AbstractFactory schema) {
        //1,首先准备好装机所需要的配件
        prepareHardwares(schema);
        //2、组装机器
        //3、测试机器
        //4、交付客户
    }
    private void prepareHardwares(AbstractFactory schema) {
        //这里要去准备CPU和主板的具体实现,为了示例简单,这里只准备这两个
        //可是,装机工程师并不知道如何去创建,怎么办呢?
        //使用抽象工厂来获取相应的接口对象
        this.cpu = schema.createCPUApi();
        this.mainboard = schema.createMainboardApi();
        
        //测试一下配件是否好用
        this.cpu.calculate();
        this.mainboard.installCPU();
    }
}

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

/**
 *装机方案一:Intel的CPU+技嘉的主板
 *这里创建CPU和主板对象的时候,是对应的,能匹配上的 
 */
public class Schema1 implements AbstractFactory {

    @Override
    public CPUApi createCPUApi() {
        return new IntelCPU(1156);
    }

    @Override
    public MainboardApi createMainboardApi() {
        return new GAMainboard(1156);
    }

}

猜你喜欢

转载自blog.csdn.net/youjiangtengwan1/article/details/84023149