抽象工厂模式
概念
抽象工厂模式可以向客户端提供一个接口,使得客户端在不必指定产品具体类型的情况下,创建多个产品族中的产品对象。这就是抽象工厂模式的用意。
产品族 产品等级(类别)
每个模式都是针对一定问题的解决方案。抽象工厂模式面对的问题是多产品等级结构的系统设计。
在学习抽象工厂具体实例之前,应该明白两个重要的概念:产品族和产品等级。
产品族:是指位于不同产品等级结构中,功能相关联的产品组成的家族。比如AMD的CPU和ADM芯片的主板,组成一个家族。Intel的CPU和Intel芯片的主板,又组成一个家族。
而这两个家族都来自于两个产品等级:CPU,主板。一个等级结构是由相同的结构的产品组成,示意图如下:
理解这个产品结构是理解抽象工厂模式的关键所在,所以我不惜花费时间来画此图。如果领悟不到此图的含义,就无法区分工厂方法模式和抽象工厂模式的区别。
从上图可以看出,抽象工厂模式的每个工厂创造出来的都是一族产品,而不是一个或者一组。组是可以随意组合的!其实两个就这点点差别,呵呵,估计现在你已经差不多明白了抽象工厂模式的含义。不废话了,看个例子,真相将大白于天下!
例子
聪明的农场主总是让自己的庄园越来越有价值,“农场”在经历了简单工厂模式和工厂模式后,不断的扩大生产。如今,再次面临新的大发展,一项重要的工作就是引进塑料大棚技术,在大棚里种植热带(Tropical)和亚热带(Northern)的水果和蔬菜,用以满足市场需求,获取更大的利益。
系统设计图:
// 抽象工厂:Gardener.java public interface Gardener { public Fruit createFruit(String name); public Veggie createVeggie(String name); }
// 抽象水果产品:Fruit.java public interface Fruit { }
// 抽象蔬菜产品:Veggie.java public interface Veggie { }
// 热带水果:TropicalFruit.java public class TropicalFruit implements Fruit { private String name; public TropicalFruit(String name) { System.out.println("热带工厂为您创建了:热带水果-"+name); } public String getName() { return name; } public void setName(String name) { this.name = name; } }
// 热带蔬菜:TropicalVeggie.java public class TropicalVeggie implements Veggie { private String name; public TropicalVeggie(String name) { System.out.println("热带工厂为您创建了:热带水果-"+name); } public String getName() { return name; } public void setName(String name) { this.name = name; } }
// 亚热带水果:NorthernFruit.java public class NorthernFruit implements Fruit { private String name; public NorthernFruit(String name) { System.out.println("亚热带工厂为您创建了:亚热带水果-"+name); } public String getName() { return name; } public void setName(String name) { this.name = name; } }
// 亚热带蔬菜:NorthernVeggie.java public class NorthernVeggie implements Veggie { private String name; public NorthernVeggie(String name) { System.out.println("亚热带工厂为您创建了:亚热带蔬菜-"+name); } public String getName() { return name; } public void setName(String name) { this.name = name; } }
// 热带工厂:TropicalGardener.java public class TropicalGardener implements Gardener { public Fruit createFruit(String name) { return new TropicalFruit(name); } public Veggie createVeggie(String name) { return new TropicalVeggie(name); } }
// 亚热带工厂:NorthernGardener.java public class NorthernGardener implements Gardener { public Fruit createFruit(String name) { return new NorthernFruit(name); } public Veggie createVeggie(String name) { return new NorthernVeggie(name); } }
// 测试类(客户端):TestApp.java public class TestApp { private void test(){ Veggie tv,nv; Fruit tf,nf; TropicalGardener tg=new TropicalGardener(); NorthernGardener ng=new NorthernGardener(); tv=tg.createVeggie("热带菜叶"); nv=ng.createVeggie("东北甜菜"); tf=tg.createFruit("海南椰子"); nf=ng.createFruit("雪梨"); } public static void main(String args[]){ TestApp test=new TestApp(); test.test(); } }
// 测试运行结果 热带工厂为您创建了:热带水果-热带菜叶 亚热带工厂为您创建了:亚热带蔬菜-东北甜菜 热带工厂为您创建了:热带水果-海南椰子 亚热带工厂为您创建了:亚热带水果-雪梨
抽象工厂模式的优缺点
增加一个产品族很简单,符合开闭原则。但是增加一个产品类别很难(比如增加 树的类别,和蔬菜水果平级),违反了开闭原则。
三种工厂模式总结
三个工厂都是各有利弊。
简单工厂违反了最基本的原则;
工厂方法与抽象工厂完美的解决了简单工厂的弊端!但是,工厂方法的工厂个数过多,导致系统庞大;
抽象工厂增加新的产品族很方便!