设计模式—抽象工厂模式
场景问题
举个生活中常见的例子——组装电脑,我们在组装电脑的时候,通常需要选择一系列的配件,比如CPU、硬盘、内存、主板、电源、机箱等。
需要整体考虑各个配件之间的兼容性。比如:CPU和主板,如果使用Intel的CPU和AMD的主板是根本无法组装的。因为Intel的CPU针脚数与AMD主板提供的CPU插口不兼容,就是说如果使用Intel的CPU根本就插不到AMD的主板中,所以装机方案是整体性的,里面选择的各个配件之间是有关联的。
由于抽象工厂定义的一系列对象通常是相关或相互依赖的,这些产品对象就构成了一个产品族,也就是抽象工厂定义了一个产品族。
这就带来非常大的灵活性,切换产品族的时候,只要提供不同的抽象工厂实现就可以了,也就是说现在是以一个产品族作为一个整体被切换。
优点:当一个产品族中的多个对象被设计成一起工作时,它能保证客户端始终只使用同一个产品族中的对象。
缺点:产品族扩展非常困难,要增加一个系列的某一产品,既要在抽象的 Creator 里加代码,又要在具体的里面加代码。
使用场景: 1、QQ 换皮肤,一整套一起换。 2、生成不同操作系统的程序。
抽象工厂类:
public interface AbstractFactory {
/**
* 创建CPU对象
* @return CPU对象
*/
public Cpu createCpu();
/**
* 创建主板对象
* @return 主板对象
*/
public Mainboard createMainboard();
}
具体实现工厂类:
public class IntelFactory implements AbstractFactory {
@Override
public Cpu createCpu() {
// TODO Auto-generated method stub
return new IntelCpu(755);
}
@Override
public Mainboard createMainboard() {
// TODO Auto-generated method stub
return new IntelMainboard(755);
}
}
public class AmdFactory implements AbstractFactory {
@Override
public Cpu createCpu() {
// TODO Auto-generated method stub
return new IntelCpu(938);
}
@Override
public Mainboard createMainboard() {
// TODO Auto-generated method stub
return new IntelMainboard(938);
}
}
关于产品接口和具体产品实现类已经省略。
装机工程师类:
public class ComputerEngineer {
/**
* 定义组装机需要的CPU
*/
private Cpu cpu = null;
/**
* 定义组装机需要的主板
*/
private Mainboard mainboard = null;
public void makeComputer(AbstractFactory af){
/**
* 组装机器的基本步骤
*/
//1:首先准备好装机所需要的配件
prepareHardwares(af);
//2:组装机器
//3:测试机器
//4:交付客户
}
private void prepareHardwares(AbstractFactory af){
//这里要去准备CPU和主板的具体实现,为了示例简单,这里只准备这两个
//可是,装机工程师并不知道如何去创建,怎么办呢?
//直接找相应的工厂获取
this.cpu = af.createCpu();
this.mainboard = af.createMainboard();
//测试配件是否好用
this.cpu.calculate();
this.mainboard.installCPU();
}
}
客户端代码:
public class Client {
public static void main(String[]args){
//创建装机工程师对象
ComputerEngineer cf = new ComputerEngineer();
//客户选择并创建需要使用的产品对象
AbstractFactory af = new IntelFactory();
//告诉装机工程师自己选择的产品,让装机工程师组装电脑
cf.makeComputer(af);
}
}
文章摘选自:《JAVA与模式》之抽象工厂模式