引言:在我没学习设计模式之前,让我写一个计算器的小demo,我可能会这么写......
public static double getResult(double a,double b,String operate) {
double result = 0;
switch (operate) {
case "+":
result = a + b;
break;
case "-":
result = a - b;
break;
case "*":
result = a * b;
break;
case "/":
if(b == 0) {
throw new RuntimeException("除数不能为0");
}
result = a / b;
break;
default:
break;
}
return result;
}
public static void main(String[] args) {
System.out.println("请输入数字a");
Scanner scanner = new Scanner(System.in);
double a = scanner.nextDouble();
System.out.println("请输入数字b");
double b = scanner.nextDouble();
System.out.println(Operation.getResult(a, b, "+"));
}
但当我学习之后,还这么写,就有点过分了,首先,除了封装了功能之外,这一点也不面向对象,另外,当添加新功能时,比如平方,必须修改case语句,这一改,牵一发而动全身,其他功能都得重新编译,改对了ok,改错了全完蛋,耦合性太高,得修改!得修改!得修改!
public abstract class Operation {
protected double a;
protected double b;
public abstract double getResult();
}
//+
public class OperationAdd extends Operation {\
@Override
public double getResult() {
return a + b;
}
}
//-
public class OperationSub extends Operation {
@Override
public double getResult() {
return a - b;
}
}
//*
public class OperationMul extends Operation{
@Override
public double getResult() {
return a * b;
}
}
// /
public class OperationDiv extends Operation {
@Override
public double getResult() {
if(b == 0) {
throw new RuntimeException("除数不能为0");
}
return a / b;
}
}
ok,现在再添加功能也不怕了,只需要添加相应的功能类,也不会影响到其他的功能。那如何计算呢?让客户端去实例化加减乘除类去计算?感觉不好,最好就是客户端给个运算符号就行了,这个时候,简单工厂模式必须要出场了。
简单工厂
![](https://i-blog.csdnimg.cn/blog_migrate/43e81325eb67c4b30c4552abb320b85c.png)
public class OperationFactory {
public static Operation createOperation(String operation) {
Operation oper = null;
switch (operation) {
case "+":
oper = new OperationAdd();
break;
case "-":
oper = new OperationSub();
break;
case "*":
oper = new OperationMul();
break;
case "/":
oper = new OperationDiv();
break;
default:
break;
}
return oper;
}
public static void main(String[] args) {
Operation oper = OperationFactory.createOperation("/");
oper.a = 2;
oper.b = 3;
System.out.println(oper.getResult());
}
}
优点:会根据客户端的选择条件动态实例化相关类,对于客户端来说,去除了与具体产品的依赖,有效降低了耦合度。
缺点:当增加功能时,我们添加功能类之外还需要修改case分支条件,这违背了开放封闭原则。
为了克服简单工厂的这个缺点,工厂模式顺势而生
为了克服简单工厂的这个缺点,工厂模式顺势而生
工厂模式
public interface IFactory {
Operation createOperation();
}
//+
public class AddFactory implements IFactory {
public Operation createOperation() {
return new OperationAdd();
}
}
//-
public class SubFactory implements IFactory {
public Operation createOperation() {
return new OperationSub();
}
}
//*
public class MulFactory implements IFactory {
public Operation createOperation() {
return new OperationMul();
}
}
// /
public class DivFactory implements IFactory {
public Operation createOperation() {
return new OperationDiv();
}
}
此时,添加新的功能时,只要添加对应的功能类以及对应的功能工厂即可。
优点:工厂方法模式是简单工厂模式的进一步抽象与推广,保持了简单工厂模式的优点,并克服了缺点。
缺点:每增加新的产品时,需要增加对应产品工厂的类,增加了额外的开发量。