#大话设计模式之简单工厂模式01#
我们使用一个案例来学习简单工厂模式吧,现在给出一个需求:设计一个“控制台计算机”。
你会怎么做呢,作为一名没学过简答工厂模式的孩纸,你5分钟敲出下面的代码... ...
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 |
|
虽然代码丑了点,但是好歹也做出来了是吧。不过我得告诉你上述代码究竟有什么问题:
①代码集中,耦合度高,难以重复利用,如果现在我要求你做一个网页版的计算器,你是不是得全部推倒重写了?
②扩展性低,如果我现在要求增加一个开根号的方法,你只能在源代码里的switch里面修改,这是很致命的,如果你偷偷(不小心)把加法改成减法,后果将不可设想
为了修改上面的缺点,你决定好好学一下简单工厂模式... ...学完简单模式后,你将决定为上面的代码做出如下修改:
①逻辑、界面的代码分开,减少代码耦合度。
②分离运算类,修改其中一个不会影响另外几个(利用继承和多态)
界面类
package SimpleFactoryPattern;
import java.util.Scanner;
public class CalcFrame {
public void printFrame(){
try{
Operation oper;
Scanner s = new Scanner(System.in);
System.out.println("*******计算器*******");
System.out.println("请输入数字A:");
String numA = s.nextLine();
System.out.println("请选择运算符号(+ - * /):");
String operator = s.nextLine();
System.out.println("请输入数字B:");
String numB = s.nextLine();
oper = OperationFactory.createOperation(operator);
oper.setNumA(Double.valueOf(numA));
oper.setNumB(Double.valueOf(numB));
//调用方法
System.out.println("结果是:"+oper.getResult());
}catch(Exception ex){
System.out.println("你的输入有错:"+ex.getMessage());
}
}
public static void main(String[] args) {
CalcFrame calcFrame = new CalcFrame();
calcFrame.printFrame();
}
}
运算父类(为什么要使用父类~~因为你会发现我们的子类会十分相似//)
package SimpleFactoryPattern;
public class Operation {
private double numA = 0;
private double numB = 0;
public double getNumA() {
return numA;
}
public void setNumA(double numA) {
this.numA = numA;
}
public double getNumB() {
return numB;
}
public void setNumB(double numB) {
this.numB = numB;
}
//
public double getResult(){
double result = 0;
return result;
}
}
运算子类(重写父类的getResult(),获取numA和numB进行运算,所有的算法都是一个新的类,不会彼此影响)
class Add extends Operation{
@Override
public double getResult() {
double result = 0;
result = getNumA() + getNumB();//子类直接调用父类的方法
return result;
}
}
class Sub extends Operation{
@Override
public double getResult() {
double result = 0;
result = getNumA() - getNumB();//子类直接调用父类的方法
return result;
}
}
class Mul extends Operation{
@Override
public double getResult() {
double result = 0;
result = getNumA() * getNumB();//子类直接调用父类的方法
return result;
}
}
class Div extends Operation{
@Override
public double getResult() {
double result = 0;
result = getNumA() / getNumB();//子类直接调用父类的方法
return result;
}
}
运算工厂类(看起来很抽象,其实是为了解决一个问题:如何让计算机知道我想用哪个算法呢?现在我只需要输入运算符号,就能实例化合适的对象了)
package SimpleFactoryPattern;
public class OperationFactory {
public static Operation createOperation(String operate){
Operation oper = null;
switch(operate){
case "+":
oper = new Add();
break;
case "-":
oper = new Sub();
break;
case "*":
oper = new Mul();
break;
case "/":
oper = new Div();
break;
}
return oper;
}
}
流程图:“界面类”得到numA,numB,operator,然后根据operator调用“工厂类”createOperation(operator)成功实例化想要的对象,比如new Add(),注意!!此方法将返回Operation类型,即“运算父类”,那么现在“界面类”成功获得实例对象Add(因为多态的关系,add属于Operation类),然后“子类add”调用父类方法setNumA、setNumB,父类numA和numB由0变为一个新的值,最后调用getResult方法,这个方法“子类add”已经重写过了,所以将会返回和的结果... ...
优点:①当你想要增加算法,只需要增加类,不会改变原来的正常的代码②复用性高,即使以后我们需要网络版或者图像界面版的计算器,逻辑算法所有代码也能复用,减轻程序员的压力~~
ending... ...