Java 抽象工厂模式
场景问题
活中常见的例子——组装电脑,我们在组装电脑的时候,通常需要选择一系列的配件,比如 CPU、硬盘、内存、主板、电源、机箱等,事实上,在选择 CPU 的时候,面临一系列的问题,比如品牌、型号、针脚数目、主频等问题,只有把这些问题都确定下来,才能确定具体的 CPU。
同样,在选择主板的时候也是如此。选择不同的 CPU 和主板,是每个客户在组装电脑的时候,向装机公司提出的要求,也就是我们每个人自己拟定的装机方案。在最终确定这个装机方案之前,还需要整体考虑各个配件之间的兼容性。比如:CPU 和主板,如果使用 Intel 的 CPU 和 AMD 的主板是根本无法组装。所以装机方案是整体性的,里面选择的各个配件之间是有关联的。
对于装机工程师而言,他只知道组装一台电脑,需要相应的配件,但是具体使用什么样的配件,还得由客户说了算。也就是说装机工程师只是负责组装,而客户负责选择装配所需要的具体的配件。因此,当装机工程师为不同的客户组装电脑时,只需要根据客户的装机方案,去获取相应的配件,然后组装即可。
/**
* CPU 接口与具体实现
* @author qinxuewu
* @create 18/7/15 下午 4:01
* @since 1.0.0
*/
public interface Cpu {
public void calculate();
}
/**
* 〈不同型号 cpu 的实现类〉
* @author qinxuewu
* @create 18/7/15 下午 4:01
* @since 1.0.0
*/
public class IntelCpu implements Cpu {
/**
* CPU 的针脚数
*/
private int pins = 0;
public IntelCpu(int pins){
this.pins = pins;
}
@Override
public void calculate() {
System.out.println("Intel CPU 的针脚数:" + pins);
}
}
public class AmdCpu implements Cpu {
/**
* CPU 的针脚数
*/
private int pins = 0;
public AmdCpu(int pins){
this.pins = pins;
}
@Override
public void calculate() {
System.out.println("Amd CPU 的针脚数:" + pins);
}
}
主板接口与具体实现
/**
* 〈主板公共接口〉
* @author qinxuewu
* @create 18/7/15 下午 4:05
* @since 1.0.0
*/
public interface Mainboard {
public void installCPU();
}
public class IntelMainboard implements Mainboard{
/**
* CPU 插槽的孔数
*/
private int cpuHoles = 0;
/**
* 构造方法,传入 CPU 插槽的孔数
* @param cpuHoles
*/
public IntelMainboard(int cpuHoles){
this.cpuHoles = cpuHoles;
}
@Override
public void installCPU() {
System.out.println("Intel 主板的 CPU 插槽孔数是:" + cpuHoles);
}
}
public class AmdMainboard implements Mainboard{
/**
* CPU 插槽的孔数
*/
private int cpuHoles = 0;
/**
* 构造方法,传入 CPU 插槽的孔数
* @param cpuHoles
*/
public AmdMainboard(int cpuHoles){
this.cpuHoles = cpuHoles;
}
@Override
public void installCPU() {
System.out.println("Amd 主板的 CPU 插槽孔数是:" + cpuHoles);
}
}
CPU 与主板工厂类
public class CpuFactory {
public static Cpu createCpu(int type){
Cpu cpu=null;
if(type == 1){
cpu = new IntelCpu(755);
}else if(type == 2){
cpu = new AmdCpu(938);
}
return cpu;
}
}
public class MainboardFactory {
public static Mainboard createMainboard(int type){
Mainboard mainboard = null;
if(type == 1){
mainboard = new IntelMainboard(755);
}else if(type == 2){
mainboard = new AmdMainboard(938);
}
return mainboard;
}
}
抽象工厂类和实现类
/**
* 〈抽象工厂类〉
*/
public interface AbstractFactory {
/**
* 创建 CPU 对象
* @return CPU 对象
*/
public Cpu createCpu();
/**
* 创建主板对象
* @return 主板对象
*/
public Mainboard createMainboard();
}
public class IntelFactory implements AbstractFactory {
@Override
public Cpu createCpu() {
return new IntelCpu(755);
}
@Override
public Mainboard createMainboard() {
return new IntelMainboard(755);
}
}
public class AmdFactory implements AbstractFactory {
@Override
public Cpu createCpu() {
return new IntelCpu(938);
}
@Override
public Mainboard createMainboard() {
return new IntelMainboard(938);
}
}
装机工程师类与客户类
public class ComputerEngineer {
private Cpu cpu=null;
private Mainboard mainboard=null;
/**
* 根据传入的主板型号和 cpu 型号 进行组装电脑
*/
public void makeComputer(int cpuType,int mainboard){
/**
* 组装机器的基本步骤
*/
//1:首先准备好装机所需要的配件
//直接找相应的工厂获取
this.cpu = af.createCpu();
this.mainboard = af.createMainboard();
//测试配件是否好用
this.cpu.calculate();
this.mainboard.installCPU();
//2:组装机器
//3:测试机器
//4:交付客户
}
}
public class Client {
public static void main(String[] args) {
ComputerEngineer cf = new ComputerEngineer();
//客户选择并创建需要使用的产品对象
AbstractFactory af = new IntelFactory();
//告诉装机工程师自己选择的产品,让装机工程师组装电脑
cf.makeComputer(af);
}
}
抽象工厂模式的优点
分离接口和实现
- 客户端使用抽象工厂来创建需要的对象,而客户端根本就不知道具体的实现是谁,客户端只是面向产品的接口编程而已。也就是说,客户端从具体的产品实现中解耦。
使切换产品族变得容易
- 因为一个具体的工厂实现代表的是一个产品族,比如上面例子的从 Intel 系列到 AMD 系列只需要切换一下具体工厂。
抽象工厂模式的缺点
- 不太容易扩展新的产品,如果需要给整个产品族添加一个新的产品,那么就需要修改抽象工厂,这样就会导致修改所有的工厂实现类。
如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。
上一篇: Java 单例模式
下一篇: Java 适配器模式
绑定邮箱获取回复消息
由于您还没有绑定你的真实邮箱,如果其他用户或者作者回复了您的评论,将不能在第一时间通知您!
发布评论