您的位置:首页 > 其它

设计模式之四:工厂模式(简单工厂、工厂方法、抽象工厂)

2013-05-25 16:04 781 查看
《Head First设计模式》第四章学习笔记

一、设计原则

要依赖抽象,不要依赖具体类。当你直接实例化一个对象时,就是在依赖它的具体类。

如果有一个不像是会改变的类,那么在代码中直接实例化具体类也就没什么大碍。

二、工厂模式

<一>、简单工厂模式

简单工厂模式:就是由一个类的方法(可以是静态方法)根据传入的参数,决定创建出哪一种具体产品类的实例。

简单工厂其实不是一个设计模式,反而比较像是一种编程习惯。类图如下:



<二>、工厂方法模式

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

带参数的工厂方法,称为参数化工厂方法,它可以根据传入的参数创建不同的对象。(不推荐参数化的工厂方法,因为会导致每个具体的方法实现,跟简单工厂是一样的)

工厂方法类图如下:



抽象工厂类Creator,定义了一个创建对象的抽象方法factoryMethod,在每个具体的工厂类中,实现该方法,创建具体的产品实例。

<三>、抽象工厂模式

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



抽象工厂的每个方法,实际上看起来就是工厂方法。

三、例子

1、简单工厂模式的例子

披萨店做披萨,Pizza为披萨抽象类,CheesPizza、GreekPizza、ClamPizza等为具体的Pizza实现类。现在借助简单工厂模式,根据不同的参数,创建不同的披萨。代码片段如下:

简单工厂SimplePizzaFactory类:

public class SimplePizzaFactory {
public static Pizza createPizza(String type) {
Pizza pizza = null;
if ("cheese".equals(type)) {
pizza = new CheesePizza();
} else if ("greek".equals(type)) {
pizza = new GreekPizza();
} else if ("clam".equals(type)) {
pizza = new ClamPizza();
}
return pizza;
}
}

PizzaStore类(客户端):

public class PizzaStore {
public Pizza orderPizza(String type) {
Pizza pizza = SimplePizzaFactory.createPizza(type);
pizza.prepare();
pizza.bake();
pizza.cut();
pizza.box();
return pizza;
}
}

测试代码:

public class PizzaTestDrive {
public static void main(String[] args) {
PizzaStore store = new PizzaStore();
Pizza pizza = store.orderPizza("cheese");
System.out.println("Ethan ordered a " + pizza.getName());
pizza = store.orderPizza("clam");
System.out.println("Joel ordered a " + pizza.getName());
}
}


2、工厂方法模式的例子

不同地区的披萨店,做的Pizza不一样。在工厂方法模式中,PizzaStore负责定义创建Pizza的方法,但方法的具体实现,由各个地区的披萨店来实现,并负责创建具体的Pizza。

抽象的工厂类:

public abstract class PizzaStore {
public Pizza orderPizza(String type) {
Pizza pizza = createPizza(type);
pizza.prepare();
pizza.bake();
pizza.cut();
pizza.box();
return pizza;
}
// 抽象的方法,由各个子类来实现。此处用的是参数化的工厂方法
protected abstract Pizza createPizza(String type);
}

具体的工厂类:

public class ChicagoPizzaStore extends PizzaStore {
protected Pizza createPizza(String type) {
if ("cheese".equals(type)) {
return new ChicagoStyleCheesePizza();
}
return null;
}
}

具体的工厂类:

public class NYPizzaStore extends PizzaStore {
protected Pizza createPizza(String type) {
if ("cheese".equals(type)) {
return new NYStyleCheesePizza();
}
return null;
}
}

测试例子:

public class PizzaTestDrive {
public static void main(String[] args) {
PizzaStore nyStore = new NYPizzaStore();
PizzaStore chicagoStore = new ChicagoPizzaStore();
Pizza pizza = nyStore.orderPizza("cheese");
System.out.println("Ethan ordered a " + pizza.getName());
pizza = chicagoStore.orderPizza("cheese");
System.out.println("Joel ordered a " + pizza.getName());
}
}

3、抽象工厂的例子

4、JDK中工厂模式的应用

简单工厂:

java.lang.Boolean#valueOf(String)
java.lang.reflect.Proxy#newProxyInstance()
java.lang.Class#forName()
java.lang.Class#newInstance()

工厂方法:

java.lang.Object#toString()

四、小结

1、在简单工厂模式中,一个工厂类处于对产品类实例化的中心位置上,它知道每一个产品,它决定哪一个产品类应当被实例化。这个模式的优点是允许客户端相对独立于产品创建的过程,并且在系统引入新产品的时候无需修改客户端,也就是说,它在某种程度上支持“开--闭”原则。但这个模式的缺点是对“开--闭”原则的支持力度不够,因为如果有新的产品加入到系统中去,就需要修改工厂类,将必要的逻辑加入到工厂类中。

2、在工厂方法模式中,核心的工厂类不再负责所有的产品的创建,而是将具体创建的工作交给子类去做。工厂方法模式退化后可以变得很像简单工厂模式:设想如果非常确定一个系统只需要一个具体工厂类,那么就不妨把抽象工厂给合并到具体的工厂类中。由于使用了多态性,工厂方法模式保持了简单工厂模式的优点,而且克服了它的缺点。

参考资料

1、《Head First设计模式》

2、《java与模式》

3、JDK里的设计模式
内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息
标签: 
相关文章推荐