工厂方法模式(Factory Method)——Java设计模式(二)

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

前言

在上一篇简单工厂模式(Factory)——Java设计模式中,提出简单工厂模式存在以下几个缺点:

  1. 工厂类集中了所有具体产品类的创建逻辑,一旦这个工厂类不能正常工作,整个系统将会受到影响。
  2. 违背“开闭原则”,一旦添加新产品,就必须修改工厂类。

为了解决上述问题,由简单工厂模式衍生出一种新的设计模式,即工厂方法模式(Factory Method)。

工厂方法模式简介

工厂方法模式:定义一个创建产品对象的工厂接口,将实际创建工作推迟到子类当中。核心工厂类不再负责产品的创建,这样核心类成为了一个抽象工厂角色,仅负责具体工厂子类必须实现的接口。这样进一步抽象化的好处是使得工厂方法模式可以使系统在不修改具体工厂角色的情况下引进新的产品。

工厂方法模式对简单工厂模式进行了抽象。有一个抽象的Factory类(可以是抽象类或接口),这个类将不再负责具体的产品生产,而是只制定一些规范,具体的生产工作由其子类去完成。在这个模式中,一个抽象工厂对应一个抽象产品,一个具体工厂对应一个具体产品,这个具体的工厂就负责生产对应的产品。

分类:创建型模式

核心精神是:封装类中不变的部分,提取其中个性化善变的部分为独立类,通过依赖注入以达到解耦、复用和方便后期维护拓展的目的。

核心结构有4个角色:抽象工厂、具体工厂、抽象产品、具体产品。

角色结构

抽象工厂(Creator)角色:工厂方法模式的核心,与应用程序无关。任何在模式中创建对象的工厂类必须实现这个接口。

具体工厂(Concrete Creator)角色:抽象工厂接口的具体实现类。包含与应用程序密切相关的逻辑,通过调用来创建产品对象。

抽象产品(Product)角色:产品对象的共同父类或共同拥有的接口。

具体产品(Concrete Product)角色:抽象产品角色的具体实现类。具体产品由对应的具体工厂创建。

实现方式


具体实现例子:

制作身份证(ID卡)。


步骤一:创建抽象产品类。
/**
 * 抽象产品
 * @author Administrator
 *
 */
public abstract class Product {
	public abstract void use();
}
步骤二:创建抽象工厂类。
/**
 * 抽象工厂
 * 作用:去生产产品实例。
 * @author Administrator
 *
 */
public abstract class Factory {
	
	public final Product create(String owner) {
		Product product = createProduct(owner);
		registerProduct(product);
		
		return product;
	}
	
	protected abstract Product createProduct(String owner);
	protected abstract void registerProduct(Product product);
}
步骤三:创建具体产品类。
/**
 * 实现抽象产品的具体产品类。
 * @author Administrator
 *
 */
public class IDCard extends Product {
	private String owner;
	
	public IDCard(String owner) {
		System.out.println("制作" + owner + "的ID卡。");
		this.owner = owner;
	}
	
	@Override
	public void use() {
		System.out.println("使用" + owner + "的ID卡。");
	}
	
	public String getOwner() {
		return owner;
	}
}
步骤四:创建具体工厂类。
/**
 * 实现抽象工厂的具体工厂类。
 * @author Administrator
 *
 */
public class IDCardFactory extends Factory {
	private List<Object> owners = new ArrayList<Object>();
	
	@Override
	protected Product createProduct(String owner) {
		return new IDCard(owner);
	}

	@Override
	protected void registerProduct(Product product) {
		this.owners.add(((IDCard)product).getOwner());
	}

	public List<Object> getOwners() {
		return owners;
	}
}
步骤五:测试。
public class Main {

	public static void main(String[] args) {
		Factory factory = new IDCardFactory();
		
		Product card1 = factory.create("小明");
		Product card2 = factory.create("小红");
		Product card3 = factory.create("小刚");
		card1.use();
		card2.use();
		card3.use();
	}

}
步骤六:验证输出。
制作小明的ID卡。
制作小红的ID卡。
制作小刚的ID卡。
使用小明的ID卡。
使用小红的ID卡。

使用场合

  • 第一种情况是对于某个产品,调用者清楚地知道应该使用哪个具体工厂服务,实例化该具体工厂,生产出具体的产品来。Java Collection中的iterator() 方法即属于这种情况。
  • 第二种情况,只是需要一种产品,而不想知道也不需要知道究竟是哪个工厂为生产的,即最终选用哪个具体工厂的决定权在生产者一方,它们根据当前系统的情况来实例化一个具体的工厂返回给使用者,而这个决策过程这对于使用者来说是透明的。

阅读更多

没有更多推荐了,返回首页