设计模式 - 抽象工厂模式案例

抽象工厂模式vs工厂方法模式

  1. 工厂方法模式中具体工厂只需要生产一种具体产品
  2. 抽象工厂模式中具体工厂可以生产相关的一组具体产品,这样的一组产品称为产品族

引入两个概念

产品等级结构

产品等级结构:产品的继承结构。

比如:抽象电视机和具体品牌电视之间构成了一个产品等级结构
在这里插入图片描述

产品族

产品族:是指由同一个工厂生产的,位于不同产品等级结构一组产品

比如:
① 海尔工厂生成的海尔电视机、海尔电冰箱。
海尔电视机、海尔电冰箱就属于同一个产品族
③ 在这里海尔电视机属于电视机产品等级结构,海尔电冰箱属于电冰箱等级结构 ,它们位于不同产品等级结构
在这里插入图片描述

模式结构的角色

  1. 抽象工厂

① 定义了返回具体产品对象的方法
产品有几种就定义几个方法

  1. 具体工厂

① 实现父类中 返回具体产品对象的方法
具体工厂的个数 = 产品族的个数 --> 品牌的个数

  1. 抽象产品

① 将业务方法抽象出来
抽象产品的个数 = 产品等级结构的个数 -->电视机、电冰箱 (产品类别的个数)

  1. 具体产品

① 只要指明一个产品所处的产品族,以及所属的产品等级结构,就可以唯一确定这个产品
② 实现该产品的业务方法
具体产品的个数 = 产品族个数(品牌) * 产品等级结构的个数(产品类别)
比如品牌(产品族)有两个:海尔和海信
抽象产品(产品等级结构)有两个:电视机、电冰箱
则具体产品就是2 * 2

抽象工厂模式案例

案例背景

计算机包含内存(RAM),CPU等硬件设备,根据如图所示的“产品等级结构-产品族示意图”,使用抽象工厂模式实现计算机设备创建过程并绘制类图
在这里插入图片描述

案例分析

  1. 产品族(即具体工厂 --> 品牌)的个数有两个:PC 和 MAC
  2. 产品等级结构(即抽象产品 --> 产品类别)的个数有两个:CPU 和 RAM

实现步骤

  1. 编写一个抽象工厂类:AbstractFactory,
    两个具体工厂:PcFactory和MacFactory ,
    两个抽象产品类:CPU,RAM,
    四个具体产品类:PcCPU,MacCPU,PcRAM,MacRAM
  2. 编写一个用户类Client和辅助类XMLUtil以实现通过XML文件来制造不同的产品
  3. 更改XML中的属性,观察用户类是否能使用不同的产品

代码实现(按顺序)

文件结构/类图

在这里插入图片描述

在这里插入图片描述

1. 抽象产品类(2个)

/**
 * @author 王胖子
 * @version 1.0
 */
public interface CPU {
    public void play();
}

/**
 * @author 王胖子
 * @version 1.0
 */
public interface RAM {
    public void play();
}

2. 具体产品类(4个)

一个具体工厂生产一个产品族,一个产品族里有两种产品:CPU和RAM
② 有两个具体工厂:PC工厂 和 MAC工厂
PC工厂生产 PcCPU 和 PcRAM

/**
 * @author 王胖子
 * @version 1.0
 */
public class PcCPU implements CPU {
    @Override
    public void play() {
        System.out.println("PC的CPU工作中...");
    }
}
/**
 * @author 王胖子
 * @version 1.0
 */
public class PcRAM implements RAM {
    @Override
    public void play() {
        System.out.println("PC的RAM工作中...");
    }
}

/**
 * @author 王胖子
 * @version 1.0
 */
public class MacCPU implements CPU {
    @Override
    public void play() {
        System.out.println("MAC的CPU工作中...");
    }
}

/**
 * @author 王胖子
 * @version 1.0
 */
public class MacRAM implements RAM {
    @Override
    public void play() {
        System.out.println("MAC的RAM工作中...");
    }
}

3. 抽象工厂(1个)

/**
 * @author 王胖子
 * @version 1.0
 */
public interface AbstractFactory {
    public CPU produceCPU();
    public RAM produceRAM();
}

4. 具体工厂(2个)

/**
 * @author 王胖子
 * @version 1.0
 */
public class PcFactory implements AbstractFactory {
    @Override
    public CPU produceCPU() {
        return new PcCPU();
    }

    @Override
    public RAM produceRAM() {
        return new PcRAM();
    }
}

