初学设计模式,所有素材都来自“大话设计模式”。
要求:“实现一个计算机控制台程序,要求输入两个数和运算符,得到结果”。
/**
* 运算基类
*/
public class Operation {
public static double getResult(double numberA,double numberB,String operate){
double result = 0;
switch(operate){
case "+":
result = numberA+numberB;
break;
case "-":
result = numberA - numberB;
break;
case "*":
result = numberA * numberB;
break;
case "/":
result = numberA / numberB;
break;
}
return result;
}
}
public class OperationApplication {
public static void main(String[] args) {
Scanner input = new Scanner(System.in);
try{
System.out.println("请输入数字A");
double numberA = input.nextDouble();
System.out.println("请选择运算符(+、-、*、/)");
String operate = input.next();
System.out.println("请输入数字B");
double numberB = input.nextDouble();
System.out.println("结果为: "+Operation.getResult(numberA,numberB,operate));
} catch (Exception e){
e.printStackTrace();
}
}
}
这样设计的话能否做到很灵活的可修改和扩展?
答案是否定的
如果在这个基础上面增加一个开根(sqrt)运算,要如何实现?
直接在switch分支上面加一个分支的话,就需要让加减乘除都参与编译,如果一不小心,把加法运算改成了减法,后果可想而知。
我们要做的是把加减乘除等运算分离,修改其中一个也不影响其他几个,增加运算算法也不会影响其他代码。
Operation运算类
/**
* 运算基类
*/
public class Operation {
private double numberA = 0;
private double numberB = 0;
public double getNumberA() {
return numberA;
}
public double getNumberB() {
return numberB;
}
public void setNumberA(double numberA) {
this.numberA = numberA;
}
public void setNumberB(double numberB) {
this.numberB = numberB;
}
public double getResult() throws Exception{
double result = 0 ;
return result;
}
}
加减乘除类
/**
* 加法类
*/
public class OperationAdd extends Operation{
@Override
public double getResult() {
double result = this.getNumberA() + this.getNumberB();
return result;
}
}
/**
* 减法类
*/
public class OperationSub extends Operation{
@Override
public double getResult() {
double result = this.getNumberA() - this.getNumberB();
return result;
}
}
/**
* 乘法类
*/
public class OperationMul extends Operation{
@Override
public double getResult() {
double result = this.getNumberA() * this.getNumberB();
return result;
}
}
/**
* 除法类
*/
public class OperationDiv extends Operation{
@Override
public double getResult() throws Exception{
if(this.getNumberB() == 0){
throw new Exception("除数不能为0");
}
double result = this.getNumberA() / this.getNumberB();
return result;
}
}
Operation作为基类,封装两个double属性用于运算,构造一个虚方法getResult()用于获得运算结果
加减乘除运算类继承Operation类,我们要获取结果的话可以直接重写getResult()方法,在getResult()方法中运算。这样做的话即便修改某一个运算类也不会影响其他的代码。
如此还面临着一个问题,那如何才能知道具体要做哪一种运算,需要实例化哪一个运算类,这样就需要用到简单工厂模式了。
OperationFactory运算工厂类
/**
* 运算工厂类
*/
public class OperationFactory {
public static Operation createOperation(String operate){
Operation oper = null;
switch(operate){
case "+":
oper = new OperationAdd();
break;
case "-":
oper = new OperationSub();
break;
case "*":
oper = new OperationMul();
break;
case "/":
oper = new OperationDiv();
break;
}
return oper;
}
}
只需要输入运算符号,工厂就实例化出合适的对象,通过多态,返回父类的方式实现计算机的灵活性、可扩展。
public class OperationApplication {
public static void main(String[] args) {
Scanner input = new Scanner(System.in);
try{
System.out.println("请输入数字A");
double numberA = input.nextDouble();
System.out.println("请选择运算符(+、-、*、/)");
String operate = input.next();
System.out.println("请输入数字B");
double numberB = input.nextDouble();
Operation operation =OperationFactory.createOperation(operate);
operation.setNumberA(numberA);
operation.setNumberB(numberB);
System.out.println("结果为: "+operation.getResult());
} catch (Exception e){
e.printStackTrace();
System.out.println(e.getMessage());
}
}
}
文章讨论了一个初学者设计的计算程序,指出其灵活性和扩展性不足。通过引入设计模式,特别是使用继承和简单工厂模式,将加减乘除运算抽象成单独的类,并通过工厂方法动态创建运算对象,提高了代码的可维护性和扩展性。这样,在添加新的运算如开根(sqrt)时,不会影响原有代码,增强了程序的灵活性。
1585





