创建型(四)—抽象工厂模式

1、介绍

Provide an interface for creating families of related or dependent objects without specifying their concrete classes.

意思是:为创建一组相关或相互依赖的对象提供一个接口,而且无需指定它们的具体类。

2、使用场景

当一个对象族(或一组没有任何关系的对象)都有相同的约束,则可以使用抽象工厂模式。例如,应用需涉及不同的操作系统时,若是需要在三个不同的平台(Windows、Linux、Android)上运行,可以通过抽象工厂模式屏蔽掉操作系统对应用的影响。

3、UML类图


角色介绍:

  1. AbstactFactory:是工厂模式的核心,与应用系统无关,具有的工厂类必须实现这个接口。
  2. ConcreteFactory:实现了抽象工厂接口,含所有选择合适产品对象的逻辑,并且受到应有程序的调用以创建产品对象
  3. Product:负责定义产品的共性
  4. ConcreteProduct:实现抽象产品角色所声明的接口

4、示例

在上一章阐述了车厂生产车,但是车厂发现一个问题,虽然Q1和Q2都是一个车系,但两者的区别很大,例如:Q1轮胎是普通的,发动机是国产的;Q2轮胎是越野轮胎,发动机是进口的。这就可以将抽象工厂应用到其中。

抽象车厂类

public abstract class CarFactory {
	/**
	 * 生产轮胎
	 * @return 轮胎
	 */
	public abstract ITire createTire();
	/**
	 * 生产发动机
	 * @return 发动机
	 */
	public abstract IEngine createEngine();

}

具体Q1、Q2工厂类

public class Q1Factory extends CarFactory{

	@Override
	public ITire createTire() {
		return new NormalTire();
	}

	@Override
	public IEngine createEngine() {
		return new DomesticEngine();
	}
}
public class Q2Factory extends CarFactory{

	@Override
	public ITire createTire() {
		return new SUVTire();
	}

	@Override
	public IEngine createEngine() {
		return new ImportEngine();
	}

}

为每一种零件产品定义一个接口,轮胎具体有普通和越野之分,发动机具体有国产和进口之分。

轮胎相关类如下:

public interface ITire {
	/**
	 * 轮胎
	 */
	public abstract void tire();
}
public class NormalTire implements ITire {
	@Override
	public void tire() {
		System.out.println("生产普通轮胎");
	}
}
public class SUVTire implements ITire {
	@Override
	public void tire() {
		System.out.println("生产越野轮胎");
	}
}

发动机相关类如下:

public interface IEngine {
	/**
	 * 引擎
	 */
	public abstract void engine();

}
public class DomesticEngine implements IEngine{
	@Override
	public void engine() {
		System.out.println("生产国产引擎");	
	}
}
public class ImportEngine implements IEngine{
	@Override
	public void engine() {
		System.out.println("生产进口引擎");	
	}
}

最后,我们在一个Client客户类中模拟

public class Client {
	public static void main(String[] args) {
		System.out.println("Q1生产车间:");
		CarFactory factoryQ1 = new Q1Factory();
		factoryQ1.createTire().tire();
		factoryQ1.createEngine().engine();
		
		System.out.println("Q2生产车间:");
		CarFactory factoryQ2= new Q2Factory();
		factoryQ2.createTire().tire();
		factoryQ2.createEngine().engine();
	}
}

输出结果如下:

Q1生产车间:
生产普通轮胎
生产国产引擎
Q2生产车间:
生产越野轮胎
生产进口引擎

5、总结

优点:

  1. 分离接口与实现,客户端使用抽象工厂来创建具体的对象,无需关心具体实现,只是面向产品的接口编程而已,使其从具体的产品实现中解耦,同时基于接口与实现的分离,使得切换产品类时灵活容易

缺点:

  1. 类文件的爆炸性增加。
  2. 不太容易扩展新的产品类,因为增加一个产品类就需要修改抽象工厂,所有的具体工厂类均会修改。

猜你喜欢

转载自blog.csdn.net/zcjxaiofeizhu/article/details/80650775