在工厂方法模式中具体工厂负责生产具体的产品,每一个具体工厂对应一种具体产品,工厂方法也具有唯一性,一般情况下,一个具体工厂中只有一个工厂方法或者一组重载的工厂方法。但是有时候我们需要一个工厂可以提供多个产品对象,而不是单一的产品对象,如一个电器设备工厂,它可以生产电视机、电冰箱、空调等设备,而不只是生成某种类型的电器。
因此我们引入了一个新的设计模式:抽象工厂模式。
抽象工厂模式定义:抽象工厂模式是工厂方法模式的泛化版,工厂方法模式是一种特殊的抽象工厂模式。在工厂方法模式中,每一个具体工厂只能生产一种具体产品,而在抽象工厂方法模式中,每一个具体工厂可以生产多个具体产品。在实际的软件开发中,抽象工厂模式使用频率较高,
下面将深化抽象工厂模式的学习。
抽象工厂模式包含如下角色:
1.AbstractProduct(抽象产品)
抽象产品为每种产品声明接口,在抽象产品中定义了产品的抽象业务方法。
2.ConcreteProduct(具体产品)
具体产品定义具体工厂生产的具体产品对象,实现抽象接口产品接口中定义的业务方法,
3.AbstractFactory(抽象工厂)
抽象工厂用于声明生成抽象产品的方法,在一个抽象工厂中可以定义一组方法,每一个方法对应一个产品等级结构。
4.ConcreteFactory(具体工厂)
具体工厂实现了抽象工厂声明的生成抽象产品的方法,生成一组具体产品,这些产品成了一个产品族,每一个产品都位于某个产品等姐结构中。
题目:电脑配件生产工厂生产内存、CPU等硬件设备,这些内存、CPU的品牌、型号并不一定相同,根据下面的“产品等级结构-产品族”示意图,使用抽象工厂模式实现电脑配件生产过程并绘制相应的类图,绘制类图并编程实现。
1.抽象产品类 CPU(CPU类)
public interface CPU {
public void paly();
}
CPU作为抽象产品类,它可以是一个接口,也可以是一个抽象类,其中包含了所有产品都具有的业务方法play().
2.具体产品类MacCPU(MacCPU类)
public class MacCPU implements CPU{
@Override
public void paly() {
System.out.println("MacCPU正在运行中。。。");
}
}
MacCPU是抽象产品CPU接口的子类,它是一种具体产品,实现了在CPU接口中定义的业务方法paly()。
3.具体产品类PcCPU(PcCPU类)
public class PcCPU implements CPU{
@Override
public void paly() {
System.out.println("PcCPU正在运行中。。。");
}
}
PcCPU是抽象产品CPU的另一个子类。
4.抽象产品类 RAM(RAM类)
public interface RAM {
public void work();
}
RAM作为抽象产品类,它可以是一个接口,也可以是一个抽象类,其中包含了所有产品都具有的业务方法work().
5.具体产品类MacRAM(MacRAM类)
public class MacRAM implements RAM{
@Override
public void work() {
System.out.println("MacRAM正在运行中。。。");
}
}
MacRAM是抽象产品RAM接口的子类,它是一种具体产品,实现了在CPU接口中定义的业务方法work()。
6.具体产品类PcRAM(PcRAM类)
public class PcRAMimplements RAM{
@Override
public void work() {
System.out.println("PcRAM正在运行中。。。");
}
}
PcRAM是抽象产品RAM的另一个子类。
7.抽象工厂类ComputerFactory(电脑工厂类)
public interface ComputerFactory {
public CPU produceCPU();
public RAM produceRAM();
}
ComputerFactory类是抽象工厂类,其中定义了抽象工厂方法,针对每一个产品族的产品都提供了一个对应的工厂方法。
8.具体工厂类MacFactory(Mac工厂类)
package abstract_factory_pattern;
public class MacFactory implements ComputerFactory{
@Override
public CPU produceCPU() {
System.out.println("已生产MacCPU");
return new MacCPU();
}
@Override
public RAM produceRAM() {
System.out.println("已生产MacRAM");
return new MacRAM();
}
}
MacFactory是ComputerFactory的一个子类,实现了在ComputerFactory中定义的工厂方法,用于创建具体产品对象。MacFactory所生产的具体产品构成了一个产品族。
9.具体工厂类PcFactory(Pc工厂类)
package abstract_factory_pattern;
public class PcFactory implements ComputerFactory{
@Override
public CPU produceCPU() {
System.out.println("已生产PcCPU");
return new PcCPU();
}
@Override
public RAM produceRAM() {
System.out.println("已生产PcRAM");
return new PcRAM();
}
}
PcFactory是ComputerFactory的另一个子类,实现了在ComputerFactory中定义的工厂方法,用于创建具体产品对象。PcFactory所生产的具体产品构成了一个产品族。
MacFactory、PcFactory和ComputerFactory构成了一个工厂等级结构。
3.3辅助代码
package abstract_factory_pattern;
import org.w3c.dom.*;
import javax.xml.parsers.*;
import java.io.*;
public class XMLUtil {
public static Object getBean(){
try {
//创建DOM文档对象
DocumentBuilderFactory dFactory =DocumentBuilderFactory.newInstance();
DocumentBuilder builder = dFactory.newDocumentBuilder();
Document doc;
doc = builder.parse(new File("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;
}
}
}
2.配置文件config.xml
abstract_factory_pattern.MacFactory
3.客户端测试类Client
package abstract_factory_pattern;
public class Client {
public static void main(String[] args) {
ComputerFactory factory;
CPU cpu;
RAM ram;
factory = (ComputerFactory) XMLUtil.getBean();
cpu = factory.produceCPU();
cpu.paly();
ram = factory.produceRAM();
ram.work();
}
}
如果在配置文件中将
如果在配置文件中将
(1)抽象工厂模式隔离了具体类的生成,使得客户并不需要知道什么被创建。由于这种隔离,更换一个具体工厂就变得相对容易。所有的具体工厂都实现了抽象工厂申定义的那些公共接口,因此只需改变具体工厂的实例,就可以在某种程度上改变整个软件系统的行为。另外,应用抽象工厂模式可以实现高内聚低轉合的设计目的,因此抽象工厂模式得到了广泛的应用。
(2)当一个产品族中的多个对象被设计成一起工作时,它能够保证客户端始终只使用同一个产品族中的对象。这对一些需要根据当前环境来决定其行为的软件系统来说,是一种非常实用的设计模式。
(3)增加新的具体工厂和产品族很方便,无须修改已有系统,符合“开闭原则”
在添加新的产品对象时,难以扩展抽象工厂来生产新种类的产品,这是因为在抽象工厂角色中规定了所有可能被创建的产品集合,要支持新种类的产品就意味着要对该接口进行扩展,而这将涉及对抽象工厂角色及其所有子类的修改,显然会带来较大的不便。