关闭

跟着实例学习设计模式(2)-静态工厂(创建型)

标签: 设计模式实例设计对象
369人阅读 评论(0) 收藏 举报
分类:

静态工厂设计模式是创建型设计模式。

设计意图:实例化出我们需要的类对象,这些对象可以实现不同的功能,也可能只实现一个功能!

类图关系:

通过类图关系我们可以看到静态工厂负责创建OperationFather类的对象,我们来看一下实例代码。

我们是想实现一个计算器,计算器的功能暂时有加法、减法功能,以后可能随时增加新的功能如乘法、除法等。如果使用一般的做法,实际上我们写一个类就可以实现。

package com.factory.staticfactory;

/**
 * @author gaoxu
 * 实践出真知!
 */
public class Operation {

	/**
	 * @author gaoxu
	 * @param args
	 */
	public static void main(String[] args) {
		
		//定义变量
		//获取传入的参数
		//判断传入的计算类型
		if("".equals("+")){
			
		}else if("".equals("-")){
			
		}
		
		//输出计算结果
	}

}

大家看一下这个实现,基本的功能肯定是实现了,但是好像扩展性很差,如果我们需要加一个乘法,那只能修改if语句增加条件,如果不断增加新的计算功能,那么这个类就不能维护了,什么样的方式才能让代码漂亮,功能扩展灵活,维护方便呢?

面向对象编程可以实现,首先我们需要封装计算的实现、其次我们需要解耦数据获取设置与计算的逻辑、还要考虑增加功能方便快捷。这几点实现了,我们也就可以实现代码漂亮,功能扩展灵活、代码维护方便的几个需求了。

首先我们把计算进行封装,我们把数据处理放到父类中把计算放到不同的子类中。

package com.factory.staticfactory;

/**
 * @author gaoxu
 * 实践出真知!
 */
public class OperationFather {
	
	double numA = 0;
	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 double getResult() {
		// TODO Auto-generated method stub
		return 0;
	}

}

package com.factory.staticfactory;

/**
 * @author gaoxu
 * 实践出真知!加法
 */
public class OperationAdd extends OperationFather{
	@Override
	public double getResult(){
		double result=0;
		result = numA +numB;
		return result;
	}
}

package com.factory.staticfactory;

/**
 * @author gaoxu
 * 实践出真知!减法
 */
public class OperationSub extends OperationFather{
	@Override
	public double getResult(){
		double result=0;
		result = numA -numB;
		return result;
	}
}

我们看到上面三个类,有一个父类负责设置数据,并提供了计算的方法。下面的两个子类一个加法类、一个减法类,它们各个实现自己的业务逻辑(重写了父类的方法),这样做的好处是,每增加一个功能点都不会修改到别的功能的代码。

我们现在做的就是要根据用户的需要创建出不同的功能产品来,这时可以使用静态工厂了,来看工厂类的实现。

package com.factory.staticfactory;

/**
 * @author gaoxu
 * 实践出真知!
 */
public class StaticFactory {
	
	public static OperationFather getOperationByType(String type){
		
		OperationFather operation = null;
		if("+".equals(type)){
			operation = new OperationAdd();
		}else if("-".equals(type)){
			operation = new OperationSub();
		}
		return operation;
		
	}

}

大家看到了,我们把执行什么操作的判断挪到了工厂的方法里了,我们使用工厂封装了创建对象的过程,静态方法的功能就是根据传入的参数来创建不同功能的实例对象。创建对象也实现了,那么再来看如何调用吧!

package com.factory.staticfactory;

/**
 * @author gaoxu
 * 实践出真知!
 */
public class StaticFactoryClient {
	
	public static void main(String[] para){
		StaticFactory factory = new StaticFactory();
		String operatType = "-";
		OperationFather operate = factory.getOperationByType(operatType);
		if(operate!=null){
			operate.setNumA(1);
			operate.setNumB(5);
			System.out.println("两数相"+operatType+",结果如下:"+operate.getResult());
		}else{
			System.out.println("操作类创建失败!");
		}
		
		
	}

}

我们可以看到客户端的代码也相当简洁,而且可以很明确知道这个类要干什么,根本不用关心是由谁来干。(这一点由功能来决定要哪个对象来干)

由以上代码我们可以看出:

客户端--工厂类--计算实现类

这三块的关系,各自有自己要做的业务,耦合性极低,功能扩展性增强,如果增加新的功能只需要实现一个计算类,修改工厂静态方法的判断逻辑,由此我们实现了代码简洁、功能扩展灵活、维护方便的需求。

什么场景下适合使用工厂模式创建:

1:对象需要很复杂的创建过程,在客户端创见过于负责。

2:不同的对象可以实现不同功能,需要有很强的扩展需求时。

我们把对象的创建交给工厂类来实现,有如下优点(相对于不使用工厂的实现来说):

1:创建产品的过程被封装起来,通过必要的逻辑判断实现动态实例化相关的类对象,精简客户端的代码,去除了客户端与具体产品的依赖。

2:可以有效解耦,客户端和具体实现功能的类之间没有直接的创建耦合关系。

3:可以很好的复用功能,灵活的添加功能,添加产品只需要修改工厂逻辑和加产品实现类。


0
0

猜你在找
【直播】机器学习&数据挖掘7周实训--韦玮
【套餐】系统集成项目管理工程师顺利通关--徐朋
【直播】3小时掌握Docker最佳实战-徐西宁
【套餐】机器学习系列套餐(算法+实战)--唐宇迪
【直播】计算机视觉原理及实战--屈教授
【套餐】微信订阅号+服务号Java版 v2.0--翟东平
【直播】机器学习之矩阵--黄博士
【套餐】微信订阅号+服务号Java版 v2.0--翟东平
【直播】机器学习之凸优化--马博士
【套餐】Javascript 设计模式实战--曾亮
查看评论
* 以上用户言论只代表其个人观点,不代表CSDN网站的观点或立场
    个人资料
    • 访问:35853次
    • 积分:771
    • 等级:
    • 排名:千里之外
    • 原创:40篇
    • 转载:1篇
    • 译文:0篇
    • 评论:8条
    最新评论