第一篇、创建型设计模式——简单工厂模式(静态工厂方法模式)

在具体学习设计模式之前,先要了解什么是设计模式,以及为什么要学习设计模式。

简单来说,设计模式就是一套被人们反复应用,形成了一套代码编写规范的经验以及结构总结。我们通过设计模式的学习,可以有意识地将业务逻辑与界面逻辑做到有效的分离,使程序的耦合度降低,让程序变得易维护、易扩展、易复用、少修改。


这里还要提一句的是,我们在用面向对象语言编写代码时,应该注意点几点准则:

1、单一指责原则:就一个类而言,引起它的变化的因素越少越好,最好只有一个因素。因为一个类承担过多的职责,相当于把这些职责耦合在了一起,一个职责的变化可能削弱或抑制它完成其他的职责。当业务发生变化时,设计会受到意想不到的破坏。直接例子就是会导致我们修改的工作量提升)

2、开放-封闭原则:软件实体(类,模块,函数等)应该可以扩展,但是不可以修改。也可以理解为,对扩展是开放的,宽松的;对修改是关闭的,严格的。这条原则也是面向对象设计的核心所在。当然,完全对修改封闭也是不现实的,但是通过遵守这一原则设计出的程序,可以减少我们修改程序时的工作量。

3、依赖倒转原则:简单来说,就是我们应该针对接口进行编程,不应该针对实现。例如:当我们生产一台电脑时,再设计内存条插槽时,只需要遵守它的设计规范就好,组装时,凡事遵守该规范的内存条均可使用,无需知道具体会用到哪种品牌的。如果针对实现设计,那我们就要事先知道用哪种品牌的内存条,这大大增加了我们设计开发时的工作量。

4、里氏代换原则:子类型必须能够替代他们的父类型。这条也是多台概念的体现。

以上4条原则,也充分体现了面向对象语言的特性,即继承,封装,多态。

----------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------

现在我们开始来看第一个设计模式,也是类创建性模式中的简单工厂模式,又叫静态工厂方法模式

何为简单工厂模式,就是书写一个类作为工厂类,它负责创建相应具体的产品类对象,并将结果return给客户端。客户端只需要给他传递相应的条件,即可拿到需要的产品对象,而无需知道工厂类是如何创建这个对象的。

假如说,我们需要编写一个计算器程序,先实现简单的加减法,对于初学面向对象语言的人来说,可能会这样书写代码:

在客户端的页面类中

		String operaStr = "-";
		double a = 2;
		double b = 1;
		double result = 0.0;
		switch (operaStr) {
		case "+":
			result = a + b;
			break;
		case "-":
			result = a - b;
			break;
		}
		System.out.println(result);

首先,这样是可以实现功能,但是这样设计程序,使客户端页面不仅仅承担了数据的获取与展示职责,也承担了运算的职责,当数据获取出现问题时,会导致其运算职责受到影响。同样运算出现问题时,也可能导致数据展示受到影响。

其次,当我们需要增加乘法与除法运算功能时,我们要修改这个类,像这样

		String operaStr = "-";
		double a = 2;
		double b = 1;
		double result = 0.0;
		switch (operaStr) {
		case "+":
			result = a + b;
			break;
		case "-":
			result = a - b;
			break;
		case "*":
			result = a * b;
			break;
		case "/":
			result = a / b;
			break;
		}
		System.out.println(result);
有人会说,这样修改很简单啊,一下子就完成了。那如果你的程序中,有多个地方拥有这个运算功能,那你是不是就要修改所有这些地方了。如果你的功能更加复杂,那修改起来是不是更加麻烦。这种设计是否增加了工作量。

现在我们用简单工厂模式来设计这个程序

1、首先创建一个运算父类

public abstract class Operation {
	public double a = 0.0;
	public double b = 0.0;

	public abstract double getResult();
}
2、创建具体的运算类,加法运算类,减法运算类

//加法运算类
public class OperationAdd extends Operation {
	@Override
	public double getResult() {
		return a + b;
	}
}

//减法运算类
public class OperationSub extends Operation {
	@Override
	public double getResult() {
		return a - b;
	}
}

3、运算工厂类
public class OperationFactory {
		public static Operation creatOperation(String str) {
			Operation operation = null;
			switch (str) {
			case "+":
				operation = new OperationAdd();
				break;
			case "-":
				operation = new OperationSub();
				break;
			}
			return operation;
		}
}


4、客户端页面

Operation operation = OperationFactory.creatOperation("+");
operation.a = 1.0;
operation.b = 2.0;
double result = operation.getResult();

有人会说,一个计算器弄得这么麻烦,没有看到这样写的优势啊。别急,我们一起来分析分析。

首先,我将客户端数据获取、展示,运算进行了分离,这样满足了单一职责原则。客户端只负责与用户的交互,如获取用户命令,展示运算结果。运算类只负责运算,不关心其他职责。当一方有问题时,降低了对其他类的影响。

其次,当我需要增加乘法与除法运算时,我只需要仿照加法与减法,增加两个运算类OperationMul和OperationDiv,并在运算工厂类中稍作修改

public class OperationFactory {
		public static Operation creatOperation(String str) {
			Operation operation = null;
			switch (str) {
			case "+":
				operation = new OperationAdd();
				break;
			case "-":
				operation = new OperationSub();
				break;
			case "*":
				operation = new OperationMul();
				break;
			case "/":
				operation = new OperationDiv();
				break;
			}
			return operation;
		}
}


对于客户端而言,我们即使不进行修改,也可实现新的功能,不管有多少调用,均不会受到修改的影响,直接降低了功能变化造成的工作量,耦合度降低。当再次添加其他运算功能时,只需添加新的运算类,对运算工厂类稍作修改,无需改动已有的运算类。这种低耦合度的设计,降低了修改过程中,对已有功能的影响。是不是体现了易维护、易扩展、易复用、少修改的原则。

评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值