您的位置:首页 > 编程语言 > Java开发

Java 工厂方法模式

2017-06-28 21:47 295 查看
接上篇 Java简单工厂模式

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

工厂方法模式UML图



Product:抽象的产品接口,所有的产品必须实现这个共同的接口。这样一来,使用这些产品的类就可以引用这个接口,而不是具体类。

ContreteProcut:具体的产品类,实现Product接口。

Creater:抽象的创建者,定义了抽象方法factoryMethod( )来创建Product,所有的子类都要实现这个抽象方法。并包含了其他操作产品类的方法otherMethod( )。

ContreteCreator:具体的创建者,实现了factoryMethod( ),以实际制造产品。

披萨店经营的很好,开始搞加盟店了(这不是KFC吗)。身为总公司,你希望加盟店都使用总店经过时间考验的代码。就是说PizzaStore的代码不变。

理想很美好但是现实很残酷啊,每家加盟店可能想要做出有自己特色的披萨。披萨的创建和制作流程都会有差异,那该怎么办呢?



答案就是今天的主题工厂方法模式

首先看看PizzaStore所做的改变

//现在PizzaStore是抽象的
public abstract class PizzaStore {

//继承的子类使用同一套点披萨的流程,这个方法可以使final的
public Pizza orderPozza(String type) {
Pizza pizza = createPizza(type);
pizza.prepare();
pizza.bake();
pizza.cut();
pizza.box();
return pizza;
}

//创建Pizza的方法从工厂中移回PizzaStore,这个方法是抽象的
protected abstract Pizza createPizza(String type);
}


现在已经有了一个PizzaStore作为超类,让每个加盟店XXXPizzaStore都继承这个PizzaStore,并实现createPizza(String type)方法。当在点披萨时调用createPizza(String type)方法时,就会由具体的实现了createPizza(String type)方法的子类XXXPizzaStore各自决定如何创建披萨。

现在在开始开加盟店了,代码如下

纽约加盟店

public class NYPizzaStore extends PizzaStore {

//实现createPizza(String type)方法
@Override
protected Pizza createPizza(String type) {
if (type.equals("cheese")) {
return new NYStyleCheesePizza();
} else if (type.equals("pepperoni")) {
return new NYStylePepperoniPizza();
} else if (type.equals("clam")) {
return new NYStyleClamPizza();
} else if (type.equals("veggie")) {
return new NYStyleVeggiePizza();
} else {
return null;
}
}
}


上海加盟店

public class SHPizzaStore extends PizzaStore {

//实现createPizza(String type)方法
@Override
protected Pizza createPizza(String type) {
if (type.equals("cheese")) {
return new SHStyleCheesePizza();
} else if (type.equals("pepperoni")) {
return new SHStylePepperoniPizza();
} else if (type.equals("clam")) {
return new SHStyleClamPizza();
} else if (type.equals("veggie")) {
return new SHStyleVeggiePizza();
} else {
return null;
}
}
}


现在和上篇Java简单工厂模式不同的是,原本由一个对象SimplePizzaFactory负责所有具体类(各种披萨),现在通过对PizzaStore做一些改变,变成由一群子类(各个加盟店)负责实例化。

抽象的Pizza类

public  abstract class Pizza {

protected String name;

protected void prepare() {

}

protected void bake() {

}

protected void cut() {

}

protected void box() {

}
}


具体的子类披萨继承Pizza类,可以覆盖任何一个方法,来实现自己的特色披萨。

//一个纽约风味的披萨
public class NYStyleCheesePizza extends Pizza {

@Override
protected void cut() {
System.out.println("纽约披萨切片");
}
}


一个上海风味的披萨。

public class SHStyleCheesePizza extends Pizza {

@Override
protected void cut() {
System.out.println("上海披萨切片");
}
}


现在可以愉快的点披萨吃了。

public class Client {

public static void main(String[] args) {
//在上海吃上海风味的披萨
PizzaStore shStore = new SHPizzaStore();
Pizza shCheesePizza = shStore.orderPizza("cheese");

//在纽约吃纽约风味的披萨
PizzaStore nyStore = new NYPizzaStore();
Pizza nyCheesePizza = nyStore.orderPizza("cheese");
}
}


简单工厂模式和工厂方法模式的区别:简单工厂模式把对象的实例化放在一个工厂里来进行,当我们要加一个具体的产品类的话,就要在工厂里再加一个分支判断,就会修改以前的代码(对修改没有关闭)。而使用工厂方法模式,我们可以直接新建一个创建者,来创建新的产品类即可,以前的代码不用动(对修改关闭)。

注:自己的理解不是很透彻,先记下来,以后完善。

:参考链接

【1】http://blog.csdn.net/itachi85/article/details/52326959

【2】Head First 设计模式
内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息
标签: