抽象工厂模式(Abstract Factory) 提供一个创建一系列相关或相互依赖对象的接口, 而无须指定它们具体的类. 抽象工厂模式又称为Kit模式, 属于对象创建型模式.
设计模式-概述
乍一看抽象工厂模式与工厂方法模式是一样的, 它们的区别是: 工厂方法模式是对一类产品的创建的聚合, 例如: 按钮工厂, 内部包含了:圆按钮, 方按钮, 椭圆按钮等; 而抽象工厂模式是对一组的产品聚合, 例如:护眼主题工厂, 内部包含了: 绿色圆形按钮, 绿色输入框, 绿色背景等. 当一组产品有很强的关联性, 使用抽象工厂模式比工厂方法模式更方便, 结构更清晰.
结构 它包含了如下角色:
AbstractFactory 抽象工厂
ConcreteFactory 具体工厂
AbstractProduct 抽象产品
Product 具体产品
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 @startuml abstract-factory-1 !include ./common.cuml Class(AbstractFactory,"抽象工厂") << abstract >> { + createAbstractProduct1() : AbstractProduct1 + createAbstractProduct2() : AbstractProduct2 + createAbstractProductN() : AbstractProductN } Class(AbstractProduct1,"抽象产品1") << abstract >> { + use1() : void } Class(AbstractProduct2,"抽象产品2") << abstract >> { + use2() : void } Class(AbstractProductN,"抽象产品N") << abstract >> { + useN() : void } Class(ConcreteProduct1_1,"具体产品1-1") { + use1() : void } Class(ConcreteProduct1_2,"具体产品1-2") { + use1() : void } Class(ConcreteProduct2_1,"具体产品2-1") { + use2() : void } Class(ConcreteProduct2_2,"具体产品2-2") { + use2() : void } Class(ConcreteProductN_1,"具体产品N-1") { + useN() : void } Class(ConcreteProductN_2,"具体产品N-2") { + useN() : void } Class(ConcreteFactory1,"具体工厂1") { + createAbstractProduct1() : AbstractProduct1 + createAbstractProduct2() : AbstractProduct2 + createAbstractProductN() : AbstractProductN } Class(ConcreteFactory2,"具体工厂1") { + createAbstractProduct1() : AbstractProduct1 + createAbstractProduct2() : AbstractProduct2 + createAbstractProductN() : AbstractProductN } AbstractFactory <|..left.. ConcreteFactory1 AbstractFactory <|..right.. ConcreteFactory2 ConcreteFactory1 .down.> ConcreteProduct1_1 ConcreteFactory1 .down.> ConcreteProduct2_1 ConcreteFactory1 .down.> ConcreteProductN_1 ConcreteFactory2 .down.> ConcreteProduct1_2 ConcreteFactory2 .down.> ConcreteProduct2_2 ConcreteFactory2 .down.> ConcreteProductN_2 AbstractProduct1 <|.up.. ConcreteProduct1_1 AbstractProduct1 <|.up.. ConcreteProduct1_2 AbstractProduct2 <|.up.. ConcreteProduct2_1 AbstractProduct2 <|.up.. ConcreteProduct2_2 AbstractProductN <|.up.. ConcreteProductN_1 AbstractProductN <|.up.. ConcreteProductN_2 @enduml
使用时序
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 @startuml abstract-factory-2 actor 用户 as U entity 客户端 as C participant 工厂A as A U -> C : 切换主题A activate C C -> A : createAButton(给我一个A主题按钮) activate C #BBBBBB create A主题按钮 as AB A -->> AB : 创建 C <-- A : 给你一个A主题按钮 C -> AB : 渲染A主题按钮(use) deactivate C C -> A : createAInput(给我一个A主题输入框) activate C #Blue create A主题输入框 as AI A -->> AI : 创建 C <-- A : 给你一个A主题输入框 C -> AI : 渲染A主题输入框(use) deactivate C C -> A : createATable(给我一个A主题表格) activate C #DarkSalmon create A主题表格 as AT A -->> AT : 创建 C <-- A : 给你一个A主题表格 C -> AT : 渲染A主题表格(use) deactivate C C --> U : 展示给用户看A主题 ==用户觉得A主题不好看== participant 工厂B as B C <- U : 切换主题B activate C C -> B : createBButton(给我一个B主题按钮) activate C #BBBBBB create B主题按钮 as BB B -->> BB : 创建 C <-- B : 给你一个B主题按钮 C -> BB : 渲染B主题按钮(use) deactivate C C -> B : createBInput(给我一个B主题输入框) activate C #Blue create B主题输入框 as BI B -->> BI : 创建 C <-- B : 给你一个B主题输入框 C -> BI : 渲染B主题输入框(use) deactivate C C -> B : createBTable(给我一个B主题表格) activate C #DarkSalmon create B主题表格 as BT B -->> BT : 创建 C <-- B : 给你一个B主题表格 C -> BT : 渲染B主题表格(use) deactivate C C --> U : 展示给用户看B主题 @enduml
代码实例 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 public class Main { public static void main (String[] args) { AbstractFactory factory = new ConcreteFactory1 (); AbstractProduct1 product1 = factory.createProduct1(); AbstractProduct2 product2 = factory.createProduct2(); product1.use1(); product2.use2(); } } abstract class AbstractFactory { abstract AbstractProduct1 createProduct1 () ; abstract AbstractProduct2 createProduct2 () ; } abstract class AbstractProduct1 { abstract void use1 () ; } abstract class AbstractProduct2 { abstract void use2 () ; } class ConcreteProduct1 extends AbstractProduct1 { @Override void use1 () { System.out.println("使用产品1" ); } } class ConcreteProduct2 extends AbstractProduct2 { @Override void use2 () { System.out.println("使用产品2" ); } } class ConcreteFactory1 extends AbstractFactory { @Override AbstractProduct1 createProduct1 () { return new ConcreteProduct1 (); } @Override AbstractProduct2 createProduct2 () { return new ConcreteProduct2 (); } }
使用场景
系统不关心产品是如何创建的, 仅仅要一个产品就好了, 这个对所有的工厂模式都适用.
如果各种不同种类的产品, 但是他们同属于某个分类时, 并且大多数情况下会同时使用时.
具体应用 客户端切换界面主题, 各个控件对象的构造过程都收敛到同一个工厂类中, 使用者并不关心各种控件如何构造, 并且有多个主题使用(如果仅有一个主题, 那么使用简单工厂模式就行了).