当系统中的具体产品类不断增多时候,可能会出现要求工厂类根据不同条件创建不同实例的需求.这种对条件的判断和对具体产品类型的判断交错在一起,很难避免模块功能的蔓延,对系统的维护和扩展非常不利;
这些缺点在工厂方法模式中得到了一定的克服。
工厂方法模式:定义一个创建产品对象的工厂接口,让子类决定实例化哪一种实例对象,将创建实例对象的工作放在具体子类工厂,核心的工厂类将不再负责具体产品的的创建,也就是一个抽象工厂定义了一个创建产品的接口,至于具体创建哪种产品它不知道,产品的实例化被放到了具体的工厂子类中。
下面我们以一个生活中的例子来阐述这个模式:假设小明是个富二代,大学毕业后拿了老爸的50万投资了一个小吃店,卖炸鸡汉堡之类的小吃,他的目标很宏大,要把小吃店干成KFC那样的连锁店,目标很宏大,路要一步一步走,刚开始的小店,模式很简单,客人来了之后根据菜单上的品种来点餐,点了之后小明现场做,说到这,大家是不是很快想起来了,这个不就是简单工厂模式吗,小明的这家店就是一个简单的工厂,客户是具体的消费者,来了之后客户不需要知道店里面的小吃具体怎么做的,有什么配方,只需要跟小明说一声。模式很简单,适合单店。
小明很勤劳,加上配方正宗,生意异常火爆,不多久就赚了不少钱,开了不少分店,但是问题也慢慢凸显,产品品种单一,花式不多,每一次上新品,每个点都要重新引进设备,人员培训,修改菜单宣传页,代价很大。小明这时候痛定思痛决定引进中央厨房,由中央厨房统一把食品的胚胎,原型做出来,统一配送到每个店铺,店铺只要做最后的加工,装饰,不同花样的产品就能方便快捷的到客户的手中,一举解决了所有问题,小明的连锁梦想越来越接近现实了。
// 产品接口,对应例子里面的产品坯胎,初加工产品
interface IProduct {
public void create();
}
// 具体的产品实现类 。汉堡,炸鸡,饮料
public class ProductA implements IProduct {
public void create() {
System.out.println("ConcreteProductA is Coming!!");
}
}
public class ProductB implements IProduct {
public void create() {
System.out.println("ProductB is Coming!!");
}
}
// 抽象的工厂类,定义了其子类必须实现的createProduct()方法 ,对应就是中央厨房
public abstract class Factory {
public abstract <T extends IProduct> T createProduct(Class<T> c);
}
//具体工厂类,对应一个个分店
public class ConcreteFactory extends Factory {
public <T extends IProduct> T createProduct(Class<T> c) {
T product = null;
try {
product = (T) Class.forName(c.getName()).newInstance();
} catch (Exception e) {
e.printStackTrace();
}
return product;
}
}
public class Customer{
public static void main(String[] args) {
//创建一个具体分店 ,这边也可以再加上另外一家分店
Factory factory = new ConcreteFactory();
//根据参数中具体产品的.class名称来决定创建的产品类型
IProduct product01 = factory.createProduct(ConcreteProductA.class);
IProduct product02 = factory.createProduct(ConcreteProductB.class);
product01.create();
product02.create();
}
}
上面的例子就结束了,以后中央厨房负责创建初加工的各种产品,然后每一家分店在这个基础上做个简单的加工,消费者就能方便快捷的吃到美味可口的美食了。