设计模式学习之简单工厂模式

版权声明:本文为博主原创文章,未经博主允许不得转载。 https://blog.csdn.net/Snrt_Julier/article/details/71698624

先说一个简单的案例:

实现一个控制台程序,输入两个数字和一个运算符,输出其计算结果。

案例很简单

Class Main{
	
	public static void main(String args){
		Scanner scan = new Scanner(System.in);
		System.out.print("请输入数字A:");
		double numberA = scan.nextDouble();
		System.out.print("请输入操作符(+ - * /):");
		String operate = scan.next();
		System.out.print("请输入数字B:");
		double numberB = scan.nextDouble();
		scan.close();
		switch(operate){
			case "+":
				System.out.println("计算结果是"+(numberA+numberB));
			break;
			case "-":
				System.out.println("计算结果是"+(numberA-numberB));
			break;
			case "*":
				System.out.println("计算结果是"+(numberA*numberB));
			break;
			case "/":
				System.out.println("计算结果是"+(numberA/numberB));
			break;
			default:
				System.out.println("操作符有误");
			break;
		}
	}
}


但是这样写真的很好吗?java语言的面向对象的优越性就这样放弃了??这样算是业务逻辑和界面逻辑分离了???

基于上述考虑我们可以对这个案例进行重新设计

先考虑业务与逻辑的分离:

Class Main{
	
	public static void main(String args){
		Scanner scan = new Scanner(System.in);
		System.out.print("请输入数字A:");
		double numberA = scan.nextDouble();
		System.out.print("请输入操作符(+ - * /):");
		String operate = scan.next();
		System.out.print("请输入数字B:");
		double numberB = scan.nextDouble();
		scan.close();
		Operate op = new Operate(numberA, numberB, operate);
		System.out.println("计算结果是"+op.getResult());
		
	}
}
class Operate{
	private double numberA;
	private double numberB;
	private String operate;
	
	public Operate(double numberA, double numberB, String operate){
		this.numberA = numberA;
		this.numberB = numberB;
		this.operate = operate;
	}
	
	public double getResult(){
		switch(operate){
			case "+":
				return (numberA+numberB);
			break;
			case "-":
				return (numberA-numberB);
			break;
			case "*":
				return(numberA*numberB);
			break;
			case "/":
				return (numberA/numberB);
			break;
			default:
			break;
		}
	}
}

使用面向对象的三大特性:

public abstract class Operator {
	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 abstract double getResult() throws Exception;
	
}

class AddOperator extends Operator{

	@Override
	public double getResult() {
		return this.getNumberA()+this.getNumberB();
	}
	
}

class MinusOperator extends Operator{

	@Override
	public double getResult() {
		return this.getNumberA()-this.getNumberB();
	}
	
}

class MultiplyOperator extends Operator{

	@Override
	public double getResult() {
		return this.getNumberA()* this.getNumberB();
	}
	
}

class DivideOperator extends Operator{

	@Override
	public double getResult() throws Exception {
		if(this.getNumberB() == 0)
				throw new Exception("除数不能为零");
		return this.getNumberA()/ this.getNumberB();
	}
	
}

现在问题是我该如何让程序知道我该实现哪个类完成计算

这里就需要用到简单工厂模式

建立工厂类

public class OperateFactory {
	public static Operator createOperator(String operate){
		switch (operate) {
			case "+":return new AddOperator();
			case "-":return new MinusOperator();
			case "*":return new MultiplyOperator();
			case "/":return new DivideOperator();
	
			default:return null;
		}
	}
}

在main方法中就可以应用该工厂完成Operate的实例化

class Main{
	
	public static void main(String[] args) {
		Scanner scan = new Scanner(System.in);
		System.out.print("输入数字A:");
		double numberA = scan.nextDouble();
		
		System.out.print("输入操作符(+ - * / ):");
		String operate = scan.next();
		
		System.out.print("输入数字B:");
		double numberB = scan.nextDouble();
		
		scan.close();
		
		Operator op = TestFactoryPattern.createOperator(operate);
		op.setNumberA(numberA);op.setNumberB(numberB);
		try {
			System.out.println("计算结果:"+op.getResult());
		} catch (Exception e) {
			// TODO Auto-generated catch block
			e.printStackTrace();
		}
		
	}
}

从上述的例子中不难看出

简单工厂模式解决的问题是:如何根据需要实例化合适的类

其核心思想:用一个专门的类去产生实例

优缺点分析:

优点:

工厂类是整个模式的关键所在。

包含必要的判断逻辑,能够根据外界给定的信息,决定究竟应该创建哪个具体类的对象。

用户在使用时可以直接根据工厂类去创建所需的实例,而无需了解这些对象是如何创建以及如何组织的。

有利于整个软件体系结构的优化。

缺点:

工厂类集中了所有实例的创建逻辑,这就直接导致一旦这个工厂出了问题,所有的客户端都会受到牵连;

简单工厂模式的产品室基于一个共同的抽象类或者接口,这样一来,但产品的种类增加的时候,

即有不同的产品接口或者抽象类的时候,工厂类就需要判断何时创建何种种类的产品,

这就和创建何种种类产品的产品相互混淆在了一起,违背了单一职责,导致系统丧失灵活性和可维护性。

而且更重要的是,简单工厂模式违背了“开放封闭原则”,就是违背了“系统对扩展开放,对修改关闭”的原则,

因为当我新增加一个产品的时候必须修改工厂类,相应的工厂类就需要重新编译一遍。

猜你喜欢

转载自blog.csdn.net/Snrt_Julier/article/details/71698624