一、简单工厂(Simple Factory)
简单工厂又叫作静态工厂,它主要有一个静态方法,用来接受参数,并根据参数来决定返回实现同一接口的不同类的实例。
下面来看一个简单的例子:
假设有一家公司,可以生产鼠标,键盘,显示器等等。
(1)我们先可以定义一个共同的产品接口:
public interface Product{}
(2)紧接着让所有产品实现这个接口:
public class Mouse implements Product{
public Mouse (){
System.out.println("A mouse is created.");
}
}
public class Keyboard implements Product{
public Keyboard (){
System.out.println("A keyboard is created.");
}
}
public class Screen implements Product{
public Screen (){
System.out.println("A screen is created.");
}
}
(3)然后我们写一个工厂类(它是简单工厂设计模式的重点),由它来负责生产以上的三种产品:
public class SimpleFactory {
public static Product factory(String productName) throws Exception{
if(productName.equals("Mouse ")){
return new Mouse ();
}else if(productName.equals("Keyboard ")){
return new Keyboard ();
}else if(productName.equals("Screen ")){
return new Screen ();
}else{
throw new Exception("Sorry: don't exist this product!");
}
}
}
(4)现在有了上面这个工厂类,我们就可以开始生产了,而且简单工厂类可以根据不同的参数决定生产什么产品:
public static void main(String[] args) {
try {
SimpleFactory.factory("Mouse");
SimpleFactory.factory("Keyboard");
SimpleFactory.factory("Screen");
} catch (Exception e) {
e.printStackTrace();
}
}
简单工厂设计模式虽然看起开使用很方便,也浅显易懂。总结来讲,简单工厂最大的优点在于工厂类中包含了必要的逻辑判断,根据客户端的选择条件动态实例化相关的类,对于客户端来说,去除了与具体产品的依赖。
但是简单工厂设计模式存在如下缺点:
1,我们每次想要增加一种新产品的时候,都必须修改SimpleFactory的原代码。比如上述例子中,假如该公司又可以生产CPU了,我们只能在SimpleFactory的源代码中加判断和生产CPU的代码。这样一来,我们不但对扩展开放了,对修改也开放了,这严重违背了“开放-封闭原则”。
2,当我们拥有很多很多产品的时候,而且产品之间又存在复杂的层次关系的时候,这个类必须拥有复杂的逻辑判断能力,其代码量也将不断地激增,这非常不利于以后的维护。
3,我们不难发现,整个系统都严重依赖SimpleFactory类,只要SimpleFactory类一出问题,系统就进入不能工作的状态。
以上缺点都促成了下面两种工厂设计模式的产生。
二、工厂方法(Factory Method)
上面的例子告诉我们,SimpleFactory类是整个模式的核心,一旦它出了问题,整个模式都将受影响而不能工作。为了降低风险和为日后的维护、扩展做准备,我们需要对它进行重构,这时工厂方法应运而生。
(1)工厂方法模式定义了一个用于创建对象的接口,让子类决定实例化哪个类,相比于简单工厂,工厂方法用多态来削弱了工厂类的职能。以下是工厂接口的定义:
//工厂接口
public interface Factory{
public Product create();
}
(2)我们再来定义一个产品接口:
//产品接口
public interface Product{}
(3)以下是实现了产品接口的产品类:
public class Mouse implements Product{
public Mouse (){
System.out.println("A mouse is created.");
}
}
public class Keyboard implements Product{
public Keyboard (){
System.out.println("A keyboard is created.");
}
}
public class Screen implements Product{
public Screen (){
System.out.println("A screen is created.");
}
}
(4)接下来,就是工厂方法的核心部分,也就是具体创建产品对象的具体工厂类:
//创建鼠标的工厂
public class Mouse implements Factory{
public Product create(){
return new Mouse();
}
}
//创建键盘的工厂
public class CreateKeyboard implements Factory{
public Product create(){
return new Keyboard();
}
}
//创建显示屏的工厂
public class CreateScreen implements Factory{
public Product create(){
return new Screen();
}
}
从上面创建产品对象的代码可以看出,工厂方法和简单工厂的主要区别是,简单工厂是把创建产品的职能都放在一个类里面,而工厂方法则把不同的产品放在实现了工厂接口的不同工厂类里面,这样就算其中一个工厂类出了问题,其他工厂类也能正常工作,互相不受影响,以后增加新产品,也只需要新增一个实现工厂接口工厂类,就能达到,不用修改已有的代码。