05 工厂方法模式(Factory Method Pattern)

本文深入探讨了工厂模式在软件设计中的应用,包括简单工厂模式和工厂方法模式。通过具体示例,详细介绍了这两种模式的实现方式、适用场景及各自的优缺点。

引入简单工厂模式,再引入工厂方法模式。

代码示例如下:

package factoryPattern;

/**
 * 简单工厂模式的例程
 * @Package       factoryPattern
 * @Title:        SimplePattern.java
 * @Company:      $
 * @author        BurgessLee 
 * @date          2018年10月11日-下午1:10:29
 * @Description:  $
 */
public class SimplePattern {
	
	//测试例程
	public static void main(String[] args) {
		for(int i = 0; i < 3; i++){
			Tea tea = MakeTea.makeTea(i);
		}
	}
	
}

abstract class Tea{
	public abstract void addMilk();
	public abstract void addTea();
	public abstract void addOther();
	public abstract void doPackage();
}

class ZhenZhuTea extends Tea{

	@Override
	public void addMilk() {
		System.out.println("加了一包奶");
	}

	@Override
	public void addTea() {
		System.out.println("加了一包茶");
	}

	@Override
	public void addOther() {
		System.out.println("加了一把珍珠");
	}

	@Override
	public void doPackage() {
		System.out.println("用杯子打包");
	}
	
}

class YeGuoTea extends Tea{
	
	@Override
	public void addMilk() {
		System.out.println("加了一包奶");
	}

	@Override
	public void addTea() {
		System.out.println("加了一包茶");
	}

	@Override
	public void addOther() {
		System.out.println("加了一把椰果");
	}

	@Override
	public void doPackage() {
		System.out.println("用杯子打包");
	}
}

class MakeTea{
	static Tea makeTea(int type){
		System.out.println("*********************************");
		Tea tea = type == 0 ? new ZhenZhuTea() : new YeGuoTea();
		tea.addMilk();
		tea.addTea();
		tea.addOther();
		tea.doPackage();
		return tea;
	}
}

输出结果如下:

*********************************
加了一包奶
加了一包茶
加了一把珍珠
用杯子打包
*********************************
加了一包奶
加了一包茶
加了一把椰果
用杯子打包
*********************************
加了一包奶
加了一包茶
加了一把椰果
用杯子打包

这个简单的例子就是 简单工厂模式 ,三个角色:

  • Product(抽象产品):封装了各种产品对象的公有方法,比如这里的Tea;
  • ConcreteProduct(具体产品):抽象产品的具体化,比如这里的珍珠和椰果Tea;
  • Factory(工厂):实现创建所有产品实例的内部逻辑,比如这里的Me;

继续加入新的代码,代码示例如下:

package factoryPattern;

import java.util.Random;

/**
 * 简单工厂模式的例程
 * @Package       factoryPattern
 * @Title:        SimplePattern.java
 * @Company:      $
 * @author        BurgessLee 
 * @date          2018年10月11日-下午1:10:29
 * @Description:  $
 */
public class SimplePattern {
	
	//测试例程
	public static void main(String[] args) {
		ZhenzhuMakeTea zhenZhu = new ZhenzhuMakeTea();
		YeGuoMakeTea yeGuo = new YeGuoMakeTea();
		for(int i = 0; i < 3; i++){
			Tea tea = buyTea() == 0 ? zhenZhu.makeTea() : yeGuo.makeTea();
		}
	}
	
	public static int buyTea(){
		return new Random().nextInt(2);
	}
	
}

abstract class Tea{
	public abstract void addMilk();
	public abstract void addTea();
	public abstract void addOther();
	public abstract void doPackage();
}

class ZhenZhuTea extends Tea{

	@Override
	public void addMilk() {
		System.out.println("加了一包奶");
	}

	@Override
	public void addTea() {
		System.out.println("加了一包茶");
	}

	@Override
	public void addOther() {
		System.out.println("加了一把珍珠");
	}

	@Override
	public void doPackage() {
		System.out.println("用杯子打包");
	}
	
}

class YeGuoTea extends Tea{
	
	@Override
	public void addMilk() {
		System.out.println("加了一包奶");
	}

