- 一. 为什么要学设计模式
- 我们在学习编程的时候,都有了解过设计模式,通过这些模式让你找到“封装变化” 、“对象间松散耦合”、“针对接口编程”的感觉,从而设计出易维护、易扩展、易复用、灵活性好的成语。学好设计模式,培养好面向对象的编程思维。
- 二.简单工厂模式
- 简单工厂模式就是通过一个工厂类来创建你需要的不同的实例。
比如 现在来实现一个简单的计算器
public class SampleFactory {
public static void main(String[] args) {
Scanner in = new Scanner(System.in);
System.out.println("请输入第一个数字:");
double first = Double.parseDouble(in.next());
System.out.println("请输入运算符号");
String operType = in.next();
System.out.println("请输入第二个数字");
double second = Double.parseDouble(in.next());
in.close();
double resultTest = 0;
Operation_test operTest = new Operation_test();
switch(operType) {
case "+" :
resultTest = operTest.getAddResult(first, second);
break;
case "-" :
resultTest = operTest.getSubResult(first, second);
break;
case "*" :
resultTest = operTest.getMulResult(first, second);
break;
case"/" :
try {
resultTest = operTest.getDivResult(first, second);
} catch (Exception e1) {
System.out.println(e1.getMessage());
}
break;
}
System.out.println(first + operType +second + "=" + resultTest );
}
}
public class Operation_test {
public double getAddResult(double numberA,double numberB) {
double result = numberA + numberB;
return result;
}
public double getSubResult(double numberA,double numberB) {
double result = numberA - numberB;
return result;
}
public double getMulResult(double numberA,double numberB) {
double result = numberA * numberB;
return result;
}
public double getDivResult(double numberA,double numberB) throws Exception {
double result = 0;
if(numberB== 0) {
throw new Exception("除数不能为0");
}else {
result = numberA / numberB;
}
return result;
}
}
这样看已经实现了基本的实现了计算器的基本四种运算,如果要在继续添加其他的计算方式在运算类中就可以了,但是所有的计算方式都在一个类中,如果修改其中一个,影响到了其他的几种计算方式,或者随这计算的方式增加,这个计算类的可维护性就会变差,这个时候我们就要用到了设计模式。
1 简单工厂模式来实现
首先我们创建一个父类来将计算所需要的属性与方法放进去(封装)
/**
*
*/
package sample_factory;
/**
* @author manyi
*
* 计算方法父类
*/
public class Operation {
private double numberA;
private double numberB;
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 double getResult() throws Exception {
double result = 0;
return result;
}
}
然后我们创建计算方法的具体实现子类(继承)
/**
*
*/
package sample_factory;
/**
* @author manyi
*
* 加法计算类
*/
public class OperationAdd extends Operation{
public double getResult() {
double result = 0 ;
result = getNumberA() + getNumberB();
return result;
}
}
/**
*
*/
package sample_factory;
/**
* @author manyi
* 减法运算类
*/
public class OperationSub extends Operation{
public double getResult() {
double result = 0;
result = getNumberA() - getNumberB();
return result;
}
}
/**
*
*/
package sample_factory;
/**
* @author manyi
* 乘法运算类
*/
public class OperationMul extends Operation{
public double getResult() {
double result = 0;
result = getNumberA() * getNumberB();
return result;
}
}
/**
*
*/
package sample_factory;
/**
* @author manyi
* 除法计算类
*/
public class OperationDiv extends Operation{
public double getResult() throws Exception {
double result = 0 ;
if(getNumberB() == 0) {
throw new Exception("除数不能为0");
}else {
result = getNumberA() / getNumberB();
}
return result;
}
}
接下来创建工厂类来根据客户端传来的计算方式来创建返回正确的计算方式实例(多态)
/**
*
*/
package sample_factory;
/**
* @author manyi
* 计算工厂类
* @return 返回一个输入的计算方法类实例
*/
public class OperationFactory {
public static Operation createOperation(String type) {
Operation oper = null;
switch(type) {
case "+" :
oper = new OperationAdd();
break;
case "-" :
oper = new OperationSub();
break;
case "*" :
oper = new OperationMul();
break;
case"/" :
oper = new OperationDiv();
break;
}
return oper;
}
}
/**
*
*/
package sample_factory;
import java.util.Scanner;
/**
* @author manyi
* @Date 2018年12月9日
*/
public class SampleFactory {
public static void main(String[] args) {
Scanner in = new Scanner(System.in);
System.out.println("请输入第一个数字:");
double first = Double.parseDouble(in.next());
System.out.println("请输入运算符号");
String operType = in.next();
System.out.println("请输入第二个数字");
double second = Double.parseDouble(in.next());
in.close();
new OperationFactory(); //创建一个计算工厂类实例
Operation oper = OperationFactory.createOperation(operType);// 通过传入的计算符号返回一个对应的计算类实例
oper.setNumberA(first);
oper.setNumberB(second);
double result = 0;
try {
result = oper.getResult();
} catch (Exception e) {
System.out.println(e.getMessage());
}
System.out.println(first + operType +second + "=" + result);
}
}
这样就减少了计算方法之间的耦合,修改其中一个也不会影响其他的方法,增加的新的方法时添加一个新的计算类继承父类就可以实现了。
优点:
1、用户想创建一个对象,只要知道其名称就可以从工厂中获取对象。
2、扩展性高,如果想增加一个产品,只要扩展一个具体产品类就可以。
3、屏蔽产品的具体实现,用户只关心产品的接口。
缺点:
每次增加一个产品时,都需要增加一个具体类和对象实现工厂,使得程序中出现大量的类,在一定程度上增加系统的复杂度。