定义
提供一个创建一系列相关或相互依赖的对象接口,而无需指定他们具体的类。
结构和说明
AbstractFactory:创建一席勒产品对象的操作接口。
ConcreteFactory:具体的工厂实现抽象工厂的定义方法,具体实现一系列产品对象的创建
AbstractProduct:定义一类产品对象的接口。
ConcreteProduct:具体的产品实现对象,通常在具体工厂里面会选择具体的产品实现对象,来创建符合抽象工厂返回的产品类型对象。
client:客户端
public interface AbstractFactory{
public AbstractProductA createProductA();
public AbstractProductB createProductB();
}
public interface AbstractProductA{
}
public interface AbstractProductB{
}
public class ConcreteFactory implements AbstractFactory{
public AbstractProductA createProductA(){
return new ProductA1();
}
public AbstractProductB createProductB(){
return new ProductB1();
}
}
public class ConcreteFactory2 implements AbstractFactory{
public AbstractProductA createProductA(){
return new ProductA2();
}
public AbstractProductB createProductB(){
return new ProductB2();
}
}
public class ProductA1 implements AbstractProductA{
}
public class ProductB1 implements AbstractProductB{
}
public class ProductA2 implements AbstractProductA{
}
public class ProductB2 implements AbstractProductB{
}
组装电脑配件
注意一点组装电脑cpu,主板是需要相互匹配。
装机工程师组装电脑对象,需要一系列产品对象,
cpu,主板等,于是创建一个抽象工厂给装机工程师使用,
这个抽象工厂里面定义的创建cpu和主板的方法,相互匹配。
public interface CPUApi{
//运算 功能
public void calculate();
}
public class IntelCPU implements CPUApi{
//cpu的针角数
private int pins = 0;
public IntelCPU(int pins){
this.pins = pins;
}
public void calculate(){
//
System.out.println("Now in Intel CPU,pins="+pins);
}
}
public class AMDCPU implements CPUApi{
//cpu的针角数
private int pins = 0;
public AMDCPU(int pins){
this.pins = pins;
}
public void calculate(){
//
System.out.println("Now in AMD CPU,pins="+pins);
}
}
public interface MainboardApi{
//安装CPU
public void installCPU();
}
public class GAMainboard implements MainboardApi{
//cpu插槽的孔数
private int cpuHoles = 0;
public GAMainboard(int cpuHoles){
this.cpuHoles = cpuHoles;
}
public void installCPU(){
//
System.out.println("Now in GAMainboard CPU,cpuHoles="+cpuHoles);
}
}
public class MSIMainboard implements MainboardApi{
//cpu插槽的孔数
private int cpuHoles = 0;
public MSIMainboard(int cpuHoles){
this.cpuHoles = cpuHoles;
}
public void installCPU(){
//
System.out.println("Now in MSIMainboard CPU,cpuHoles="+cpuHoles);
}
}
//抽象工厂 装机方案创建配套组合
public interface AbstractFactory{
public CPUApi createCPUAPi();
public MainboardApi createMainboardApi();
}
//intelCPU + GAMainboard 组合
public class Schema1 implements AbstractFactory{
public CPUApi createCPUApi(){
return new IntelCPU(1566);
}
public MainboardApi createMainboardApi(){
return new GAMainboard(1566);
}
}
//AMDCPU + MSIMainboard 组合
public class Schema2 implements AbstractFactory{
public CPUApi createCPUApi(){
return new AMDCPU(939);
}
public MainboardApi createMainboardApi(){
return new MSIMainboard(939);
}
}
public class ComputerEngineer{
private CPUApi cupApi = null;
private MainboardApi mainboard = null;
public void makeComputer(AbstractFactory schema){
//首先准备好装机所需要的配件
prepareHardwares(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){
AbstractFactory schema = new Schema1();
ComputerEngineer computerEngineer = new ComputerEngineer();
computerEngineer.makeComputer(schema);
}
}
理解抽象工厂
1.抽象工厂的功能
抽象工厂的功能是为一系列相关的对象或者相互依赖的对象创建一个接口。从某种意义上看抽象工厂其实
是一个产品系列,或者产品簇。
2.实现成接口
AbstractFactory是接口,而不是抽象类
3.使用工厂方法
AbstractFactory定义了创建所需的接口具体实现是
在实现类里,通常在实现类中就需要选择多种的具体的实现,
所以AbstractFactory中定义的创建产品的方法可以看成
工厂方法,而这些工厂方法的具体实现,就延迟在具体的
工厂里面,也就是工程方法来实现抽象工厂。
4.切换产品簇
抽象工厂定义了一个产品簇,因此切换产品簇的时候提供不同抽
象工厂就好了。
问题
假如在产品簇中需要新增加一种产品比如除了CPU,主板外
需要增加内存??
1.AbstractFactory增加一个内存Api的方法
不太容易实现,相关接口方法全部需要修改且较为复杂。违反开闭原则。
2.定义可扩展的工厂
抽象工厂里面不需要定义那么多方法,定义一个方法就可以通过设置一个参数来判断具体产生什么产品对象。
public interface MemoryApi{
public void cacheData();
}
public class HyMemory implements MemoryApi{
public void cacheData(){
//加内存方法
}
}
public interface AbstractFactory{
//创建一个产品簇对象 type为产品代表的参数
public Object createProduct(int type);
}
public class Schema1 implements AbstractFactory{
public Object createProduct(int type){
Object object = null;
if (type == 1){
return object = new IntelCPU();
}else if(type == 2){
return object = new GAMainboard();
}else if(type ==3){
return object = new HyMemory();
}
}
}
public class ComputerEngineer{
private CPUApi cupApi = null;
private MainboardApi mainboard = null;
private MemoryApi memory = null;
public void makeComputer(AbstractFactory schema){
//首先准备好装机所需要的配件
prepareHardwares(schema);
//组装机器
//测试机器
//交付客户
}
private void prepareHardwares(AbstractFactory schema){
//对象类型强转换,不安全
this.cpu = (CPUApi)schema.createProduct(1);
this.mainboard = (MainboardApi)schema.createProduct(2);
this.memory= (MemoryApi)schema.createProduct(4);
this.cpu.calculate();
this.mainboard.installCPU();
if (memory!= null){
memory.cacheData();
}
}
}
抽象工厂和DAO
在实现DAO模式的时候,最常见的实现策略就是使用工厂的策略,而且多是抽象工厂模式的实现。
抽象工厂的优缺点
1.分离接口和实现
2.使得切换产品簇变得容易
3.不太容易扩展新的产品
4.容易使得类层次复杂
抽象工厂的本质
选择产品簇的实现
使用场景
1.一个系统独立与他的产品产品创建,组合和表示的时候,希望一个系统知识知道产品的接口,而不关心具体实现
2.动态切换产品簇
3.一系列相关产品的接口,以便联合使用它们的时候。