软件设计模式—简单工厂模式

软件设计模式之简单工厂模式

这是我的第一篇文章,而且是第一次使用markdown编辑器,以此记录在编程学习中的一些心得体会,如果有读者看到有不足之处,烦请指出,非常感谢!

背景:楼主是一个渣渣大三狗,这学期学校开了软件设计模式这门课,出于对本门课程的热爱就把所学内容记录下来,而且有幸阅读到程杰老师的名著大话设计模式,甚是喜欢,更给了我好好学下去的动力!

软件设计模式的思想来源于建筑学领域,它包含四个要素:

模式名称: 帮助记忆的名称的专业术语
问题: 设计场景
解决方案: 设计的细节,例如原理图示和代码示例
效果: 设计方案的优缺点,面向软件的一些质量属性,例如可扩展性、复用性等

总结:设计模式可以帮助设计者更快、更好地完成系统的设计工作。

以后所有的代码我都将习惯采用 java语言编写

问: 请用C++、Java、C#或VB、NET任意一种面向对象语言实现一个计算器控制台程序,要求输入两个数和运算符号,得到结果。

一:按照我们平常的编程习惯,肯定是这样写:

import java.util.Scanner;
public class caculator{
	public class void main(String[] args){
	 Scanner sc = new Scanner(System.in);
	 System.out.println("请输入数字A");
	 double numberA = sc,nextDouble();
	 System.out.println("请输入运算符号:(+、-、*、/):");
	 String strOperate = sc.next();
	 System.out.println("请输入数字B");
	 double numberB = sc,nextDouble();
	 double result = 0;
	 
	 switch(strOperate){
	 	case "+":
	 	result = numberA + numberB;
	 	break;
	 	case "-":
	 	result = numberA - numberB;
	 	break;
	 	case "*":
	 	result = numberA * numberB;
	 	break;
	 	case "/":
	 		if(numberB != 0)
	 			result = numberA / numberB;
	 		else
	 			System.out.println("除数不能为0");
	 	break;
	 	}
	 	System.out.println("计算结果为:"+result);
	 	sc.close();
	}
}

二:这样从头写到尾就行了吗? 问题来了:上面这段代码并没有题目所要求的的面向对象的思想,而且好的代码一定是要容易维护、容易扩展、容易复用。 那么怎么实现面向对象呢?我们想到了面向对象的三大特性:封装、继承和多态。 那好,接下来我们实现业务的封装,将业务逻辑类和界面逻辑类分离开来:

//运算类
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 "/":
	 		if(numberB != 0)
	 			result = numberA / numberB;
	 		else
	 			System.out.println("除数不能为0");
	 	break;
	}
	return result;
	}
}
//界面类
public class Client{
	public static void main(String[] args){
		Scanner sc = new Scanner(System.in);
	 	System.out.println("请输入数字A");
	 	double numberA = sc,nextDouble();
	 	System.out.println("请输入运算符号:(+、-、*、/):");
	 	String strOperate = sc.next();
	 	System.out.println("请输入数字B");
	 	double numberB = sc,nextDouble();
	
		double result = getResult(double numberA,double numberB,String operate);
	Sysrtem.out.println("计算结果为:"+result);
	}
}

三:上面已经将业务和界面分开了,问题又来了:现在如果要添加一个新的开平方根运算呢?我们会想到在switch语句中直接再加一条开平方根的运算不就行了吗?可以是可以,但是这样一来其他代码也参与了编译,而且如果不小心把别的运算在修改的过程中弄错了呢?我们想到把所有的运算都分离了不就行了(使用继承和多态)

//运算主类
public abstract class Operation{
	private double numberA;
	private double numberB;
	public void getNumberA(){
		return numberA;
	}
	public void setNumberA(String numberA){
		this.numberA = numberA;
	}
 	public void getNumberB(){
		return numberB;
	}
	public void setNumberB(String numberB){
		this.numberB = numberB;
	}
	public abstract void getResult();
}
//加法
public class OperationAdd extends Operation{
	public void getResult(){
	double result = getNumberA()+getNumberB();
	return result;
	}
}
//减法
public class OperationSub extends Operation{
	public void getResult(){
	double result = getNumberA()-getNumberB();
	return result;
	}
}
//乘法
public class OperationMul extends Operation{
	public void getResult(){
	double result = getNumberA()*getNumberB();
	return result;
	}
}
//除法
public class OperationDiv extends Operation{
	public void getResult(){
	double result;
	if(getNumberB()!=0)
		result = getNumberA()/getNumberB();
	else
		System.out.println("计算结果为:"+result)
	return result;
	}
}

四:当我们将全部计算分开之后,会发现一个问题,当我们写界面逻辑的时候,我们怎么让计算机知道我们选的是哪一种运算呢?这时候必须要考虑到实例化出一个对象,而且考虑到还会增加别的运算,我们就要单独做一个类用来创造实例,这里我们就要用到—简单工厂模式

//计算工厂类
public class OperationFactory{
	public static Operation createOperate(String operate){
	Operation oper = null;
	switch(Operation){
		case "+":
		oper = new OperationAdd();
		break;
		case "-":
		oper = new OperationSub();
		break;
		case "*":
		oper = new OperationMul();
		break;
		case "/":
		oper = new OperationDiv();
		break;
	}
	return oper;
	}
}
public class Client{
	public static void main(String[] args){
		Scanner sc = new Scanner(System.in);
		Operation oper;
	 	System.out.println("请输入运算符号:(+、-、*、/):");
	 	String strOperate = sc.next();
	 	OperationFactory.createOperate(strOperate);
	 	System.out.println("请输入数字A");
	 	oper.setNumberA(sc.nextDouble());
	 	System.out.println("请输入数字B");
	 	oper.setNumberB(sc.next.nextDouble());
		oper.getResult();
		sc.close();
	}
}

总结:
简单工厂方法模式的优点如下:
1:工厂方法包含从一个类的结构中选择初始类的业务逻辑
2:客户类不直接创建产品类的对象,客户类只作为对象的消费者
3:简单工厂方法模式实现了责任分离
4:客户类不负有创建类的对象的责任,因此如果有新的产品子类加入,不必修改已有的客户类代码(前提是客户类暂时不需要使用新的产品子类对象
5:因为工厂类中包含了对象生成的必要的逻辑判断,根据客户端的选择条件动态实例化相关的类,所以客户端类中没有创建对象所需要的条件语句
简单工厂方法模式的缺点如下:
1:由于工厂类必须知道怎样创建每个子类的对象,所以每当增加产品类的时候,都需要工厂类的代码。简单工厂方法模式不符合开闭原则。
2:因为工厂类的工厂方法是静态的,所以工厂类中的方法不能被继承,简单工厂类只能是一个单独的类,而不能成为一个层次的类

(上文总结摘自《软件设计模式与体系结构》)

UML图
在这里插入图片描述

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值