1、工厂模式的形式
工厂模式专门负责将大量有共同接口的类实例化。工厂模式可以动态的决定将哪一个类实例化,工厂模式有以下几种形态:
简单工厂(Simple Factory)模式:又称静态工厂方法(Static Factory Methord)模式。
工厂方法(Factory Method)模式:又称多态性工厂(Polymorphic Factory)模式或虚拟构造子(Virtual Constructor)模式。
抽象工厂(Abstract Factory)模式:又称工具箱(Kit或Toolkit)模式。
2、简单工厂模式优缺点
(1)简单工厂模式的优点
核心式工厂类,工厂类决定在什么情况下创建哪一种产品类的实例。而客户端则可以免除直接创建产品对象的责任,而仅仅是“消费”产品。简单工厂模式通过这种做法实现了对责任的分割。
(2)简单工厂模式的缺点
当产品类具有复杂的多层次等级结构时,工厂类只有它自己。以不变应万变,是其缺点。
这个工厂类集中了所有产品创建逻辑,形成了一个无所不知的全能类(也称上帝类),如果此类出问题了,整个应用都受大影响。
当产品有多个接口时,判断在什么条件下创建什么产品类实例会很困难。
对于工厂来说,增加新的产品时一个痛苦的过程。工厂角色必须知道每一种产品,如何创建它们,以及何时向客户提供它们。换言之,接纳新的产品意味着修改这个工厂角色的源代码。简单工厂只在有限的程度上支持“开-闭”原则。
由于简单工厂模式使用静态方法作为工厂方法,而静态方法无法由子类继承,因此工厂角色无法形成基于继承的等级结构。这一缺点会在工厂方法模式中得到克服。
3、工厂方法模式
(1)概念理解
工厂方法模式是简单工厂模式的进一步抽象和推广。由于使用了多态性,工厂方法模式保持了简单工厂模式的优点,而且克服了它的缺点。
在工厂方法模式中,核心的工厂类不再负责所有产品的创建,而是将具体创建的工作交给子类去做。这个核心工厂则变为抽象工厂角色,仅负责给出具工厂子类必须实现的接口,而不接触哪一产品创建的细节。
(2)例子
水果产品接口Fruit.java
public interface Fruit { /** * 种植 */ void plant(); /** * 生长 */ void grow(); /** * 收获 */ void harvest(); }
具体产品苹果Apple.java
public class Apple implements Fruit { private int treeAge; @Override public void grow() { System.out.println("Apple is growing..."); } @Override public void harvest() { System.out.println("Apple has been harvested."); } @Override public void plant() { System.out.println("Apple has been planted."); } /** * @return 返回树龄 */ public int getTreeAge() { return treeAge; } /** * 设置树龄 */ public void setTreeAge(int treeAge) { this.treeAge = treeAge; } }
具体产品葡萄:Grape.java
略...
具体产品草莓:Strawberry.java
略...
水果工厂接口:FruitGardener.java
public interface FruitGardener { /** * 工厂方法 * * @return 水果 */ public Fruit factory(); }
苹果工厂:AppleGardener.java
public class AppleGardener implements FruitGardener { @Override public Fruit factory() { Fruit f = new Apple(); System.out.println("水果工厂(AppletGardener)成功创建一个水果:苹果!"); return f; } }
葡萄工厂:GrapeGardener.java
略...
草莓工厂:StrawberryGardener.java
略...
测试类(客户端):TestApp.java
public class TestApp { private FruitGardener f1, f2, f3; private Fruit p1, p2, p3; private void test() { // 实力化水果工厂 f1 = new AppleGardener(); f2 = new GrapeGardener(); f3 = new StrawberryGardener(); // 从水果工厂生产水果 p1 = f1.factory(); p2 = f2.factory(); p3 = f3.factory(); } public static void main(String args[]) { TestApp test = new TestApp(); test.test(); }
运行结果:
水果工厂(AppletGardener)成功创建一个水果:苹果!
水果工厂(GrapeGardener)成功创建一个水果:葡萄!
水果工厂(StrawberryGardener)成功创建一个水果:草莓!
Process finished with exit code 0
(3) 存在的缺点
有一个农业镇,这里有好几家农场。但每家农场生产的产品各不相同。
游客来到这里,想要买几种不同的水果回去,他必须要到几个农场去(因为:一家农场只卖一种水果)。
4、抽象工厂模式
(1)概念理解
抽象工厂模式可以向客户端提供一个接口,使得客户端在不必指定产品具体类型的情况下,创建多个产品族中的产品对象。这就是抽象工厂模式的用意。
每个模式都是针对一定问题的解决方案。抽象工厂模式面对的问题是多产品等级结构的系统设计。
在学习抽象工厂具体实例之前,应该明白两个重要的概念:产品族和产品等级。
产品族:是指位于不同产品等级结构中,功能相关联的产品组成的家族。比如AMD的CPU和ADM芯片的主板,组成一个家族。Intel的CPU和 Intel芯片的主板,又组成一个家族。而这两个家族都来自于两个产品等级:CPU,主板。
(2)例子
抽象工厂: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 { @Override public Fruit createFruit(String name) { return new TropicalFruit(name); } @Override public Veggie createVeggie(String name) { return new TropicalVeggie(name); } }
亚热带工厂:NorthernGardener.java
public class NorthernGardener implements Gardener { @Override public Fruit createFruit(String name) { return new NorthernFruit(name); } @Override public Veggie createVeggie(String name) { return new NorthernVeggie(name); } }
测试类
public class TestApp { private FruitGardener f1, f2, f3; private Fruit p1, p2, p3; private void test() { Veggie tv,nv; Fruit tf,nf; Gardener tg=new TropicalGardener(); Gardener 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(); } }
结果:
热带工厂为您创建了:热带水果-热带菜叶
亚热带工厂为您创建了:亚热带蔬菜-东北甜菜
热带工厂为您创建了:热带水果-海南椰子
亚热带工厂为您创建了:亚热带水果-雪梨