这是我参与11月更文挑战的第19天,活动详情查看:2021最后一次更文挑战
前言
抽象工厂模式也是创建型设计模式之一,它和工厂模式很相似,抽象工厂是所有形态的工厂模式中最为抽象和最具一般性的一种形态,当有多个抽象角色时可以使用种工厂模式。
关联阅读:工厂模式
比如在我们上一期工厂模式中只有一个抽象产品Computer,如果说现在又有一个新的抽象产品耳机也要创建,耳机包括蓝牙耳机和有线耳机,那么就可以使用抽象工厂模式,对于客户端来说,只需要指定工厂类型,就可以创建具体的工厂了,无需指定产品的具体情况。
抽象工厂可以理解为是工厂的工厂,用于针对不同的产品分支创建出不同的工厂。
Talk is cheap,Show me the code.
抽象工厂模式的结构
同样需要有Computer
抽象类和子类PC
,Laptop
。
然后我们增加耳机的抽象类Headset
,然后有两个子类BluetoothHeadset
和有线耳机WiredHeadset
。
public abstract class HeadSet {
public abstract void play();
}
/**
* 蓝牙耳机
**/
public class BlueToothHeadSet extends HeadSet{
@Override
public void play() {
System.out.println("蓝牙耳机播放音乐");
}
}
/**
* 有线耳机
**/
public class WiredHeadset extends HeadSet{
@Override
public void play() {
System.out.println("有线耳机播放音乐");
}
}
复制代码
创建耳机工厂类:
/**
* @author 小黑说Java
* @ClassName HeadSetFactory
* @Description
* @date 2021/11/17
**/
public class HeadSetFactory implements AbstractFactory {
@Override
public Computer createComputer(String type, String ram, String hdd, String cpu) {
return null;
}
@Override
public HeadSet createHeadSet(String type) {
if ("Bluetooth".equals(type)) {
return new BlueToothHeadSet();
}
if ("Wired".equals(type)) {
return new WiredHeadset();
}
return null;
}
}
复制代码
然后需要有一个可以创建工厂的服务,在这个服务中可以按照工厂的类型创建出具体的工厂实例:
/**
* @author 小黑说Java
* @ClassName FactoryProducer
* @Description
* @date 2021/11/18
**/
public class FactoryProducer {
public static AbstractFactory getFactory(String factoryType) {
if ("Computer".equals(factoryType)) {
return new ComputerFactory();
}
if ("Headset".equals(factoryType)) {
return new HeadSetFactory();
}
return null;
}
}
复制代码
接下来通过一个简单的测试代码来模拟对抽象工厂的使用:
public class AbstactFactoryTest {
public static void main(String[] args) {
AbstractFactory computerFactory = FactoryProducer.getFactory("Computer");
AbstractFactory headsetFactory = FactoryProducer.getFactory("Headset");
// 通过computerFactory创建PC
Computer pc = computerFactory.createComputer("PC", "16GB", "500GB", "2.4GHz");
// 通过headsetFactory创建有线耳机
HeadSet wired = headsetFactory.createHeadSet("Wired");
Computer laptop = computerFactory.createComputer("Laptop", "16GB", "500GB", "2.4GHz");
HeadSet bluetooth = headsetFactory.createHeadSet("Bluetooth");
}
}
复制代码
抽象工厂的类图
抽象工厂模式的优势
抽象工厂模式主要有以下优势:
- 分离了具体的类。客户通过抽象接口操纵实例,产品的类名也在具体工厂的实现中被分离,它们不出现在客户代码中。
- 易于更换产品系列。一个具体工厂类只在初始化时出现一次,这使得改变一个应用的具体工厂变得很容易,只需改变具体的工厂即可使用不同的产品配置
- 有利于产品的一致性。当一个系列的产品对象被设计成一起工作时,一个应用一次只能使用同一个系列中的对象,这一点很重要,而抽象工厂很容易实现这一点
JDK中的抽象工厂模式
javax.xml.parsers.DocumentBuilderFactory.newInstance()
javax.xml.transform.TransformerFactory.newInstance()
javax.xml.xpath.XPathFactory.newInstance()
抽象工厂模式和工厂模式的区别
- 工厂模式针对的是多个产品结构;
- 抽象工厂模式针对的是多个产品族结构。
小结
抽象工厂模式的一个主要功能是它能够隔离要生成的具体产品类, 由于这些类的实际类名部被隐藏在工厂内部,因此客户端根本不需要关心如何对它们进行实例化的细节。每种设计模式都是针对特定问题的解决方案,而抽象工厂模式面临的问题则是当涉及到有多个产品等级结构时,如何更好地进行软件体系结构的设计。