我们写代码的时候,往往会不自觉地使用面向过程的思想去编写。
比如下面的代码,是一个简单的计算机程序,但是用面向过程的思想。
package study.ruanwh.simple_factory;
import java.util.Scanner;
/**
* 一个简单的面向过程的计算器
* @author ruanwh
*
*/
public class SimpleCalculator {
public static void main(String[] args) {
System.out.println("请输入数字A:");
Scanner in = new Scanner(System.in);
double numA = in.nextDouble();
System.out.println("请选择运算符号(+、-、*、/):");
String operate = in.next();
System.out.println("请输入数字B:");
double numB = in.nextDouble();
in.close();
String result = "";
switch (operate) {
case "+":
result = numA + numB + "";
break;
case "-":
result = numA - numB + "";
break;
case "*":
result = numA * numB + "";
break;
case "/":
if (numB != 0) {
result = numA / numB + "";
} else {
result = "除数不能为零";
}
break;
}
System.out.println(numA + operate + numB + "的结果是:" + result);
}
}
但是这样的程序可维护性差,可复用性差,可扩展性差。比如这个程序的需求是进行两个数字的加减乘除运算,但是如果要增加一个开根或求平方的运算,就要修改这个单独的类,一旦修改的部分出现了错误,即使加减乘除代码完全正确,程序也无法正确运行。
利用面向对象的思想,通过封装、继承、多态把程序的耦合度降低,利用设计模式使程序更加灵活,容易修改,并且易于复用。因此,面向对象思想使程序具备三个特点:可维护、可复用、可扩展。
比如我们利用封装这个面向对象的特性对上面计算器的代码进行改造。改造后把业务逻辑与界面逻辑分开,让程序的耦合度下降。
运算类代码
package study.ruanwh.simple_factory;
/**
* 項目:一个简单的面向过程的计算器
* 功能:运算类
* @author ruanwh
*
*/
public class Operation {
public static String getResult (double numA, double numB, String operate) {
String result = "";
switch (operate) {
case "+":
result = numA + numB + "";
break;
case "-":
result = numA - numB + "";
break;
case "*":
result = numA * numB + "";
break;
case "/":
if (numB != 0) {
result = numA / numB + "";
} else {
result = "除数不能为零";
}
break;
}
return result;
}
}
客户端代码
package study.ruanwh.simple_factory;
import java.util.Scanner;
/**
* 項目:一个简单的面向过程的计算器
* 功能:客户端
* @author ruanwh
*
*/
public class SimpleCalculator {
public static void main(String[] args) {
System.out.println("请输入数字A:");
Scanner in = new Scanner(System.in);
double numA = in.nextDouble();
System.out.println("请选择运算符号(+、-、*、/):");
String operate = in.next();
System.out.println("请输入数字B:");
double numB = in.nextDouble();
in.close();
String result = "";
result = Operation.getResult(numA, numB, operate);
System.out.println(numA + operate + numB + "的结果是:" + result);
}
}
下面通过代码演变来讲解简单工厂模式。
运算类Operation——这是一个抽象类
package study.ruanwh.simple_factory;
/**
* 项目:一个简单工厂模式实现的计算器
* 功能:运算类(抽象类)
* @author ruanwh
*
*/
public abstract class Operation {
protected double numA = 0;
protected 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 abstract double getResult () throws Exception;
}
然后是相应的加减乘除类
1.加法类
package study.ruanwh.simple_factory;
/**
* 项目:一个简单工厂模式实现的计算器
* 加法运算类
* @author smallruan
*
*/
public class AddOperation extends Operation {
@Override
public double getResult() {
double result = 0;
result = numA + numB;
return result;
}
}
2.减法类
package study.ruanwh.simple_factory;
/**
* 项目:一个简单工厂模式实现的计算器
* 减法运算类
* @author smallruan
*
*/
public class SubstractOperation extends Operation {
@Override
public double getResult() {
double result = 0;
result = numA - numB;
return result;
}
}
3.乘法类
package study.ruanwh.simple_factory;
/**
* 项目:一个简单工厂模式实现的计算器
* 乘法运算类
* @author smallruan
*
*/
public class MultiplyOperation extends Operation {
@Override
public double getResult() {
double result = 0;
result = numA * numB;
return result;
}
}
4.除法类
package study.ruanwh.simple_factory;
/**
* 项目:一个简单工厂模式实现的计算器
* 除法运算类
* @author smallruan
*
*/
public class DivideOperation extends Operation {
@Override
public double getResult() throws Exception {
double result = 0;
if (numB == 0) {
throw new Exception("除数不能为零。");
}
result = numA / numB;
return result;
}
}
接下来是工厂类,由为个类来生成各种算法的对象。
package study.ruanwh.simple_factory;
/**
* 项目:一个简单工厂模式实现的计算器
* 运算工厂类
* @author smallruan
*
*/
public class OperationFactory {
public static Operation createOperate (String operate) {
Operation oper = null;
switch (operate) {
case "+":
oper = new AddOperation();
break;
case "-":
oper = new SubstractOperation();
break;
case "*":
oper = new MultiplyOperation();
break;
case "/":
oper = new DivideOperation();
break;
}
return oper;
}
}
最后是客户端,这里主要是展现如何去进行计算器的调用。
package study.ruanwh.simple_factory;
/**
* 项目:一个简单工厂模式实现的计算器
* 功能:客户端
* @author ruanwh
*
*/
public class SimpleCalculator {
public static void main(String[] args) throws Exception {
Operation oper;
oper = OperationFactory.createOperate("+");
oper.numA = 1;
oper.numB = 2;
double result = oper.getResult();
System.out.println("运算结果为: " + result);
oper = OperationFactory.createOperate("-");
oper.numA = 1;
oper.numB = 2;
double result2 = oper.getResult();
System.out.println("运算结果为: " + result2);
oper = OperationFactory.createOperate("*");
oper.numA = 1;
oper.numB = 2;
double result3 = oper.getResult();
System.out.println("运算结果为: " + result3);
oper = OperationFactory.createOperate("/");
oper.numA = 1;
oper.numB = 2;
double result4 = oper.getResult();
System.out.println("运算结果为: " + result4);
}
}
下面是的控制的结果:
运算结果为: 3.0
运算结果为: -1.0
运算结果为: 2.0
运算结果为: 0.5
通过这个例子,我们可以看到使用设计模式是开始是比较麻烦的,但是当后面需求改变,要添加东西的时候,非常灵活方便,比如现在要增加一个平方算法,我们只需要增加一个Operation的子类实现类,然后在OperationFactory工厂类中添加对象的生成代码即可,各个算法互不相干,如果代码出了什么问题,非常容易发现。这就是设计模式的好处。