抽象工厂模式
Abstract Factory Pattern:抽象工厂模式,是GoF23种设计模式中属于创建型模式的一种,用于创建一族的产品对象。
需要理解什么是产品族(也可以说是产品簇):产品族是满足不同客户个性化需求的一组相关产品,是能够满足不同客户对产品特殊特征和功能需求的相关系列产品集合构成。
简单的用个例子说一下,比如登录网页的模板,很简单,一个输入文本框,一个密码文本框,一个提交按钮。这里的这三个组件就是构成登录网页的一个产品族,可以通过创建不同的组件样式来构成不同的登录模板,但是客户所需要的是最后的呈现效果,到底这些产品族的每一个怎么制造是不需要管的,只看到的是最终的效果,用户轻轻一点,这些文本框和按钮就应该按照用户自己所选效果的产生出来,这也就是抽象工厂模式的作用了。
结构
结合类图分析一下,这个有点点复杂,但是也很好理解。一共有四个角色:
-
抽象工厂角色:解耦合,便于扩展。
需要注意的就是:抽象工厂里面包含着所有的产品创建的抽象的方法。
-
具体工厂角色:也就是实际应用中的实现了抽象工厂的类了。
-
抽象产品角色:解耦合,便于扩展。
需要注意的就是:抽象产品就是需要被创建的产品,因为产品族的关系,这些抽象的产品应该是多个,当然要是真的只有一个也是可以的,只是这就有点杀鸡焉有牛刀的感jio了。
-
具体产品角色:实现抽象产品接口,具体的产品的实现类。
举例
- 抽象工厂模式重要的突出点就是成套的,成系列的。比如我们的程序使用的数据哭由MySQL变成,SQL-Server,或者变成了Redis,MongDB等等,我们所希望的应该就是改变使用的数据库类型就可以了,而不是说还要去改每个数据库不同的操作语句,不同的连接方式等等,实在是过于麻烦,通过抽象工厂模式,就可以实现改一个换一整套产品族的功能。
- 游戏中的时装什么的一直是颜控游戏玩家的热爱,各种各样的时装让自己的角色变得是花枝招展。进行时装更换的时候,假设游戏厂商只准一套套的卖,那我们换也是一换换一套,而不是单件的换。这里的一套时装也是一个产品族的体现呢。
注意
- 抽象工厂模式的最主要的功能就是创建出不同的产品系列,注意是创建的是系列,产品系列。这样的操作可以使得用户永远使用的是同一个产品族中的对象,要换也是换掉整个产品族,而不是单单换一两个对象。
- 不好的位置就是新增产品族比较麻烦,因为新增一个产品系列不仅仅需要在抽象工厂里面修改代码,还需要在每个具体工厂里面都修改代码。
一个小DEMO
-
场景
早晨起来,拥抱太阳,咳咳,偏题了,偏题了。OK,回到正题
不同的时间,不同的场合我们是需要准备不同的衣物的,比如说去上班那就是一身帅气西装加皮鞋;出去玩,那就是一身休闲服饰搭配;宅在家,呵呵,大裤衩直接走起是不是。
-
首先定义一连串的抽象产品族
/** * 抽象工厂模式——抽象产品类 * 上衣 * @author wq */ public interface Jacket { void show(); } //-------------------------------------------------------------------- /** * 抽象工厂模式——抽象产品类 * 裤子 * @author wq */ public interface Trousers { void show(); } //-------------------------------------------------------------------- /** * 抽象工厂模式——抽象产品类 * 鞋子 * @author wq */ public interface Shoes { void show(); }
-
抽象工厂类也直接定义出来(这里使用了接口方法的默认实现,因为这里的输出是一定的,懒的多写了,直接写到接口里面偷偷懒,嘿嘿)
/** * 抽象工厂模式——抽象工厂类 * 就定义为套装吧 * @author wq */ public interface Suit { // 保存着所有创建产品的方法 Jacket createJacket(); Trousers createTrousers(); Shoes createShoes(); // 来个简单的方法用于打印 default void show(){ System.out.println("套装生成成功!!!"); } // 直接创建这个套装 default void generator() { createJacket(); createShoes(); createTrousers(); } }
-
定义具体的产品组成产品族
/** * 抽象工厂模式——具体产品类 * 西服上衣 * @author wq */ public class SuitCoat implements Jacket{ public SuitCoat() { System.out.println("西装上衣生成"); } @Override public void show() { System.out.println("西装上衣 "); } } //----------------------------------------------------------- /** * 抽象工厂模式——具体产品类 * 卫衣 * @author wq */ public class Sweater implements Jacket{ public Sweater() { System.out.println("卫衣生成"); } @Override public void show() { System.out.println("卫衣"); } } //----------------------------------------------------------- /** * 抽象工厂模式——具体产品类 * 西裤 * @author wq */ public class SuitTrousers implements Trousers{ public SuitTrousers() { System.out.println("西裤生成"); } @Override public void show() { System.out.println("西裤 "); } } //----------------------------------------------------------- /** * 抽象工厂模式——具体产品类 * 休闲裤 * @author wq */ public class CasualPants implements Trousers{ public CasualPants() { System.out.println("休闲裤生成"); } @Override public void show() { System.out.println("休闲裤 "); } } //----------------------------------------------------------- /** * 抽象工厂模式——具体产品类 * 皮鞋 * @author wq */ public class LeatherShoes implements Shoes{ public LeatherShoes() { System.out.println("皮鞋生成"); } @Override public void show() { System.out.println("皮鞋 "); } } //----------------------------------------------------------- /** * 抽象工厂模式——具体产品类 * 休闲鞋 * @author wq */ public class CasualShoes implements Shoes{ public CasualShoes() { System.out.println("休闲鞋生成"); } @Override public void show() { System.out.println("休闲鞋"); } }
-
具体的产品工厂类
/** * 抽象工厂模式——具体工厂类 * 正装套装 * @author wq */ public class FormalWear implements Suit{ public FormalWear() { System.out.println("正装套装生成开始"); } @Override public Jacket createJacket() { return new SuitCoat(); } @Override public Trousers createTrousers() { return new SuitTrousers(); } @Override public Shoes createShoes() { return new LeatherShoes(); } } //------------------------------------------------------ /** * 抽象工厂模式——具体工厂类 * 休闲套装 * @author wq */ public class LeisureSuit implements Suit{ public LeisureSuit() { System.out.println("休闲套装生成开始"); } @Override public Jacket createJacket() { return new Sweater(); } @Override public Trousers createTrousers() { return new CasualPants(); } @Override public Shoes createShoes() { return new CasualShoes(); } }
-
测试类
/** * 抽象工厂模式——测试类 * @author wq */ public class Main { public static void main(String[] args) { // 正装套装 Suit suit = new FormalWear(); suit.generator(); suit.show(); // 休闲套装 Suit suit2 = new LeisureSuit(); suit2.generator(); suit2.show(); } }
-
走一波
正装套装生成开始 西装上衣生成 皮鞋生成 西裤生成 套装生成成功!!! 休闲套装生成开始 卫衣生成 休闲鞋生成 休闲裤生成 套装生成成功!!!
完成