抽象工厂模式为一个产品家族提供了统一的建立接口。当须要这个产品家族的某一系列的时候,能够从抽象工厂中选出相对应的系列来建立一个具体的工厂类别。这种类型的设计模式属于建立型模式,它提供了一种建立对象的最佳方式。设计模式
在抽象工厂模式中,接口是负责建立一个相关对象的工厂,不须要显式指定它们的类。每一个生成的工厂都能按照工厂模式提供对象。iphone
相关术语:ide
产品等级结构:产品的继承结构,与类的继承类似。例如笔记本是一个抽象的类,那么华为笔记本、苹果和联想笔记本就是其子类。测试
产品族:指同一个工厂生产的,位于不一样的产品等级结构的一组产品。例如华为笔记本、手机、路由器等都产自华为,笔记本的等级结构不一样,构成一个产品族。字体
抽象工厂:是一个接口,抽象工厂模式的核心,包含对多个产品等级结构的声明,任何工厂类都必须实现这个接口。spa
咱们以一个品牌为一个产品族,电脑、手机、路由器为产品等级,每个品牌都有本身的产品族,这就构成一个完整产品群;设计
横向表明一族,纵向表明一个等级,横纵交集表明某一个品牌的某一个产品(好比下图中交集的点为电脑),请看下图;code
这个类图其实比较简单,简单说明下:router
产品顶级接口:主要被产品抽象类实现;对象
产品抽象类:某个具体产品要实现的类;
具体实现类:具体产品实现,好比华为路由器实现自抽象类AbstractRouter;
工厂接口:工厂接口中定义建立每一个产品方法;
具体华为工厂:实现工厂接口,建立华为一族产品(路由器、手机、电脑);
代码中咱们以华为产品为例,分别定义华为电脑、手机、路由器产品,从UML类图中能够看出咱们的产品结构层级比较清晰,如今咱们先设计咱们产品。
下面开始定义产品;
产品顶级接口;
package pattern.abstractfactory.product; /** * 定义产品接口 * @author ningbeibei */ public interface InterfaceProduct { void get(); }
定义计算机抽象类并实现产品InterfaceProduct 接口;
package pattern.abstractfactory.product; /** * 定义计算机产品抽象类,并实现产品接口InterfaceProduct * @author ningbeibei */ public abstract class AbstractComputers implements InterfaceProduct { public abstract void get(); }
定义手机抽象类并实现产品InterfaceProduct 接口;
package pattern.abstractfactory.product; /** * 定义手机抽象类,并实现产品接口InterfaceProduct * @author ningbeibei */ public abstract class AbstractPhone implements InterfaceProduct { public abstract void get(); }
定义路由器抽象类并实现产品InterfaceProduct 接口;
package pattern.abstractfactory.product; /** * 定义路由器产品抽象类,并实现InterfaceProduct接口 * @author ningbeibei */ public abstract class AbstractRouter implements InterfaceProduct{ public abstract void get(); }
定义华为电脑具体实现类,继承AbstractComputers抽象类;
package pattern.abstractfactory.product; /** * 华为电脑实现类 * @author ningbeibei */ public class HuaWeiComputer extends AbstractComputers{ @Override public void get() { System.out.println("华为笔记本"); } }
定义华为手机具体实现类,继承AbstractPhone抽象类;
package pattern.abstractfactory.product; /** * 华为手机实现类, * @author ningbeibei */ public class HuaWeiPhone extends AbstractPhone{ @Override public void get() { System.out.println("华为手机"); } }
定义华为路由器具体实现类,继承AbstractRouter抽象类;
package pattern.abstractfactory.product; /** * 华为路由器 * @author ningbeibei */ public class HuaWeiRouter extends AbstractRouter { @Override public void get() { System.out.println("华为品牌路由器"); } }
下面开始定义工厂;
定义工厂接口;
package pattern.abstractfactory.factory; import pattern.abstractfactory.product.InterfaceProduct; /** * 定义产品工厂接口, * @author ningbeibei */ public interface InterfactFactory { //手机产品 InterfaceProduct createPhone(); //电脑产品 InterfaceProduct createComputer(); //路由器产品 InterfaceProduct createRouter(); }
具体工厂实现类,实现 InterfactFactory 接口;
package pattern.abstractfactory.factory; import pattern.abstractfactory.product.HuaWeiComputer; import pattern.abstractfactory.product.HuaWeiPhone; import pattern.abstractfactory.product.HuaWeiRouter; import pattern.abstractfactory.product.InterfaceProduct; /** * 华为工厂 * @author ningbeibei */ public class HuaWeiFactory implements InterfactFactory { /** * 建立电脑对象并返回 */ @Override public InterfaceProduct createComputer() { return new HuaWeiComputer(); } /** * 建立手机对象并返回 */ @Override public InterfaceProduct createPhone() { return new HuaWeiPhone(); } /** * 建立路由器对象并返回 */ @Override public InterfaceProduct createRouter() { return new HuaWeiRouter(); } }
测试类;
package pattern.abstractfactory; import pattern.abstractfactory.factory.HuaWeiFactory; import pattern.abstractfactory.factory.InterfactFactory; import pattern.abstractfactory.product.InterfaceProduct; /** * 抽象工厂模式测试类 * @author ningbeibei */ public class test { public static void main(String[] args) { //建立华为品牌工厂 InterfactFactory huawei = new HuaWeiFactory(); //经过华为工厂获取华为电脑对象 InterfaceProduct computer = huawei.createComputer(); computer.get(); //经过华为工厂获取华为手机对象 InterfaceProduct phone = huawei.createPhone(); phone.get(); //经过华为工厂获取华为路由器对象 InterfaceProduct router = huawei.createRouter(); router.get(); } }
运行结果;
抽象工厂模式对于横向扩展方便,对于纵向扩展很是困难,也就是说:假如咱们要扩展一个新的品牌,好比扩展一个小米品牌,小米产品有电脑、手机、路由器,扩展新品牌就是横向扩展,很是方便,可是咱们要给小米添加一个电饭煲产品却很是困难,这就是纵向扩展,因此在使用抽象工厂模式时必定要选择合适的场景,也就是在不一样场景中使用最适合的模式才是设计模式的精髓。
下面咱们就来横向扩展一个新品牌的产品族,须要添加电脑、手机、路由器具体类(小米品牌)代码以下;
小米电脑
package pattern.abstractfactory.product; /** * 小米电脑,继承自 AbstractComputers 抽象类 * @author ningbeibei */ public class MiComputer extends AbstractComputers { @Override public void get() { System.out.println("小米电脑"); } }
小米手机
package pattern.abstractfactory.product; /** * 小米手机,继承自 AbstractPhone 抽象类 * @author ningbeibei */ public class MiPhone extends AbstractPhone { @Override public void get() { System.out.println("小米手机"); } }
小米路由器
package pattern.abstractfactory.product; /** * 小米路由器,继承自 AbstractRouter 抽象类 * @author ningbeibei */ public class MiRouter extends AbstractRouter{ @Override public void get() { System.out.println("小米路由器"); } }
添加小米具体工厂类
package pattern.abstractfactory.factory; import pattern.abstractfactory.product.InterfaceProduct; import pattern.abstractfactory.product.MiComputer; import pattern.abstractfactory.product.MiPhone; import pattern.abstractfactory.product.MiRouter; /** * 小米工厂,实现 InterfactFactory 接口 * @author ningbeibei */ public class MiFactory implements InterfactFactory{ //小米手机 @Override public InterfaceProduct createPhone() { return new MiPhone(); } //小米电脑 @Override public InterfaceProduct createComputer() { return new MiComputer(); } //小米路由器 @Override public InterfaceProduct createRouter() { return new MiRouter(); } }
最后编写测试类,代码中红色字体为新扩展的品牌产品;
package pattern.abstractfactory; import pattern.abstractfactory.factory.HuaWeiFactory; import pattern.abstractfactory.factory.InterfactFactory; import pattern.abstractfactory.factory.MiFactory; import pattern.abstractfactory.product.InterfaceProduct; /** * 抽象工厂模式测试类 * @author ningbeibei */ public class test { public static void main(String[] args) { // 建立华为品牌工厂 InterfactFactory huawei = new HuaWeiFactory(); // 经过华为工厂获取华为电脑对象 InterfaceProduct computer = huawei.createComputer(); computer.get(); // 经过华为工厂获取华为手机对象 InterfaceProduct phone = huawei.createPhone(); phone.get(); // 经过华为工厂获取华为路由器对象 InterfaceProduct router = huawei.createRouter(); router.get(); // 建立小米品牌工厂 InterfactFactory Mifactory = new MiFactory(); // 经过小米工厂获取小米电脑对象 InterfaceProduct micomputer = Mifactory.createComputer(); micomputer.get(); // 经过小米工厂获取小米手机对象 InterfaceProduct miphone = Mifactory.createPhone(); miphone.get(); // 经过小米工厂获取小米路由器对象 InterfaceProduct mirouter = Mifactory.createRouter(); mirouter.get(); } }
运行结果:
注意:经过上面的品牌扩展咱们发现,横向扩展容易,纵向扩展很是困难,代码能够很是方便的扩展一个品牌已有的产品,但要扩展一个未定义的产品却异常困难,好比要扩展一个华为平板,须要修改工厂逻辑代码,新增产品结构,这显然不符合设计模式开闭原则,因此在使用时必定要考虑清楚,肯定不在有新的产品等级扩展。
优势
抽象工厂模式隔离了具体类的生成, 使得客户并不须要知道什么被建立。 因为这种隔离,更换一个具体工厂就变得相对容易, 全部的具体工厂都实现了抽象工厂中定义的那些公共接口, 所以只需改变具体工厂的实例, 就能够在某种程度上改变整个软件系统的行为。
当一个族中的多个对象被设计成一块儿工做时, 它可以保证客户端始终只使用同一个族中的对象。
增长新的族很方便, 无须修改已有系统, 符合“开闭原则”。
缺点
使用场景
一个系统不该当依赖于具体类实例如何被建立、 组合和表达的细节, 这对于全部类型的工厂模式都是很重要的, 用户无须关心对象的建立过程, 将对象的建立和使用解耦。
系统中有多于一个的族, 而每次只使用其中某一族。 能够经过配置文件等方式来使得用户能够动态改变族, 也能够很方便地增长新的族。
等级结构稳定, 设计完成以后, 不会向系统中增长新的等级结构或者删除已有的等级结构。
写的不足之处请在评论区指出,便于我及时更正错误,避免给读者带来误解,但愿你们多多提意见。