抽象工厂模式的定义:提供一个创建一系列相关或相互依赖对象的接口,而无需指定它们具体的类。
工厂方法模式或简单工厂关注的是单个产品对象的创建,而抽象工厂模式要创建一系列的产品对象(比如CPU和主板),这一系列被创建的对象相互之间是有约束的(比如CPU只能安装到特定的主板)。
抽象工厂会定义创建这些对象(CPU和主板)的抽象方法,并不去真正地实现,然后由具体的抽象工厂的子类来提供这一系列对象的创建(子类根据需要可以提供很多不同的实现)。
抽象工厂模式的本质:选择产品簇的实现
1、定义一个CPU接口,以及两个实现该接口的实例
/**
定义一个CPU产品的接口,具有计算能力
*/
public interface CPUApi {
public void calculate();
}
/**
定义一个实现CPU接口的产品 Intel
*/
public class IntelCpu implements CPUApi {
private int pins=0;
public IntelCpu(int pins){
this.pins=pins;
}
public void calculate() {
System.out.print("now in Intel CPU");
}
}
/**
定义另一个实现CPU接口的产品 AMD
*/
public class AMDCPU implements CPUApi{
private int pins=0;
public AMDCPU(int pins){
this.pins=pins;
}
public void calculate() {
System.out.print("now in AMD CPU");
}
}
2、定义一个主板接口,以及两个实现该接口的实例
/**
定义主板接口,具有按照CPU的功能
*/
public interface MainboardApi {
public void installCPU();
}
/**
定义一个实现主板接口的产品 技嘉主板
*/
public class GAMainboard implements MainboardApi
{
private int cpuHoles=0;
public GAMainboard(int cpuholes){
this.cpuHoles=cpuholes;
}
public void installCPU() {
System.out.print("now in GAMainboard");
}
}
/**
定义另一个实现主板接口的产品 微星主板
*/
public class MSIMainboard implements MainboardApi {
private int cpuHoles=0;
public MSIMainboard(int cpuholes){
this.cpuHoles=cpuholes;
}
public void installCPU() {
System.out.print("now in MSIMainboard");
}
}
3、抽象工厂的接口
public interface AbstractFactory {
/**
* 创建CPU的对象
* */
public CPUApi createCpuApi();
/**
* 创建主板的对象
* */
public MainboardApi createMainboardApi();
}
4、抽象工厂的实现对象。(不同的产品关联起来)
/**
装机方案一:Intel的CPU + 技嘉的主板
*/
public class Schema1 implements AbstractFactory {
public CPUApi createCpuApi() {
return new IntelCpu(1156);
}
public MainboardApi createMainboardApi() {
return new GAMainboard(1156);
}
}
/**
装机方案二:AMD的CPU + 微星的主板
*/
public class Schema2 implements AbstractFactory {
public CPUApi createCpuApi() {
return new AMDCPU(939);
}
public MainboardApi createMainboardApi() {
return new MSIMainboard(939);
}
}
5、客户端使用
public class ComputerEngineer {
private CPUApi cpu=null;
private MainboardApi mainboard=null;
/**
* 选择不同的装机方案
* */
public void makeComputer(AbstractFactory schema){
this.cpu=schema.createCpuApi();
this.mainboard=schema.createMainboardApi();
cpu.calculate();
mainboard.installCPU();
}
public static void main(String[] args) {
ComputerEngineer ce=new ComputerEngineer();
//客户选择装机方案
AbstractFactory schema=new Schema1();
ce.makeComputer(schema);
}
}
抽象工厂的功能是为一系列相关对象或相互依赖的对象创建一个接口,这个接口内的方法不是任意堆砌的,而是一系列相关或相互依赖的方法。
二、定义可扩展的工厂
如果在产品簇中新增一种产品,那么就需要在抽象工厂里添加创建一个方法,所有的具体工厂实现都要发生变化,因此非常的不灵活。
改造一下:抽象工厂里面不需要定义那么多方法,定义一个方法就可以,给这个方法设置一个参数,通过这个参数来判断具体创建什么产品对象。返回的产品对象都继承或实现同一个接口,或者使用Object类型。
/**
可扩展的抽象工厂的接口
*/
public interface AbstractFactory1 {
/**
*
* type用来标识创建什么类型的产品,创建CPU或主板,不再进一步表示具体的CPU或具体的主板
* */
public Object createProduct(int type);
}
/**
可扩展的抽象工厂的接口的具体实现
*/
public class Schema3 implements AbstractFactory1 {
public Object createProduct(int type) {
Object retObj=null;
if(type==1){
retObj=new AMDCPU(939);
}else if(type==2){
retObj=new MSIMainboard(939);
}
return retObj;
}
}
/**
客户端使用
*/
public class ComputerEngineer {
private CPUApi cpu=null;
private MainboardApi mainboard=null;
/**
* 选择不同的装机方案
* */
public void makeComputer(AbstractFactory1 schema){
//需要进行类型转换,存在不安全因素
this.cpu=(CPUApi) schema.createProduct(1));
this.mainboard=(MainboardApi) schema.createProduct(2);
cpu.calculate();
mainboard.installCPU();
}