简单工厂模式
简单工厂模式是是很常见的一个设计模式。在日常的学习中经常提起,也很容易实现。
一个简单的计算器,实现两个数的运算。简单工厂方法的实现如下:
//运算类
public abstract class Operation {
public double numberA = 0;
public double numberB = 0;
public abstract double getResult();
}
加法类实现运算类,实现对外的接口,还可以实现减法等等的类
public class AddOperation extends Operation {
@Override
public double getResult() {
return numberA+numberB;
}
}
简单工厂模式
public class staticFactory {
public static Operation factory(String type){
Operation operation = null;
switch (type){
case "+":
operation = new AddOperation();
break;
case "-":
break;
case "*":
break;
case "/":
}
return operation;
}
}
public static void main(String[] args) {
Operation op = staticFactory.factory("+");
op.numberA = 1.0;
op.numberB = 2.0;
System.out.println(op.getResult());
}
}
简单工厂模式最大的优点就在于工厂类中包含了必要的逻辑判断,根据客户端的选择条件动态的实例化相关的类。但是简单工厂模式有不好的地方,就是违反了开闭原则,它对拓展是开放的,但是对于修改也是开放的。于是就有了下面的工厂方法模式。
工厂方法模式
工厂方法模式,定义一个用于创建对象的接口,让子类决定实例化拿个类。工厂方法使一个类的实例化延时到其子类。
从图中可以看出工厂方法其实是简单工厂方法的面向接口编程。
1. 创建一个Operation类,定义操作。
2. 创建一个生产Operation工厂的工厂(接口)OperationFactory,所有的Operation工厂类都继承它。
3. 创建相应的加法AddOperation,减法等类,继承Operation类。
4. 创建相应的AddOperationFactory工厂,来产生相应的加法,减法类。
简单实现
//运算类,
public abstract class Operation {
public double numberA = 0;
public double numberB = 0;
public abstract double getResult();
}
//产生运算类工厂的工厂
public interface OperationFactory {
public Operation CreateOperationFactory();
}
public class SubOperation extends Operation {
@Override
public double getResult() {
return numberA-numberB;
}
}
public class AddOperation extends Operation {
@Override
public double getResult() {
return numberA+numberB;
}
}
产生相应的工厂
public class SubOperationFactory implements OperationFactory {
@Override
public Operation CreateOperationFactory() {
return new SubOperation();
}
}
public class AddOperationFactory implements OperationFactory {
@Override
public Operation CreateOperationFactory() {
return new AddOperation();
}
}
工厂方法模式虽然在完成相同的事情上,比简单工厂模式多了接口和很多类,但是工厂方法模式符合开闭原则。当我们需要拓展新的运算时,例如实现M的N次方的运算,我们只需要创建一个新的运算类继承operation。在创建一个产生这个运算类的工厂继承OperationFactory 就完成了功能的拓展,不会修改其他的代码。只需要对前台的客户端进行升级就可以了。
总的来说工厂方法的使用其实是对应的。
当你想使用工厂方法的时候,就像你想做一个加法减法功能。想用工厂方法。
首先就是抽象出一个运算类,对应的工厂方法就是一个产生这个类的工厂
其次,创建了具体的运算的类继承这个运算类是,你就需要创建产生个类的工厂类,同时这个工厂类继承产生运算类的工厂类。
使用匿名内部类构造工厂模式
看过thinking in java的后,从以上代码中我们可以发现,SubOperationFactory 和AddOperationFactory 都不是单例的,而且每次可能会创建多次,可以将他们的构造方法都变成private,然后创建一个静态的OperationFactory变量来获取具体的 操作,改造如下:
1,Operation和OperationFactory都不变
2,删除SubOperationFactory和AddOperationFactory
3,修改AddOperation和SubOperation
public class SubOperation extends Operation {
@Override
public double getResult() {
return super.numberA-super.numberB;
}
public static OperationFactory factory = new OperationFactory() {
@Override
public Operation CreateOperationFactory() {
return new SubOperation();
}
};
}
public class AddOperation extends Operation {
@Override
public double getResult() {
return numberA+numberB;
}
public static OperationFactory factory = new OperationFactory() {
@Override
public Operation CreateOperationFactory() {
return new AddOperation();
}
};
}
4,统一化具体的操作创建Factories
public class Factories {
public static void Operations(OperationFactory factory,double i,double j){
Operation operation = factory.CreateOperationFactory();
operation.numberA = i;
operation.numberB = j;
System.out.println(operation.getResult());
}
public static void main(String[] args) {
//减法
Operations(SubOperation.factory,1.0,2.0);
//加法
Operations(AddOperation.factory,2.0,3.0);
}
}
通过以上改造,我们使我们的程序更加的优美,而且更加具有实际意义。客户端直接调用统一接口,传递不同参数就可以完成功能,同时也具有高开闭性,充分体现了依赖转移的设计 原则。