/**
 * @author 王胖子
 * @version 1.0
 */
public class MacFactory implements AbstractFactory {
    @Override
    public CPU produceCPU() {
        return new MacCPU();
    }

    @Override
    public RAM produceRAM() {
        return new MacRAM();
    }
}

5. 配置类(config.xml)

<?xml version="1.0"?>
<config>
    <className>PcFactory</className>
</config>

6. 读取配置类(XMLUtil.java)

import org.w3c.dom.Document;
import org.w3c.dom.Node;
import org.w3c.dom.NodeList;

import javax.xml.parsers.DocumentBuilder;
import javax.xml.parsers.DocumentBuilderFactory;
import javax.xml.parsers.ParserConfigurationException;
import java.io.File;

/**
 * @author 王胖子
 * @version 1.0
 */
public class XMLUtil {
    //该方法用于从xml配置文件中提取具体类类名,并返回一个实例对象
    public static Object getBean() {
        try {
            //创建DOM对象
            DocumentBuilderFactory dFactory = DocumentBuilderFactory.newInstance();
            DocumentBuilder builder = dFactory.newDocumentBuilder();
            Document doc;
            //这个地址从项目根目录开始读取
            doc = builder.parse(new File("src//config.xml"));

            //获取包含类名的文本节点
            NodeList nl = doc.getElementsByTagName("className");
            Node classNode = nl.item(0).getFirstChild();
            String cName = classNode.getNodeValue();

            //通过类名生成实例对象并返回
            Class c = Class.forName(cName);
            Object obj = c.newInstance();
            return obj;
        } catch (Exception e) {
            e.printStackTrace();
            return null;
        }
    }
}

7. 客户类

/**
 * @author 王胖子
 * @version 1.0
 */
public class Client {
    public static void main(String[] args) {
        CPU cpu;
        RAM ram;
        AbstractFactory factory;
        factory = (AbstractFactory) XMLUtil.getBean();
        cpu = factory.produceCPU();
        ram = factory.produceRAM();
        cpu.play();
        ram.play();
    }
}

输出结果

在这里插入图片描述

模式适用环境

抽象工厂模式主要适用于:

  1. 一个系统不应当依赖于产品类实例如何被创建、组合和表达的细节
  2. 系统中有多于一个的产品族,但每次只使用其中某一产品族
  3. 属于同一个产品族的产品将在一起使用,这一约束必须在系统的设计中体现出来
  4. 产品等级结构稳定,在设计完成之后不会向系统中增加新的产品等级结构或者删除已有的产品等级结构
  • 7
    点赞
  • 98
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
以下是一个Java抽象工厂模式实例,该实例演示了如何使用抽象工厂模式创建不同操作系统下的按钮和文本框: ```java // 创建抽象工厂接口 interface GUIFactory { Button createButton(); TextField createTextField(); } // 创建具体工厂类 - Windows工厂 class WindowsFactory implements GUIFactory { public Button createButton() { return new WindowsButton(); } public TextField createTextField() { return new WindowsTextField(); } } // 创建具体工厂类 - MacOS工厂 class MacOSFactory implements GUIFactory { public Button createButton() { return new MacOSButton(); } public TextField createTextField() { return new MacOSTextField(); } } // 创建抽象产品接口 - 按钮 interface Button { void paint(); } // 创建具体产品类 - Windows按钮 class WindowsButton implements Button { public void paint() { System.out.println("Windows Button"); } } // 创建具体产品类 - MacOS按钮 class MacOSButton implements Button { public void paint() { System.out.println("MacOS Button"); } } // 创建抽象产品接口 - 文本框 interface TextField { void paint(); } // 创建具体产品类 - Windows文本框 class WindowsTextField implements TextField { public void paint() { System.out.println("Windows TextField"); } } // 创建具体产品类 - MacOS文本框 class MacOSTextField implements TextField { public void paint() { System.out.println("MacOS TextField"); } } // 创建客户端类 class Application { private Button button; private TextField textField; public Application(GUIFactory factory) { button = factory.createButton(); textField = factory.createTextField(); } public void paint() { button.paint(); textField.paint(); } } // 测试代码 public class Main { public static void main(String[] args) { // 创建Windows工厂 GUIFactory factory = new WindowsFactory(); // 创建应用程序 Application app = new Application(factory); // 绘制UI app.paint(); // 创建MacOS工厂 factory = new MacOSFactory(); // 创建应用程序 app = new Application(factory); // 绘制UI app.paint(); } } ```

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值