1. 定义: 一个用于创建对象的接口, 让子类决定实例化哪个类。 工厂方法使一个类的实例化延迟到子类。
2. 结构
3. 参与者(如上图)
Product ---- 定义工厂方法所创建的对象接口
ConcreteProduct ---- 实现Product接口
Creator ---- 声明工厂方法, 该方法返回一个Product类型的对象
ConcreteCreator ---- 重新定义工厂方法返回一个ConcreteProduct实例
4. 实现
(1) 特例: 简单工厂(Simple Factory)又叫做静态工厂方法(Static Factory Method)
结构:
代码:
接口 Tree
package com.wenniuwuren.simplefactory; /** * * @author wenniuwuren * 生产者抽象类 */ public interface Tree { public String product(); }
真实Product: AppleTree
package com.wenniuwuren.simplefactory; public class AppleTree implements Tree { @Override public String product() { return "Apple"; } }
真实Product: LemonTree
package com.wenniuwuren.simplefactory; public class LemonTree implements Tree { @Override public String product() { return "Lemon"; } }
核心类: 对象生成工厂Creator
package com.wenniuwuren.simplefactory; /** * * @author wenniuwuren * * 工厂(Creator)角色 :简单工厂模式的核心,它负责实现创建所有实例的内部逻辑。 * 工厂类可以被外界直接调用,创建所需的产品对象。 * */ public class SomethingCreator { // 静态工厂 这就是为什么简单工厂又叫静态工厂方法 public static Tree factory(String fruitType) throws Exception{ if(fruitType.equals("Lemon")){ return new LemonTree(); }else if(fruitType.equals("Apple")){ return new AppleTree(); }else{ throw new Exception("暂时不支持生产该类型产品"); } } }
测试类:
package com.wenniuwuren.simplefactory; /** * * @author wenniuwuren * 测试类 */ public class Test { public static void main(String[] args) throws Exception { String fruitType = "Lemon"; Tree tree = SomethingCreator.factory(fruitType); System.out.println(fruitType + "Tree Product : " + tree.product()); fruitType = "Apple"; tree = SomethingCreator.factory(fruitType); System.out.println(fruitType + "Tree Product : " + tree.product()); fruitType = "Pear"; tree = SomethingCreator.factory(fruitType); System.out.println(fruitType + "Tree Product : " + tree.product()); } }
运行结果:
LemonTree Product : Lemon
AppleTree Product : Apple
Exception in thread "main" java.lang.Exception: 暂时不支持生产该类型产品
at com.wenniuwuren.simplefactory.SomethingCreator.factory(SomethingCreator.java:22)
at com.wenniuwuren.simplefactory.Test.main(Test.java:15)
(2) 一般情况就是本文开头提到的工厂模式(Factory Method)
可以想象, 如果水果种类很多的话, 上面的简单工厂SomethingCreator类会爆炸, 所以更一般的方法是工厂的具体实现也交给子类。
代码:
将上述SomethingCreator改为接口(面向接口编程是一种良好的OO习惯)
package com.wenniuwuren.factorymethod; public interface SomethingCreator { public Tree factory(String fruitType) throws Exception; }
工厂具体实现类:LemonCreator
package com.wenniuwuren.factorymethod; public class LemonCreator implements SomethingCreator { @Override public Tree factory(String fruitType) throws Exception { if (fruitType.equals("Lemon")) return new LemonTree(); else throw new Exception("生产Lemon错误"); } }
工厂具体实现类:AppleCreator
package com.wenniuwuren.factorymethod; public class AppleCreator implements SomethingCreator { @Override public Tree factory(String fruitType) throws Exception { if (fruitType.equals("Apple")) return new AppleTree(); else throw new Exception("生产Apple错误"); } }
Creator(本例中的:Tree、 AppleTree、 LemonTree)部分不用变化, 从上面的类图结构对比就能明显看出, 变化的只是Creator工厂部分。
测试类:
package com.wenniuwuren.factorymethod; /** * * @author wenniuwuren * 测试类 */ public class Test { public static void main(String[] args) throws Exception { String fruitType = "Lemon"; SomethingCreator somethingCreator = new LemonCreator(); Tree tree = somethingCreator.factory(fruitType); System.out.println(fruitType + "Tree Product : " + tree.product()); fruitType = "Apple"; somethingCreator = new AppleCreator(); tree = somethingCreator.factory(fruitType); System.out.println(fruitType + "Tree Product : " + tree.product()); } }
测试结果:
LemonTree Product : Lemon
AppleTree Product : Apple
5. 区别
-- 简单工厂
简单工厂方法中,包括一个“抽象产品类”(该类可以是接口Interface,也可以是实际的类Class),所有需要的产品类都是该“抽象产品类”的子类(如果是接口的话,那么就是说所有产品类都继承了该接口)。
简单工厂一般只包含一个具体的工厂类,由该工厂类生成所有的产品类的对象。
-- 工厂方法
抽象工厂中,包括“抽象工厂类”和“抽象产品类”,同时包含不只一个工厂类。所有的工厂类都必须是“抽象工厂类”的子类,所有的产品都必须是“抽象产品类”的子类。
-- 抽象工厂
抽象工厂和工厂方法很类似,区别如下:
工厂方法模式:
一个抽象产品类,可以派生出多个具体产品类。
一个抽象工厂类,可以派生出多个具体工厂类。
每个具体工厂类只能创建一个具体产品类的实例。
抽象工厂模式:
多个抽象产品类,每个抽象产品类可以派生出多个具体产品类。
一个抽象工厂类,可以派生出多个具体工厂类。
每个具体工厂类可以创建多个具体产品类的实例。
区别:
工厂方法模式只有一个抽象产品类,而抽象工厂模式有多个。
工厂方法模式的具体工厂类只能创建一个具体产品类的实例,而抽象工厂模式可以创建多个
参考书籍:
《设计模式 : 可复用面向对象软件的基础》
《Effective Java》
《Head First 设计模式》