一天一模式之7抽象工厂模式
原博文:https://blog.****.net/KongZhongNiao/article/details/80451183
定义
提供一个创建一系列相关或相互依赖对象的接口,而无需指定它们具体的类。
结构和说明
AbstractFactory:
抽象工厂,定义创建一系列产品对象的操作接口。
ConcreteFactory:
具体的工厂,实现抽象工厂定义的方法,具体实现一系列产品对象的创建。
AbstractProduct:
定义一类产品对象的接口。
ConcreteProduct:
具体的产品实现对象,通常在具体工厂里面,会选择具体的产品实现对
象,来创建符合抽象工厂定义的方法返回的产品类型的对象。
Client:
客户端,主要使用抽象工厂来获取一系列所需要的产品对象,然后面向这
些产品对象的接口编程,以实现需要的功能。
示例代码
抽象产品A的接口
package cn.javass.dp.abstractfactory.example2;
/**
* 抽象产品A的接口
*/
public interface AbstractProductA {
//定义抽象产品A相关的操作
}
- 1
- 2
- 3
- 4
- 5
- 6
- 7
- 8
- 9
抽象产品B的接口
package cn.javass.dp.abstractfactory.example2;
/**
* 抽象产品B的接口
*/
public interface AbstractProductB {
//定义抽象产品B相关的操作
}
- 1
- 2
- 3
- 4
- 5
- 6
- 7
- 8
- 9
- 10
产品A的具体实现
package cn.javass.dp.abstractfactory.example2;
/**
* 产品A的具体实现
*/
public class ProductA1 implements AbstractProductA {
//实现产品A的接口中定义的操作
}
- 1
- 2
- 3
- 4
- 5
- 6
- 7
- 8
- 9
- 10
产品A的具体实现
package cn.javass.dp.abstractfactory.example2;
/**
* 产品A的具体实现
*/
public class ProductA2 implements AbstractProductA {
//实现产品A的接口中定义的操作
}
- 1
- 2
- 3
- 4
- 5
- 6
- 7
- 8
- 9
- 10
- 11
- 12
- 13
产品A的具体实现
package cn.javass.dp.abstractfactory.example2;
/**
* 产品A的具体实现
*/
public class ProductA2 implements AbstractProductA {
//实现产品A的接口中定义的操作
}
- 1
- 2
- 3
- 4
- 5
- 6
- 7
- 8
- 9
- 10
- 11
- 12
- 13
产品B的具体实现
package cn.javass.dp.abstractfactory.example2;
/**
* 产品B的具体实现
*/
public class ProductB1 implements AbstractProductB {
//实现产品B的接口中定义的操作
}
- 1
- 2
- 3
- 4
- 5
- 6
- 7
- 8
- 9
- 10
- 11
- 12
- 13
产品B的具体实现
package cn.javass.dp.abstractfactory.example2;
/**
* 产品B的具体实现
*/
public class ProductB2 implements AbstractProductB {
//实现产品B的接口中定义的操作
}
- 1
- 2
- 3
- 4
- 5
- 6
- 7
- 8
- 9
- 10
- 11
- 12
抽象工厂的接口,声明创建抽象产品对象的操作
package cn.javass.dp.abstractfactory.example2;
/**
* 抽象工厂的接口,声明创建抽象产品对象的操作
*/
public interface AbstractFactory {
/**
* 示例方法,创建抽象产品A的对象
* @return 抽象产品A的对象
*/
public AbstractProductA createProductA();
/**
* 示例方法,创建抽象产品B的对象
* @return 抽象产品B的对象
*/
public AbstractProductB createProductB();
}
- 1
- 2
- 3
- 4
- 5
- 6
- 7
- 8
- 9
- 10
- 11
- 12
- 13
- 14
- 15
- 16
- 17
具体的工厂实现对象,实现创建具体的产品对象的操作
package cn.javass.dp.abstractfactory.example2;
/**
* 具体的工厂实现对象,实现创建具体的产品对象的操作
*/
public class ConcreteFactory1 implements AbstractFactory {
public AbstractProductA createProductA() {
return new ProductA1();
}
public AbstractProductB createProductB() {
return new ProductB1();
}
}
- 1
- 2
- 3
- 4
- 5
- 6
- 7
- 8
- 9
- 10
- 11
- 12
- 13
- 14
- 15
具体的工厂实现对象,实现创建具体的产品对象的操作
package cn.javass.dp.abstractfactory.example2;
/**
* 具体的工厂实现对象,实现创建具体的产品对象的操作
*/
public class ConcreteFactory2 implements AbstractFactory {
public AbstractProductA createProductA() {
return new ProductA2();
}
public AbstractProductB createProductB() {
return new ProductB2();
}
}
- 1
- 2
- 3
- 4
- 5
- 6
- 7
- 8
- 9
- 10
- 11
- 12
- 13
- 14
- 15
客户端
package cn.javass.dp.abstractfactory.example2;
public class Client {
public static void main(String[] args) {
//创建抽象工厂对象
AbstractFactory af = new ConcreteFactory1();
//通过抽象工厂来获取一系列的对象,如产品A和产品B
af.createProductA();
af.createProductB();
}
}
- 1
- 2
- 3
- 4
- 5
- 6
- 7
- 8
- 9
- 10
- 11
- 12
- 13
体会抽象工厂模式
选择组装电脑的配件
举个生活中常见的例子——组装电脑,我们在组装电脑的时候,通常需要
选择一系列的配件,比如:CPU、硬盘、内存、主板、电源、机箱等等。为了使
讨论简单点,只考虑选择CPU和主板的问题。
对于装机工程师而言,他只知道组装一台电脑,需要相应的配件,但是具
体使用什么样的配件,还得由客户说了算。也就是说装机工程师只是负责组装,
而客户负责选择装配所需要的具体的配件。
问题
现在需要使用程序来把这个装机的过程,尤其是选择组装电脑配件的过程
实现出来,该如何实现呢?
不用模式的解决方案
示例代码
CPU的接口
package cn.javass.dp.abstractfactory.example1;
/**
* CPU的接口
*/
public interface CPUApi {
/**
* 示意方法,CPU具有运算的功能
*/
public void calculate();
}
- 1
- 2
- 3
- 4
- 5
- 6
- 7
- 8
- 9
- 10
- 11
Intel的CPU实现
package cn.javass.dp.abstractfactory.example1;
/**
*Intel的CPU实现
*/
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);
}
}
- 1
- 2
- 3
- 4
- 5
- 6
- 7
- 8
- 9
- 10
- 11
- 12
- 13
- 14
- 15
- 16
- 17
- 18
- 19
- 20
- 21
- 22
AMD的CPU实现
package cn.javass.dp.abstractfactory.example1;
/**
* AMD的CPU实现
*/
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);
}
}
- 1
- 2
- 3
- 4
- 5
- 6
- 7
- 8
- 9
- 10
- 11
- 12
- 13
- 14
- 15
- 16
- 17
- 18
- 19
- 20
- 21
- 22
主板的接口
package cn.javass.dp.abstractfactory.example1;
/**
* 主板的接口
*/
public interface MainboardApi {
/**
* 示意方法,主板都具有安装CPU的功能
*/
public void installCPU();
}
- 1
- 2
- 3
- 4
- 5
- 6
- 7
- 8
- 9
- 10
- 11
- 12
微星的主板
package cn.javass.dp.abstractfactory.example1;
/**
* 微星的主板
*/
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);
}
}
- 1
- 2
- 3
- 4
- 5
- 6
- 7
- 8
- 9
- 10
- 11
- 12
- 13
- 14
- 15
- 16
- 17
- 18
- 19
- 20
- 21
- 22
技嘉的主板
package cn.javass.dp.abstractfactory.example1;
/**
* 技嘉的主板
*/
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="+cpuHoles);
}
}
- 1
- 2
- 3
- 4
- 5
- 6
- 7
- 8
- 9
- 10
- 11
- 12
- 13
- 14
- 15
- 16
- 17
- 18
- 19
- 20
- 21
- 22
创建CPU的简单工厂
package cn.javass.dp.abstractfactory.example1;
/**
* 创建CPU的简单工厂
*/
public class CPUFactory {
/**
* 创建CPU接口对象的方法
* @param type 选择CPU类型的参数
* @return CPU接口对象的方法
*/
public static CPUApi createCPUApi(int type){
CPUApi cpu = ;
//根据参数来选择并创建相应的CPU对象
if(type==1){
cpu = new IntelCPU(1156);
}else if(type==2){
cpu = new AMDCPU(939);
}
return cpu;
}
}
- 1
- 2
- 3
- 4
- 5
- 6
- 7
- 8
- 9
- 10
- 11
- 12
- 13
- 14
- 15
- 16
- 17
- 18
- 19
- 20
- 21
- 22
- 23
- 24
创建主板的简单工厂
package cn.javass.dp.abstractfactory.example1;
/**
* 创建主板的简单工厂
*/
public class MainboardFactory {
/**
* 创建主板接口对象的方法
* @param type 选择主板类型的参数
* @return 主板接口对象的方法
*/
public static MainboardApi createMainboardApi(int type){
MainboardApi mainboard = ;
//根据参数来选择并创建相应的主板对象
if(type==1){
mainboard = new GAMainboard(1156);
}else if(type==2){
mainboard = new MSIMainboard(939);
}
return mainboard;
}
}
- 1
- 2
- 3
- 4
- 5
- 6
- 7
- 8
- 9
- 10
- 11
- 12
- 13
- 14
- 15
- 16
- 17
- 18
- 19
- 20
- 21
- 22
- 23
- 24
客户端
package cn.javass.dp.abstractfactory.example1;
public class Client {
public static void main(String[] args) {
//创建装机工程师对象
ComputerEngineer engineer = new ComputerEngineer();
//告诉装机工程师自己选择的配件,让装机工程师组装电脑
engineer.makeComputer(1,2);
}
}
- 1
- 2
- 3
- 4
- 5
- 6
- 7
- 8
- 9
- 10
- 11
- 12
- 13
存在的问题
虽然上面的实现,通过简单工厂解决解决了:对于装机工程师,只知CPU
和主板的接口,而不知道具体实现的问题。但还有一个问题没有解决,什么问题
呢?那就是这些CPU对象和主板对象其实是有关系的,是需要相互匹配的。
n使用模式的解决方案
先来看看如何使用抽象工厂模式来解决前面提出的问题。
装机工程师要组装电脑对象,需要一系列的产品对象,比如CPU、主板
等,于是创建一个抽象工厂给装机工程师使用,在这个抽象工厂里面定义抽象的
创建CPU和主板的方法,这个抽象工厂就相当于一个抽象的装机方案,在这个装
机方案里面,各个配件是能够相互匹配的。
每个装机的客户,会提出他们自己的具体装机方案,或者是选择已有的装
机方案,相当于为抽象工厂提供了具体的子类,在这些具体的装机方案类里面,
会创建具体的CPU和主板实现对象。
使用模式的解决方案的结构图
示例代码
主板的接口
package cn.javass.dp.abstractfactory.example3;
/**
* 主板的接口
*/
public interface MainboardApi {
/**
* 示意方法,主板都具有安装CPU的功能
*/
public void installCPU();
}
- 1
- 2
- 3
- 4
- 5
- 6
- 7
- 8
- 9
- 10
示例代码
微星的主板
package cn.javass.dp.abstractfactory.example3;
/**
* 微星的主板
*/
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);
}
}
- 1
- 2
- 3
- 4
- 5
- 6
- 7
- 8
- 9
- 10
- 11
- 12
- 13
- 14
- 15
- 16
- 17
- 18
- 19
- 20
- 21
技嘉的主板
package cn.javass.dp.abstractfactory.example3;
/**
* 技嘉的主板
*/
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="+cpuHoles);
}
}
- 1
- 2
- 3
- 4
- 5
- 6
- 7
- 8
- 9
- 10
- 11
- 12
- 13
- 14
- 15
- 16
- 17
- 18
- 19
- 20
CPU的接口
package cn.javass.dp.abstractfactory.example3;
/**
* CPU的接口
*/
public interface CPUApi {
/**
* 示意方法,CPU具有运算的功能
*/
public void calculate();
}
- 1
- 2
- 3
- 4
- 5
- 6
- 7
- 8
- 9
- 10
AMD的CPU实现
package cn.javass.dp.abstractfactory.example3;
/**
* AMD的CPU实现
*/
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);
}
}
- 1
- 2
- 3
- 4
- 5
- 6
- 7
- 8
- 9
- 10
- 11
- 12
- 13
- 14
- 15
- 16
- 17
- 18
- 19
- 20
Intel的CPU实现
package cn.javass.dp.abstractfactory.example3;
/**
*Intel的CPU实现
*/
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);
}
}
- 1
- 2
- 3
- 4
- 5
- 6
- 7
- 8
- 9
- 10
- 11
- 12
- 13
- 14
- 15
- 16
- 17
- 18
- 19
- 20
- 21
- 22
抽象工厂的接口,声明创建抽象产品对象的操作
package cn.javass.dp.abstractfactory.example3;
/**
* 抽象工厂的接口,声明创建抽象产品对象的操作
*/
public interface AbstractFactory {
/**
* 创建CPU的对象
* @return CPU的对象
*/
public CPUApi createCPUApi();
/**
* 创建主板的对象
* @return 主板的对象
*/
public MainboardApi createMainboardApi();
}
- 1
- 2
- 3
- 4
- 5
- 6
- 7
- 8
- 9
- 10
- 11
- 12
- 13
- 14
- 15
- 16
装机方案一:Intel 的CPU + 技嘉的主板
package cn.javass.dp.abstractfactory.example3;
/**
* 装机方案一:Intel 的CPU + 技嘉的主板
* 这里创建CPU和主板对象的时候,是对应的,能匹配上的
*/
public class Schema1 implements AbstractFactory{
public CPUApi createCPUApi() {
return new IntelCPU(1156);
}
public MainboardApi createMainboardApi() {
return new GAMainboard(1156);
}
}
- 1
- 2
- 3
- 4
- 5
- 6
- 7
- 8
- 9
- 10
- 11
- 12
- 13
- 14
装机方案二:AMD的CPU + 微星的主板
package cn.javass.dp.abstractfactory.example3;
/**
* 装机方案二:AMD的CPU + 微星的主板
* 这里创建CPU和主板对象的时候,是对应的,能匹配上的
*/
public class Schema2 implements AbstractFactory{
public CPUApi createCPUApi() {
return new AMDCPU(939);
}
public MainboardApi createMainboardApi() {
return new MSIMainboard(939);
}
}
- 1
- 2
- 3
- 4
- 5
- 6
- 7
- 8
- 9
- 10
- 11
- 12
- 13
- 14
装机工程师的类
package cn.javass.dp.abstractfactory.example3;
/**
* 装机工程师的类
*/
public class ComputerEngineer {
/**
* 定义组装机器需要的CPU
*/
private CPUApi cpu= ;
/**
* 定义组装机器需要的主板
*/
private MainboardApi mainboard = ;
/**
* 装机过程
* @param schema 客户选择的装机方案
*/
public void makeComputer(AbstractFactory schema){
//1:首先准备好装机所需要的配件
prepareHardwares(schema);
//2:组装机器
//3:测试机器
//4:交付客户
}
/**
* 准备装机所需要的配件
* @param schema 客户选择的装机方案
*/
private void prepareHardwares(AbstractFactory schema){
//这里要去准备CPU和主板的具体实现,为了示例简单,这里只准备这两个
//可是,装机工程师并不知道如何去创建,怎么办呢?
//使用抽象工厂来获取相应的接口对象
this.cpu = schema.createCPUApi();
this.mainboard = schema.createMainboardApi();
//测试一下配件是否好用
this.cpu.calculate();
this.mainboard.installCPU();
}
}
- 1
- 2
- 3
- 4
- 5
- 6
- 7
- 8
- 9
- 10
- 11
- 12
- 13
- 14
- 15
- 16
- 17
- 18
- 19
- 20
- 21
- 22
- 23
- 24
- 25
- 26
- 27
- 28
- 29
- 30
- 31
- 32
- 33
- 34
- 35
- 36
- 37
- 38
- 39
- 40
- 41
- 42
- 43
- 44
- 45
- 46
客户端
package cn.javass.dp.abstractfactory.example3;
public class Client {
public static void main(String[] args) {
//创建装机工程师对象
ComputerEngineer engineer = new ComputerEngineer();
//客户选择并创建需要使用的装机方案对象
AbstractFactory schema = new Schema2();
//告诉装机工程师自己选择的装机方案,让装机工程师组装电脑
engineer.makeComputer(schema);
}
}
- 1
- 2
- 3
- 4
- 5
- 6
- 7
- 8
- 9
- 10
- 11
- 12
- 13
理解抽象工厂模式
认识抽象工厂模式
1:模式的功能
抽象工厂的功能是为一系列相关对象或相互依赖的对象创建一个接口。
从某种意义上看,抽象工厂其实是一个产品系列,或者是产品簇。
2:实现成接口
AbstractFactory在Java中通常实现成为接口,大家不要被名称误导了,以
为是实现成为抽象类
3:使用工厂方法
AbstractFactory定义了创建产品所需要的接口,具体的实现是在实现类里
面,通常在实现类里面就需要选择多种更具体的实现,所以AbstractFactory定
义的创建产品的方法可以看成是工厂方法,而这些工厂方法的具体实现就延迟到
了具体的工厂里面。也就是说使用工厂方法来实现抽象工厂。
4:切换产品簇
抽象工厂定义了一个产品簇,因此切换产品簇的时候提供不同的抽象工厂就好了
5:抽象工厂模式的调用顺序示意图
定义可扩展的工厂
在前面的示例中,抽象工厂为每一种它能创建的产品对象都定义了相应的
方法,比如创建CPU的方法和创建主板的方法等。
这种实现有一个麻烦,就是如果在产品簇中要新增加一种产品,比如现在
要求抽象工厂除了能够创建CPU和主板外,还要能够创建内存对象,那么就需要
在抽象工厂里面添加创建内存的这么一个方法。当抽象工厂一发生变化,所有的
具体工厂实现都要发生变化,这非常的不灵活。
现在有一种相对灵活,但是不太安全的改进方式来解决这个问题,思路如
下:抽象工厂里面不需要定义那么多方法,定义一个方法就可以了,给这个方法
设置一个参数,通过这个参数来判断具体创建什么产品对象;由于只有一个方
法,在返回类型上就不能是具体的某个产品类型了,只能是所有的产品对象都继
承或者实现的这么一个类型,比如让所有的产品都实现某个接口,或者干脆使用
Object类型。
示例代码
cup、主板的代码相同,添加内存模块
内存的接口
package cn.javass.dp.abstractfactory.example4;
/**
* 内存的接口
*/
public interface MemoryApi {
/**
* 示意方法,内存具有缓存数据的能力
*/
public void cacheData();
}
- 1
- 2
- 3
- 4
- 5
- 6
- 7
- 8
- 9
- 10
- 11
现代内存的类
package cn.javass.dp.abstractfactory.example4;
/**
* 现代内存的类
*/
public class HyMemory implements MemoryApi{
public void cacheData() {
System.out.println("现在正在使用现代内存");
}
}
- 1
- 2
- 3
- 4
- 5
- 6
- 7
- 8
- 9
- 10
装机方案一:Intel 的CPU + 技嘉的主板
package cn.javass.dp.abstractfactory.example4;
/**
* 装机方案一:Intel 的CPU + 技嘉的主板
* 这里创建CPU和主板对象的时候,是对应的,能匹配上的
*/
public class Schema1 implements AbstractFactory{
public Object createProduct(int type) {
Object retObj = ;
//type为1表示创建CPU,type为2表示创建主板
if(type==1){
retObj = new IntelCPU(1156);
}else if(type==2){
retObj = new GAMainboard(1156);
}
return retObj;
}
}
- 1
- 2
- 3
- 4
- 5
- 6
- 7
- 8
- 9
- 10
- 11
- 12
- 13
- 14
- 15
- 16
- 17
- 18
可扩展的抽象工厂的接口
package cn.javass.dp.abstractfactory.example4;
/**
* 可扩展的抽象工厂的接口
*/
public interface AbstractFactory {
/**
* 一个通用的创建产品对象的方法,为了简单,直接返回Object
* 也可以为所有被创建的产品定义一个公共的接口
* @param type 具体创建的产品类型标识
* @return 创建出的产品对象
*/
public Object createProduct(int type);
}
- 1
- 2
- 3
- 4
- 5
- 6
- 7
- 8
- 9
- 10
- 11
- 12
- 13
- 14
装机方案一:Intel 的CPU + 技嘉的主板
package cn.javass.dp.abstractfactory.example4;
/**
* 装机方案一:Intel 的CPU + 技嘉的主板
* 这里创建CPU和主板对象的时候,是对应的,能匹配上的
*/
public class Schema1 implements AbstractFactory{
public Object createProduct(int type) {
Object retObj = ;
//type为1表示创建CPU,type为2表示创建主板
if(type==1){
retObj = new IntelCPU(1156);
}else if(type==2){
retObj = new GAMainboard(1156);
}
return retObj;
}
}
- 1
- 2
- 3
- 4
- 5
- 6
- 7
- 8
- 9
- 10
- 11
- 12
- 13
- 14
- 15
- 16
- 17
- 18
装机方案二:AMD的CPU + 微星的主板
package cn.javass.dp.abstractfactory.example4;
/**
* 装机方案二:AMD的CPU + 微星的主板
* 这里创建CPU和主板对象的时候,是对应的,能匹配上的
*/
public class Schema2 implements AbstractFactory{
public Object createProduct(int type) {
Object retObj = ;
//type为1表示创建CPU,type为2表示创建主板
if(type==1){
retObj = new AMDCPU(939);
}else if(type==2){
retObj = new MSIMainboard(939);
}
return retObj;
}
}
- 1
- 2
- 3
- 4
- 5
- 6
- 7
- 8
- 9
- 10
- 11
- 12
- 13
- 14
- 15
- 16
- 17
- 18
装机方案三:Intel 的CPU + 技嘉的主板 + 现代的内存
package cn.javass.dp.abstractfactory.example4;
/**
* 装机方案三:Intel 的CPU + 技嘉的主板 + 现代的内存
*/
public class Schema3 implements AbstractFactory{
public Object createProduct(int type) {
Object retObj = ;
//type为1表示创建CPU,type为2表示创建主板,type为3表示创建内存
if(type==1){
retObj = new IntelCPU(1156);
}else if(type==2){
retObj = new GAMainboard(1156);
}
//创建新添加的产品
else if(type==3){
retObj = new HyMemory();
}
return retObj;
}
}
- 1
- 2
- 3
- 4
- 5
- 6
- 7
- 8
- 9
- 10
- 11
- 12
- 13
- 14
- 15
- 16
- 17
- 18
- 19
- 20
- 21
- 22
装机工程师的类
package cn.javass.dp.abstractfactory.example4;
/**
* 装机工程师的类
*/
public class ComputerEngineer {
/**
* 定义组装机器需要的CPU
*/
private CPUApi cpu= ;
/**
* 定义组装机器需要的主板
*/
private MainboardApi mainboard = ;
/**
* 定义组装机器需要的内存
*/
private MemoryApi memory = ;
/**
* 装机过程
* @param schema 客户选择的装机方案
*/
public void makeComputer(AbstractFactory schema){
//1:首先准备好装机所需要的配件
prepareHardwares(schema);
//2:组装机器
//3:测试机器
//4:交付客户
}
/**
* 准备装机所需要的配件
* @param schema 客户选择的装机方案
*/
private void prepareHardwares(AbstractFactory schema){
//这里要去准备CPU和主板的具体实现,为了示例简单,这里只准备这两个
//可是,装机工程师并不知道如何去创建,怎么办呢?
//使用抽象工厂来获取相应的接口对象
this.cpu = (CPUApi)schema.createProduct(1);
this.mainboard = (MainboardApi)schema.createProduct(2);
this.memory = (MemoryApi)schema.createProduct(3);
//测试一下配件是否好用
this.cpu.calculate();
this.mainboard.installCPU();
if(memory!=){
this.memory.cacheData();
}
}
}
- 1
- 2
- 3
- 4
- 5
- 6
- 7
- 8
- 9
- 10
- 11
- 12
- 13
- 14
- 15
- 16
- 17
- 18
- 19
- 20
- 21
- 22
- 23
- 24
- 25
- 26
- 27
- 28
- 29
- 30
- 31
- 32
- 33
- 34
- 35
- 36
- 37
- 38
- 39
- 40
- 41
- 42
- 43
- 44
- 45
- 46
- 47
- 48
- 49
- 50
- 51
- 52
- 53
- 54
客户端
package cn.javass.dp.abstractfactory.example4;
public class Client {
public static void main(String[] args) {
//创建装机工程师对象
ComputerEngineer engineer = new ComputerEngineer();
//客户选择并创建需要使用的装机方案对象
AbstractFactory schema = new Schema3();
//告诉装机工程师自己选择的装机方案,让装机工程师组装电脑
engineer.makeComputer(schema);
}
}
- 1
- 2
- 3
- 4
- 5
- 6
- 7
- 8
- 9
- 10
- 11
- 12
- 13
抽象工厂和DAO
一:DAO知识回顾
- 1:DAO:数据访问对象,是Data Access Object首字母的简写
- 2:DAO是JEE(也称JavaEE,原J2EE)中的一个标准模式,通过它来解决访问数据对
象所面临的一系列问题,比如:数据源不同、存储类型不同、访问方式不同、供
应商不同、版本不同等等,这些不同会造成访问数据的实现上差别很大。 - 3:使用DAO的系统结构图
- 4:DAO需要抽象和封装所有对数据的访问,DAO承担和数据仓库交互的职责,这也意
味着,访问数据所面临的所有问题,都需要DAO在内部来自行解决
示例代码
订单子记录对应的DAO操作接口
package cn.javass.dp.abstractfactory.example5;
/**
* 订单子记录对应的DAO操作接口
*/
public interface OrderDetailDAO {
/**
* 示意方法,保存订单子记录
*/
public void saveOrderDetail();
}
- 1
- 2
- 3
- 4
- 5
- 6
- 7
- 8
- 9
- 10
实现xml订单详细
package cn.javass.dp.abstractfactory.example5;
public class XmlDetailDAOImpl implements OrderDetailDAO{
public void saveOrderDetail() {
System.out.println("now in XmlDAOImpl2 saveOrderDetail");
}
}
- 1
- 2
- 3
- 4
- 5
- 6
- 7
- 8
- 9
- 10
实现rdb订单详细
package cn.javass.dp.abstractfactory.example5;
public class RdbDetailDAOImpl implements OrderDetailDAO{
public void saveOrderDetail() {
System.out.println("now in RdbDetailDAOImpl saveOrderDetail");
}
}
- 1
- 2
- 3
- 4
- 5
- 6
- 7
- 8
订单主记录对应的DAO操作接口
package cn.javass.dp.abstractfactory.example5;
/**
* 订单主记录对应的DAO操作接口
*/
public interface OrderMainDAO {
/**
* 示意方法,保存订单主记录
*/
public void saveOrderMain();
}
- 1
- 2
- 3
- 4
- 5
- 6
- 7
- 8
- 9
- 10
实现xml订单主记录
package cn.javass.dp.abstractfactory.example5;
public class XmlMainDAOImpl implements OrderMainDAO{
public void saveOrderMain() {
System.out.println("now in XmlMainDAOImpl saveOrderMain");
}
}
- 1
- 2
- 3
- 4
- 5
- 6
- 7
- 8
- 9
实现rdb订单主记录
package cn.javass.dp.abstractfactory.example5;
public class RdbMainDAOImpl implements OrderMainDAO{
public void saveOrderMain() {
System.out.println("now in RdbMainDAOImpl saveOrderMain");
}
}
- 1
- 2
- 3
- 4
- 5
- 6
- 7
- 8
抽象工厂,创建订单主、子记录对应的DAO对象
package cn.javass.dp.abstractfactory.example5;
/**
* 抽象工厂,创建订单主、子记录对应的DAO对象
*/
public abstract class DAOFactory {
/**
* 创建订单主记录对应的DAO对象
* @return 订单主记录对应的DAO对象
*/
public abstract OrderMainDAO createOrderMainDAO();
/**
* 创建订单子记录对应的DAO对象
* @return 订单子记录对应的DAO对象
*/
public abstract OrderDetailDAO createOrderDetailDAO();
}
- 1
- 2
- 3
- 4
- 5
- 6
- 7
- 8
- 9
- 10
- 11
- 12
- 13
- 14
- 15
- 16
- 17
实现xml抽象工厂
package cn.javass.dp.abstractfactory.example5;
public class XmlDAOFactory extends DAOFactory {
public OrderDetailDAO createOrderDetailDAO() {
return new XmlDetailDAOImpl();
}
public OrderMainDAO createOrderMainDAO() {
return new XmlMainDAOImpl();
}
}
- 1
- 2
- 3
- 4
- 5
- 6
- 7
- 8
- 9
- 10
实现rdb抽象工厂
package cn.javass.dp.abstractfactory.example5;
public class RdbDAOFactory extends DAOFactory{
public OrderDetailDAO createOrderDetailDAO() {
return new RdbDetailDAOImpl();
}
public OrderMainDAO createOrderMainDAO() {
return new RdbMainDAOImpl();
}
}
- 1
- 2
- 3
- 4
- 5
- 6
- 7
- 8
- 9
- 10
DAO和抽象工厂的关系
在实现DAO模式的时候,最常见的实现策略就是使用工厂的策略,而且多是
通过抽象工厂模式来实现,当然在使用抽象工厂模式来实现的时候,可以结合工
厂方法模式。因此DAO模式和抽象工厂模式有很大的联系。
DAO模式采用工厂方法模式来实现的策略
DAO模式采用抽象工厂模式来实现的策略
dao实现结构
抽象工厂模式的优缺点
- 1:分离接口和实现
- 2:使得切换产品簇变得容易
- 3:不太容易扩展新的产品
- 4:容易造成类层次复杂
思考抽象工厂模式
抽象工厂模式的本质
抽象工厂模式的本质是:选择产品簇的实现
n何时选用抽象工厂模式
- 1:如果希望一个系统独立于它的产品的创建,组合和表示的时候,换句话说,希望
一个系统只是知道产品的接口,而不关心实现的时候 - 2:如果一个系统要由多个产品系列中的一个来配置的时候,换句话说,就是可以动
态的切换产品簇的时候 - 3:如果要强调一系列相关产品的接口,以便联合使用它们的时候