	@Override
	public void addTea() {
		System.out.println("加了一包茶");
	}

	@Override
	public void addOther() {
		System.out.println("加了一把椰果");
	}

	@Override
	public void doPackage() {
		System.out.println("用杯子打包");
	}
}

abstract class MakeTeaForMorePeople{
	abstract Tea makeTea();
}

class ZhenzhuMakeTea extends MakeTeaForMorePeople{

	@Override
	Tea makeTea() {
		System.out.println("珍珠加入了自己做茶的特色");
		Tea tea = new ZhenZhuTea();
		tea.addMilk();
		tea.addTea();
		tea.addMilk();
		tea.doPackage();
		return tea;
	}
	
}

class YeGuoMakeTea extends MakeTeaForMorePeople{

	@Override
	Tea makeTea() {
		System.out.println("椰果加入了自己做茶的特色");
		Tea tea = new YeGuoTea();
		tea.addMilk();
		tea.addTea();
		tea.addMilk();
		tea.doPackage();
		return tea;
	}
	
}

打印结果:

珍珠加入了自己做茶的特色
加了一包奶
加了一包茶
加了一包奶
用杯子打包
珍珠加入了自己做茶的特色
加了一包奶
加了一包茶
加了一包奶
用杯子打包
珍珠加入了自己做茶的特色
加了一包奶
加了一包茶
加了一包奶
用杯子打包

工厂方法模式,也就是在简单工厂基础上, 把工厂创建不同产品的内部逻辑抽取出来,生成一个 抽象工厂,然后创建具体的工厂类,来产生不同的产品!

UML类图如下

总结

简单工厂模式由三部分组成,而工厂方法模式则是将工厂的生产产品 的逻辑给抽取出来,然后使用不同的具体工厂实现类来生产不同的 产品。

适用场景

简单工厂模式

  • 工厂类负责创建的对象比较少;
  • 客户只知道传入工厂类的参数,对于如何创建对象(逻辑)不关心;

工厂方法模式

  • 复杂对象生成;
  • 当需要系统有比较好的扩展性时,可以考虑工厂模式,不同的产品用不同的实现工厂来组装;

优缺点

简单工厂模式

  • 工厂类负责所有对象的创建逻辑,该类出问题整个系统挂掉;
  • 系统扩展困难,一旦添加新产品就不得不修改工厂逻辑;
  • 简单工厂模式由于使用了静态工厂方法,所以工厂角色无法形成基于继承的等级结构;

工厂方法模式

  • 在添加新产品时,需要编写新的具体产品类,而且还要提供与之对应的具体工厂类,系统中类的个数将成对增加,在一定程度上增加了系统的复杂度,有更多的类需要编译和运行,会给系统带来一些额外的开销。
  • 由于考虑到系统的可扩展性,需要引入抽象层,在客户端代码中均使用抽象层进行定义,增加了系统的抽象性和理解难度

附:通过反射简洁生产过程

上面通过一个type来区分要生产的是珍珠还是椰果奶茶,显得有些繁琐, 其实可以通过反射,直接传入产品的类类型,即可生成对应产品,实现 示例代码如下:


abstract class TeaS{
	public abstract <T extends Tea> T makeTeaByOtherMethod(Class<T> clz);
}

class TeaMe extends TeaS{

	@Override
	public <T extends Tea> T makeTeaByOtherMethod(Class<T> clz) {
		System.out.println("通过反射实现对应的实现");
		Tea tea = null;
		try {
			tea = (Tea) Class.forName(clz.getName()).newInstance();
			tea.addMilk();
			tea.addTea();
			tea.addOther();
			tea.doPackage();
		} catch (Exception e) {
			e.printStackTrace();
		}
		return (T)tea;
	}
	
}

测试方法:

//通过反射进行区分获取对应的方法
TeaMe tea = new TeaMe();
tea.makeTeaByOtherMethod(ZhenZhuTea.class);
tea.makeTeaByOtherMethod(YeGuoTea.class);

打印结果:

通过反射实现对应的实现
加了一包奶
加了一包茶
加了一把珍珠
用杯子打包
通过反射实现对应的实现
加了一包奶
加了一包茶
加了一把椰果
用杯子打包

 

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值