可维护,可扩展,可复用,灵活性的计算器
简单工厂模式:如何根据需要来实例化不同的对象!
实现1: 简单工厂模式
简单工厂模式的最大特点就是:在于工厂类中包含了必要的逻辑判断,根据客户端的选择条件动态实例化相关的类。对于客户端来说,去除了与具体产品的依赖。
缺点:当增加一个其他运算时候,比如说m的n次方,除了增加类OperarionExp(扩展示开放的原则),还必须修改在简单工厂OperationFactory类中的case语句,
显然这样子违背了修改的封闭性原则。
package shiyeqiang.demo;
public class Test {
public static void main(String[] args) {
Operation ope = null;
ope = OperationFactory.createOperation("+"); // 可以根据“+”运算法实例化OperationAdd()运算类
ope.setNumberA(12);
ope.setNumberB(12);
System.out.println(ope.getResult());
}
}
abstract class Operation { // 定义运算类,含有一个抽象方法getResult()
private double numberA = 0;
private double numberB = 0;
public double getNumberA() {
return numberA;
}
public void setNumberA(double numberA) {
this.numberA = numberA;
}
public double getNumberB() {
return numberB;
}
public void setNumberB(double numberB) {
this.numberB = numberB;
}
public abstract double getResult(); // 抽象方法是没有方法体的
}
class OperationAdd extends Operation { // 加法类,继承运算类,重写抽象方法
@Override
public double getResult() {
return this.getNumberA() + this.getNumberB();
}
}
class OperationSub extends Operation {// 减法类,继承运算类,重写抽象方法
@Override
public double getResult() {
return this.getNumberA() - this.getNumberB();
}
}
class OperationMul extends Operation {// 乘法类,继承运算类,重写抽象方法
@Override
public double getResult() {
return this.getNumberA() * this.getNumberB();
}
}
class OperationDiv extends Operation {// 除法类,继承运算类,重写抽象方法
@Override
public double getResult() {
if (this.getNumberB() == 0) {
try { // 对于除法,要特别判断除法为0的情况
throw new Exception("除数不能为0");
} catch (Exception e) {
e.printStackTrace();
}
}
return this.getNumberA() / this.getNumberB();
}
}
class OperationFactory { // 简单工厂类,根据不同的操作符来实例化不同的(加减乘除)运算类
public static Operation createOperation(String operate) {
// 工厂模式定义的是静态的方法,类名.静态方法名 可以直接访问
Operation operation = null;
switch (operate) {
case "+":
operation = new OperationAdd();
break;
case "-":
operation = new OperationSub();
break;
case "*":
operation = new OperationMul();
break;
case "/":
operation = new OperationDiv();
break;
}
return operation;
}
}
从简单工厂模式可以发现:客户端需要认识两个类:(基类以及工厂类)
Operation ope = null;
ope = OperationFactory.createOperation("+");
2:策略与简单工厂模式结合
OperationContext类中属性含有运算类!同时在OperationContext类内部实现简单工厂模式;这样子客户端只需要认识OperationContext类即可!
思想:其他类中的成员属性含有基类,有了基类以后可以在构造方法内部实现工厂模式。最后在其他类调用基类的方法就可以将基类完全隐藏起来了。
在客户端实例化的是OperationContext的对象,调用的是类OperationContext中的getResult()方法;这使得操作类的父类Operation都不让客户端认识了。
class OperationContext {
// 策略模式与工厂模式相结合
private Operation ope = null; //策略模式
public OperationContext(String operate) { //工厂模式
switch (operate) {
case "+":
ope = new OperationAdd();
break;
case "-":
ope = new OperationSub();
break;
case "*":
ope = new OperationMul();
break;
case "/":
ope = new OperationDiv();
break;
}
}
public double getResult(double numberA, double numberB) {
this.ope.setNumberA(numberA);
this.ope.setNumberB(numberB);
return this.ope.getResult();
}
}
客户端之需要调用:OperationContext一个类就行了!
OperationContext oc = new OperationContext("*");
System.out.println(oc.getResult(2, 5));