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";
}
}
package com.wenniuwuren.simplefactory;
public class LemonTree implements Tree {
@Override
public String product() {
return "Lemon";
}
}
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错误");
}
}
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错误");
}
}
测试类:
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 设计模式》