工厂模式可以分为三类:
1)简单工厂模式(Simple Factory)
2)工厂方法模式(Factory Method)
3)抽象工厂模式(Abstract Factory)
这三种模式从上到下逐步抽象,并且更具一般性。
GOF在《设计模式》一书中将工厂模式分为两类:工厂方法模式(Factory Method)与抽象工厂模式(Abstract Factory)。
将简单工厂模式(Simple Factory)看为工厂方法模式的一种特例,两者归为一类。
简单工厂模式是属于创建型模式,又叫做静态工厂方法(Static Factory Method)模式,但不属于23种GOF设计模式之一。
简单工厂模式是由一个工厂对象决定创建出哪一种产品类的实例。定义一个Factory类,可以根据参数的不同返回不同类的实例,被创建的实例通常有共同的父类。实质是由一个工厂类根据传入的参数,动态决定应该创建哪一个产品类实例。(只需要一个Factory类)
简单工厂模式中有如下三种角色:
Product:抽象产品类,将具体产品类公共的代码进行抽象和提取后封装在一个抽象产品类中。
ConcreteProduct:具体产品类,将需要创建的各种不同产品对象的相关代码封装到具体产品类中。
Factory:工厂类,提供一个工厂类用于创建各种产品,在工厂类中提供一个创建产品的工厂方法,该方法可以根据所传入参数的不同创建不同的具体产品对象。Factory类为静态类或包含静态方法。
客户端只需调用工厂类的工厂方法并传入相应的参数即可得到一个产品对象。
下面以实现一个简单运算器为例。运算类Operation相当于抽象产品类,它定义了一个抽象方法用来计算结果,具体计算步骤交给子类实现。这里一共有四个子类,相当于具体产品类,分别实现加减乘除的计算功能。运算工厂类OperationFactory完成创造实例的过程。
package simpleFactory;
public abstract class Operation {
protected double number_A=0;
protected double number_B=0;
public Operation(){}
public abstract double GetResult() throws Exception;
}
package simpleFactory;
public class AddOperation extends Operation { //加法类,继承运算类。
@Override
public double GetResult() {
double result=0;
result=number_A+number_B;
return result;
}
}
public class SubOperation extends Operation { //减法类,继承运算类。
@Override
public double GetResult() {
double result=0;
result=number_A-number_B;
return result;
}
}
public class MulOperation extends Operation { //乘法类,继承运算类。
@Override
public double GetResult() {
double result=0;
result=number_A*number_B;
return result;
}
}
public class DivOperation extends Operation { //除法类,继承运算类。
@Override
public double GetResult() throws Exception {
double result=0;
if(number_B==0)
{
throw new Exception("除数不能为0。");
}
result=number_A/number_B;
return result;
}
}
package simpleFactory;
public class OperationFactory {
public static Operation CreateOperate(String operate)
{
Operation oper=null;
switch(operate)
{
case "+":
oper=new AddOperation();
break;
case "-":
oper=new SubOperation();
break;
case "*":
oper=new MulOperation();
break;
case "/":
oper=new DivOperation();
break;
}
return oper;
}
}
package simpleFactory;
public class Main {
public static void main(String[] args) throws Exception {
Operation oper=OperationFactory.CreateOperate("/");
oper.number_A=1;
oper.number_B=2;
double result=oper.GetResult();
}
}
简单工厂模式最大的优点在于工厂类中包含了必要的逻辑判断,根据客户端的选择条件动态实例化相关的类。其缺点是一旦我们需要添加新的具体产品类,则需要修改Factory逻辑。这样违背了OCP(开放-关闭原则)。
采用工厂方法模式可以克服这一缺点。