6.1 解决方案
6.1.1 使用抽象工厂模式来解决问题
- 抽象工厂模式的定义
提供一个创建一系列相关或相互依赖对象的接口,而无需指定它们具体的类。
- 应用抽象工厂模式来解决问题的思路
定义一个抽象工厂,在里面虚拟的创建客户端需要的一系列对象。让抽象工厂的子类去实现创建。
6.1.2 抽象工厂模式示例
(1) CPUApi
package com.learn.desing.partten.transcation;
/**
* CPU 的接口
* @author Administrator
*
*/
public interface CPUApi {
/**
* 示意方法,CPU 具有运算的功能
*/
public void calculate();
}
(2)IntelCPU
package com.learn.desing.partten.transcation;
/**
* Intel 的 CPU 的实现
* @author Administrator
*
*/
public class IntelCPU implements CPUApi {
/**
* CPU 的针脚数目
*/
private int pins = 0;
/**
* 构造方法,传入 CPU 的针脚数目
* @param pins CPU 的针脚数目
*/
public IntelCPU(int pins) {
this.pins = pins;
}
public void calculate() {
System.out.println("now in Intel CPU, pins=" + pins);
}
}
(3)AMDCPU
package com.learn.desing.partten.transcation;
/**
* AMD 的 CPU 的实现
* @author Administrator
*
*/
public class AMDCPU implements CPUApi {
/**
* CPU 的针脚数目
*/
private int pins = 0;
/**
* 构造方法,传入 CPU 的针脚数目
* @param pins CPU 的针脚数目
*/
public AMDCPU(int pins) {
this.pins = pins;
}
public void calculate() {
System.out.println("now in AMD CPU, pins=" + pins);
}
}
(4)MainboardApi
package com.learn.desing.partten.transcation;
/**
* 主板的接口
* @author Administrator
*
*/
public interface MainboardApi {
/**
* 示意方法,主板都具有安装 CPU 的功能
*/
public void installCPU();
}
(5)GAMainboard
package com.learn.desing.partten.transcation;
/**
* 技嘉的主板
* @author Administrator
*
*/
public class GAMainboard implements MainboardApi {
/**
* CPU 插槽的孔数
*/
private int cpuHoles = 0;
/**
* 构造方法,传入 CPU 插槽的孔数
* @param cpuHoles CPU 插槽的孔数
*/
public GAMainboard(int cpuHoles) {
this.cpuHoles = cpuHoles;
}
public void installCPU() {
System.out.println("now in GAMainboard, cpuHoles=" + this.cpuHoles);
}
}
(6)MSIMainboard
package com.learn.desing.partten.transcation;
/**
* 微星的主板
* @author Administrator
*
*/
public class MSIMainboard implements MainboardApi {
/**
* cpu 插槽的数量
*/
private int cpuHoles = 0;
/**
* 构造方法,传入 CPU 插槽的数量
* @param cpuHoles CPU 插槽的数量
*/
public MSIMainboard(int cpuHoles) {
this.cpuHoles = cpuHoles;
}
public void installCPU() {
System.out.println("now in MSIMainboard, cpuHoles=" + cpuHoles);
}
}
(7)抽象工厂
package com.learn.design.pattern.scheme;
/**
* 抽象工厂模式的接口,声明创建抽象产品对象的操作
* @author cyxy
*
*/
public interface AbstractFactory {
/**
* 创建 CPU 的对象
* @return CPU 的对象
*/
public CPUApi createCPUApi();
/**
* 创建主板的对象
* @return 主板的对象
*/
public MainboardApi createMainboard();
}
(9)装机方案一
package com.learn.design.pattern.scheme;
/**
* 装机方案一: Intel + GA
* @author cyxy
*/
public class Schema1 implements AbstractFactory {
@Override
public CPUApi createCPUApi() {
return new IntelCPU(1111);
}
@Override
public MainboardApi createMainboard() {
return new GAMainboard(1111);
}
}
(10)装机方案二
package com.learn.design.pattern.scheme;
/**
* 装机方案二: AMD + MSI
* @author cyxy
*
*/
public class Schema2 implements AbstractFactory {
@Override
public CPUApi createCPUApi() {
return new AMDCPU(444);
}
@Override
public MainboardApi createMainboard() {
return new MSIMainboard(444);
}
}
(11)装机工程师
package com.learn.design.pattern.scheme;
/**
* 装机工程师的类
* @author cyxy
*
*/
public class ComputerEngineer {
/**
* 定义组装电脑需要的 CPU
*/
private CPUApi cpu = null;
/**
* 定义组装电脑需要的 主板
*/
private MainboardApi mainBoard = null;
/**
* 装机过程
* @param schema 客户选择的装机方案
*/
public void makeCompute(AbstractFactory schema) {
prepareHardwares(schema);
}
/**
* 准备装机所需要的配件
* @param schema 客户选择的装机方案
*/
public void prepareHardwares(AbstractFactory schema) {
this.cpu = schema.createCPUApi();
this.mainBoard = schema.createMainboard();
cpu.calculate();
mainBoard.installCPU();
}
}
(12)Client
package com.learn.design.pattern.scheme;
public class Client {
public static void main(String[] args) {
// 创建装机工程师对象
ComputerEngineer engineer = new ComputerEngineer();
// 客户选择并创建需要使用的装机方案对象
AbstractFactory schema = new Schema1();
// 告诉装机工程师自己选择的装机方案,让装机工程师装电脑
engineer.makeCompute(schema);
}
}
6.2 模式讲解
6.2.1 认识抽象工厂模式
- 抽象工厂的功能
为一系列相关对象或相互依赖的对象创建一个接口
- 实现成接口
不是抽象类,是接口
- 使用工厂方法
创建产品所需要的接口,具体的实现是在实现类里面。
6.2.2 定义可扩展的工厂
(1)抽象工厂
package com.learn.design.pattern.scheme;
/**
* 抽象工厂模式的接口,声明创建抽象产品对象的操作
* @author cyxy
*
*/
public interface AbstractFactory {
/**
* 一个通用的创建产品对象的方法,为了简单,直接返回 object
* 也可以为所有被创建的产品定义一个公共的接口
* @param type 具体创建的产品类型标识
* @return 创建出的产品对象
*/
public Object createProduct(int type);
}
(2)装机方案一
package com.learn.design.pattern.scheme;
/**
* 装机方案一: Intel + GA
* @author cyxy
*/
public class Schema1 implements AbstractFactory {
@Override
public Object createProduct(int type) {
Object object = null;
// type 为 1 表示创建 CPU, type 为 2 表示创建主板
if (type == 1) {
object = new IntelCPU(1144);
} else if (type == 2) {
object = new GAMainboard(1144);
}
return null;
}
}
(3)装机方案二
package com.learn.design.pattern.scheme;
/**
* 装机方案二: AMD + MSI
* @author cyxy
*
*/
public class Schema2 implements AbstractFactory {
@Override
public Object createProduct(int type) {
Object object = null;
if (type == 1) {
object = new AMDCPU(333);
} else if (type == 2) {
object = new MSIMainboard(333);
}
return object;
}
}
(4)装机工程师
package com.learn.design.pattern.scheme;
/**
* 装机工程师的类
* @author cyxy
*
*/
public class ComputerEngineer {
/**
* 定义组装电脑需要的 CPU
*/
private CPUApi cpu = null;
/**
* 定义组装电脑需要的 主板
*/
private MainboardApi mainBoard = null;
/**
* 装机过程
* @param schema 客户选择的装机方案
*/
public void makeCompute(AbstractFactory schema) {
prepareHardwares(schema);
}
/**
* 准备装机所需要的配件
* @param schema 客户选择的装机方案
*/
public void prepareHardwares(AbstractFactory schema) {
this.cpu = (CPUApi) schema.createProduct(1);
this.mainBoard = (MainboardApi) schema.createProduct(2);
cpu.calculate();
mainBoard.installCPU();
}
}
6.2.4 抽象工厂模式的缺点
优点:
-
分离接口的实现
-
使得切换产品变得更容易
缺点:
-
不太容器扩展新的产品
-
容易造成类层次复杂
6.2.5 思考抽象工厂模式
- 抽象工厂模式的本质
抽象工厂模式的本质:选择产品簇的实现。
- 何时选用抽象工厂模式
-
一个系统独立于它的产品的创建、组合和表示的时候
-
如果一个系统要由多个产品系列中的一个来配置的时候
-
强调一系列相关产品的接口,以便联合使用它们的时候