抽象工厂模式是常见的建造型设计模式之一,比工厂方法模式抽象程度更高。工厂方法模式中具体工厂只生产一种具体产品,但在抽象工厂模式中,具体工厂能够生产相关的一组具体产品,这样一组产品称为产品族,产品族中的每个产品分属于某一产品继承等级结构。java
有时候咱们须要一个工厂提供多个产品对象,而不是单一一个产品对象,如一个电器设备工厂,它能够生产电视机、电冰箱、空调等设备,而不仅是生成某种类型的电器。为了更清晰地理解抽象工厂模式,这里先引入两个概念:设计模式
产品等级结构:产品等级结构即产品的继承结构,如一个抽象类是电视机,其子类有海尔电视机、TCL电视机等,抽象电视机与具体品牌电视机之间构成了一个产品等级结构。ide
产品族:指由同一工厂生产的,位于不一样产品等级结构中的一组产品,如海尔电器工厂生产海尔电视机、海尔电冰箱,则它们是同一产品族,各自位于不一样产品等级结构。工具
[外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-KyRte5v6-1583586756775)(C:\Users\LENOVO\AppData\Roaming\Typora\typora-user-images\image-20200307152957643.png)]测试
当系统提供的工厂生产的具体产品不是一个简单对象,而是多个位于不一样产品等级结构中属于不一样类型的具体产品时须要使用抽象工厂模式。ui
提供一个建立一系列相关或相互依赖对象的接口,而无须指定它们具体的类。设计
AbstractFacory(抽象工厂)3d
抽象工厂用于声明生产抽象产品的方法,在一个抽象工厂中能够定义一组方法,每一方法对应一个产品等级结构code
ConcreteFactory(具体工厂)xml
具体工厂实现抽象工厂声明的生产抽象产品的方法,生产一组具体产品,这些产品构成一个产品族,每个产品都位于某个产品等级结构中。
AbstractProduct(抽象产品)
抽象产品为每种产品声明接口,在抽象产品中定义产品的抽象业务方法
ConcreteProduct(具体产品)
具体产品定义具体工厂生产的具体产品对象,实现抽象产品接口中定义的业务方法。
一个电器工厂能够产生多种类型的电器,如海尔工厂能够生产海尔电视机、海尔空调等,TCL工厂能够生产TCL电视机、TCL空调等,相同品牌的电器构成一个产品族,而相同类型电器构成一个产品等级结构。
抽象产品类Television
public interface Television { void play(); }
具体产品类HairTelevision(海尔电视机类)
public class HairTelevision implements Television { @Override public void play() { System.out.println("海尔电视机播放中......"); } }
具体产品类TCLTelevision(TCL电视机类)
public class TCLTelevision implements Television { @Override public void play() { System.out.println("TCL电视机播放中......."); } }
抽象产品类AirConditioner
public interface AirConditioner { void changeTemperature(); }
具体产品类HairAirConditioner(海尔空调类)
public class HairAirConditioner implements AirConditioner { @Override public void changeTemperature() { System.out.println("海尔空调温度改变中....."); } }
具体产品类TCLAirConditioner(TCL空调类)
public class TCLAirConditioner implements AirConditioner { @Override public void changeTemperature() { System.out.println("TCL空调温度改变中......"); } }
抽象工厂类EFactory
public interface EFactory { Television produceTelevision(); AirConditioner produceAirConditioner(); }
具体工厂类HairFactory(海尔工厂类)
public class HairFactory implements EFactory { @Override public Television produceTelevision() { return new HairTelevision(); } @Override public AirConditioner produceAirConditioner() { return new HairAirConditioner(); } }
具体工厂类TCLPFactory
public class TCLFactory implements EFactory { @Override public Television produceTelevision() { return new TCLTelevision(); } @Override public AirConditioner produceAirConditioner() { return new TCLAirConditioner(); } }
XML操做工具类
public class XMLUtil { public static Object getBean() throws Exception { //建立解析器工厂 DocumentBuilderFactory builderFactory = DocumentBuilderFactory.newInstance(); //建立解析器 DocumentBuilder builder = builderFactory.newDocumentBuilder(); //获得document Document document = builder.parse("configPhone.xml"); //获取包含品牌名称的文本节点 NodeList brandNameList = document.getElementsByTagName("factoryName"); Node classNode = brandNameList.item(0).getFirstChild(); String factoryName = classNode.getNodeValue().trim(); // System.out.println(factoryName); Class c = Class.forName("com.abstractFactory." + factoryName); Object o = c.newInstance(); return o; } }
配置文件
<?xml version="1.0" encoding="UTF-8" ?> <configuration> <factoryName>HairFactory</factoryName> </configuration>
测试类
public class Test { public static void main(String[] args) throws Exception { EFactory factory = (EFactory) XMLUtil.getBean(); Television television = factory.produceTelevision(); television.play(); AirConditioner airConditioner = factory.produceAirConditioner(); airConditioner.changeTemperature(); } }
结果分析
若是在配置文件将节点中内容设置为 HairFactory,则输出结果以下:
若是在配置文件将节点中内容设置为 TCLFactory,则输出结果以下:
若是须要增长新品牌的电器,即增长一个新的产品族,如增长海信电视机和海信空调,则只需对应增长一个具体工厂,再将配置文件中具体工厂类名修改成新增工厂类名,原有代码无须修改。但若是要增长新的产品,如增长新的电器产品洗衣机,抽象工厂须要声明一个生产洗衣机的方法,全部具体工厂类都需实现该方法,将致使系统再也不符合开闭原则。