工厂模式(Factory Pattern)之简单工厂,工厂方法模式(Factory Method Pattern),抽象工厂模式(Abstract Factory Pattern)

《Head First》介绍了工厂模式的3个内容:

一、简单工厂

简单工厂并非一个模式,反而像是一个编程习惯,其本质是抽出了对象复杂多变的实例化过程到另外一个单独的类,以保证其他代码的不变。

通常是实例化的对象是拥有多类型的情况:

案例:可以用实例化水果派的例子

public class PatternDemo {
	
	public static void main(String[] args) {
		SimplePieFactory factory = new SimplePieFactory();
		
		Pie pie = factory.createPie(SimplePieFactory.TYPE_APPLE);
		System.out.println("Pie: " + pie.getName());
		
		pie = factory.createPie(SimplePieFactory.TYPE_BANANA);
		System.out.println("Pie: " + pie.getName());
		
		pie = factory.createPie(SimplePieFactory.TYPE_PINEAPPLE);
		System.out.println("Pie: " + pie.getName());
	}
}

public class SimplePieFactory {
	
	public static final int TYPE_APPLE = 0;
	public static final int TYPE_BANANA = 1;
	public static final int TYPE_PINEAPPLE = 2;
	
	public SimplePieFactory() {
		
	}
	
	public Pie createPie(int type) {
		Pie pie = null;
		if (type == TYPE_APPLE) {
			pie = new ApplePie();
		} else if (type == TYPE_BANANA) {
			pie = new BananaPie();
		} else if (type == TYPE_PINEAPPLE) {
			pie = new PineapplePie();
		} 
		return pie;
	}
}

public abstract class Pie {

	public Pie() {}

	public abstract String getName();
}

public class ApplePie extends Pie {

	@Override
	public String getName() {
		return "Apple Pie";
	}
}

另外两个类似。


二、工厂方法模式

工厂方法模式:定义了一个创建对象的接口, 但由子类决定要实例化的类是哪一个。工厂方法让类把实例化推迟到子类

其本质是虚基类中存在统一的操作或者处理对象实例的方法,但是实例化生成对象实例的方法是抽象方法,需要子类通过继承后实现

为的是满足不同的需求下的实例化对象不同的情况

案例:同样是水果派,但是A店改进工艺后有了AStyle的Pie,同样的B店也有了BStyle的,但是制作过程是一样的,只是馅料会有A和B自己的不同

因此只要让AB两家各自实现抽象基类里的createPie方法就可以有他们各自的特色,然后再用抽象基类里面统一的制作过程

工厂模式(Factory Pattern)之简单工厂,工厂方法模式(Factory Method Pattern),抽象工厂模式(Abstract Factory Pattern)_第1张图片


代码:

public class PatternDemo {
	
	public static void main(String[] args) {
		AStore aStore = new AStore();
		aStore.cooking();
		
		BStore bStore = new BStore();
		bStore.cooking();
	}
}

public abstract class Store {

	public void cooking() {
		System.out.println("cooking......");
		Pie pie = null;
		pie = createPie();
		System.out.println("Pie: " + pie.getName());
		System.out.println("cooked......");
	}
	
	protected abstract Pie createPie();
}

public class AStore extends Store {

	@Override
	protected Pie createPie() {
		return new AStylePie();
	}

}

public class AStylePie extends Pie {

	@Override
	public String getName() {
		return "A StyleP ie";
	}

}

B的代码类似


设计原理6:要依赖抽象,不要依赖具体类(其作用是为了实现“依赖倒置原则”)


如何理解呢?

1、如果不用工厂方法模式,那么我们就用不到Pie的抽象类,然后我们会分别去根据要求用很多if-else去实例化各种各样的Pie,这个时候可以理解为Store是依赖于各种各样具体的Pie的。

2、有了抽象Pie类后,Store会依赖于抽象的Pie,而这个时候所有的具体Pie会依赖于抽象的Pie,这样就可以理解为倒置了


如何遵循“依赖倒置原则”,只是尽了遵循,因为绝对是不可能的

1、变量不可以持有具体类的引用

2、不要让类派生自具体类

3、不要覆盖基类(主要是抽象的基类)中已实现的方法


三、抽象工厂模式

抽象工厂模式:提供一个接口,用于创建相关或依赖对象的家族,而不需要明确指定具体类

可以提现这个的案例就是水果派的原料上,工厂模式(Factory Pattern)之简单工厂,工厂方法模式(Factory Method Pattern),抽象工厂模式(Abstract Factory Pattern)_第2张图片

A的代码:

public interface PieIngredientFactory {

	public Ingredient createIngredient();
}

public class APieIngredientFactory implements PieIngredientFactory {

	@Override
	public Ingredient createIngredient() {
		return new AIngredient();
	}
}

public class AStylePie extends Pie {
	
	private PieIngredientFactory factory;
	
	public AStylePie(PieIngredientFactory factory) {
		this.factory = factory;
		prepare();
	}

	@Override
	public String getName() {
		return "A StyleP Pie with " + getIngredient().getIngredientName();
	}

	@Override
	public void prepare() {
		setIngredient(factory.createIngredient());
	}
}

关键在于prepare()方法中,无论是什么工厂,都是可以轻易重用的, 而Pie根本不用管是什么工厂

你可能感兴趣的:(Design,Pattern)