您的位置:首页 > 其它

设计模式学习--工厂模式(Factory Pattern)

2013-09-06 16:18 597 查看

http://blog.csdn.net/wwj_748/article/details/8992594



什么是工厂模式?

工厂模式可分为以下三种类型,需要根据不同需求来决定使用哪一种模式:
1. 简单工厂(不是真正意义上的设计模式)
2. 工厂方法(定义了一个创建对象的接口,但由子类决定要实例化的类是哪一个。工厂方法让类实例化推迟到子类)
3. 抽象工厂(提供一个接口,用于创建相关或依赖对象的家族,而不需要明确指定具体类)

面向对象原则:

多用组合,少用继承
针对接口编程,不针对实现编程
为交互对象之间的松耦合而努力
类应该对扩展开放,对修改关闭
依赖抽象,不是依赖具体类(新的原则)

要点:

1. 所有的工厂都是用来封装对象的创建。
2. 简单工厂,虽然不是真正的设计模式,但仍不失为一个简单的方法,可以将客户程序从具体类解耦。
3. 工厂方法使用继承:把对象的创建委托给子类子类实现工厂方法来创建对象。
4. 抽象工厂使用对象组合:对象的创建被实现在工厂接口所暴露出来的方法中。
5. 所有工厂模式都通过减少应用程序和具体类之间的依赖促进松耦合。
6. 工厂方法允许类将实例化延迟到子类进行。
7. 抽象工厂创建相关的对象家族,而不需要依赖它们的具体类。
8. 依赖倒置原则,指导我们避免依赖具体类型,而要尽量依赖抽象。
9. 工厂是很有威力的技巧,帮助我们针对抽象编程,而不要针对具体类编程。

工厂模式应用实例:比萨店

简单工厂实现

看看UML的类图



项目结构:



源代码:

/Pizza.java

[java] view
plaincopyprint?

package pizzas;

import java.util.ArrayList;

/***

* 抽象pizza类

* @author wwj

*

*/

abstract public class Pizza {

String name;

String dough;

String sauce;

ArrayList toppings = new ArrayList();

public String getName() {

return name;

}

@Override

public String toString() {

StringBuffer display = new StringBuffer();

display.append("----" + name + "----\n");

display.append(dough + "\n");

display.append(sauce + "\n");

for(int i = 0; i < toppings.size(); i++) {

display.append((String)toppings.get(i) + "\n");

}

return display.toString();

}

//准备

public void prepare() {

System.out.println("Preparing " + name);

}

//烘烤

public void bake() {

System.out.println("Baking " + name);

}

//切片

public void cut() {

System.out.println("Cutting " + name);

}

//装箱

public void box() {

System.out.println("Boxing " + name);

}

}

[java] view
plaincopyprint?

package pizzas;

/**

* 2013/5/25

* @author wwj

*

*/

public class CheesePizza extends Pizza {

@SuppressWarnings("unchecked")

public CheesePizza() {

name = "Cheese Pizza";

dough = "Regular Crust";

sauce = "Marinara Pizza Sauce";

toppings.add("Fresh Mozzarella");

toppings.add("Parmesan");

}

}

[java] view
plaincopyprint?

package pizzas;

/**

* 2013/5/25

* @author wwj

*

*/

public class ClamPizza extends Pizza {

@SuppressWarnings("unchecked")

public ClamPizza() {

name = "Clam Pizza";

dough = "Thin crust";

sauce = "White garlic sauce";

toppings.add("Clams");

toppings.add("Grated parmesan cheese");

}

}

[java] view
plaincopyprint?

package pizzas;

/**

* 2013/5/25

* @author wwj

*

*/

public class PepperoniPizza extends Pizza {

@SuppressWarnings("unchecked")

public PepperoniPizza() {

name = "Pepperoni Pizza";

dough = "Crust";

sauce = "Marinara sauce";

toppings.add("Sliced Pepperoni");

toppings.add("Sliced Onion");

toppings.add("Grated parmesan cheese");

}

}

[java] view
plaincopyprint?

package pizzas;

/**

* 素食pizza

* @author wwj

*

*/

public class VegglePizza extends Pizza {

@SuppressWarnings("unchecked")

public VegglePizza(){

name = "Veggie Pizza";

dough = "Crust";

sauce = "Marinara sauce";

toppings.add("Shredded mozzarella");

toppings.add("Grated parmesan");

toppings.add("Diced onion");

toppings.add("Sliced mushrooms");

toppings.add("Sliced red pepper");

toppings.add("Sliced black olives");

}

}

/SimplePizzaFactory.java

[java] view
plaincopyprint?

package pizzas;

/**

* 2013/5/27

* @author wwj

* 简单工厂方法

*/

public class SimplePizzaFactory {

public Pizza createPizza(String type) {

Pizza pizza = null;

if(type.equals("cheese")) {

pizza = new CheesePizza();

} else if(type.equals("pepperoni")) {

pizza = new PepperoniPizza();

} else if(type.equals("clam")) {

pizza = new ClamPizza();

} else if(type.equals("veggie")) {

pizza = new VegglePizza();

}

return pizza;

}

}

/PizzaStore

[java] view
plaincopyprint?

package pizzas;

public class PizzaStore {

SimplePizzaFactory factory;

public PizzaStore(SimplePizzaFactory factory) {

this.factory = factory;

}

public Pizza orderPizza(String type) {

Pizza pizza;

pizza = factory.createPizza(type);

pizza.prepare(); //准备

pizza.bake(); //烘烤

pizza.cut(); //切片

pizza.box(); //装盒

return pizza;

}

}

/PizzaTestDriver

[java] view
plaincopyprint?

package pizzas;

/**

* 2013/5/25

* @author wwj

* 简单工厂的测试类

*/

public class PizzaTestDriver {

public static void main(String[] args) {

SimplePizzaFactory factory = new SimplePizzaFactory();

PizzaStore store = new PizzaStore(factory);

Pizza pizza = store.orderPizza("cheese");

System.out.println("We ordered a " + pizza.getName() + "\n");

pizza = store.orderPizza("veggie");

System.out.println("We ordered a " + pizza.getName() + "\n");

}

}

工厂方法模式实现



项目结构:



/Pizza.java

把Pizza声明为抽象的,让所有具体比萨都必须派生自这个类。

[java] view
plaincopyprint?

package pizzafm;

import java.util.ArrayList;

/**

* 2013/5/25

* @author wwj

*

*/

public abstract class Pizza {

String name; //名称

String dough; //面团类型

String sauce; //一套佐料

ArrayList toppings = new ArrayList();

public void prepare() {

System.out.println("Preparing " + name);

System.out.println("Tossing dough...");

System.out.println("Adding sauce...");

System.out.println("Adding toppings: ");

for(int i = 0; i < toppings.size(); i++) {

System.out.println(" " + toppings.get(i));

}

}

public void bake() {

System.out.println("Bake for 25 minutes at 350");

}

public void cut() {

System.out.println("Cutting the pizza into diagonal slices");

}

public void box() {

System.out.println("Place pizza in official PizzaStore box");

}

public String getName() {

return name;

}

}

[java] view
plaincopyprint?

package pizzafm;

/**

* 纽约披萨

* @author wwj

*

*/

public class NYStyleCheesePizza extends Pizza {

public NYStyleCheesePizza() {

name = "NY Style Sauce and Cheese Pizza";

dough = "Thin Crust Dough";

sauce = "Marinara Sauce";

toppings.add("Grated Reggiano Cheese");

}

}

[java] view
plaincopyprint?

package pizzafm;

public class NYStyleClamPizza extends Pizza {

public NYStyleClamPizza() {

name = "NY Style Clam Pizza";

dough = "Thin Crust Dough";

sauce = "Marinara Sauce";

toppings.add("Grated Reggiano Cheese");

toppings.add("Fresh Clams from Long Island Sound");

}

}

[java] view
plaincopyprint?

package pizzafm;

public class NYStylePepperoniPizza extends Pizza {

public NYStylePepperoniPizza() {

name = "NY Style Pepperoni Pizza";

dough = "Thin Crust Dough";

sauce = "Marinara Sauce";

toppings.add("Grated Reggiano Cheese");

toppings.add("Sliced Pepperoni");

toppings.add("Garlic");

toppings.add("Onion");

toppings.add("Mushrooms");

toppings.add("Red Pepper");

}

}

[java] view
plaincopyprint?

package pizzafm;

public class NYStyleVeggiePizza extends Pizza {

public NYStyleVeggiePizza() {

name = "NY Style Veggie Pizza";

dough = "Thin Crust Dough";

sauce = "Marinara Sauce";

toppings.add("Grated Reggiano Cheese");

toppings.add("Garlic");

toppings.add("Onion");

toppings.add("Mushrooms");

toppings.add("Red Pepper");

}

}

[java] view
plaincopyprint?

package pizzafm;

/**

* 芝加哥披萨

* @author wwj

*

*/

public class ChicagoStyleCheesePizza extends Pizza {

public ChicagoStyleCheesePizza() {

name = "Chicago Style Deep Dish Cheese Pizza";

dough = "Extra Thick Crust Dough";

sauce = "Plum Tomato Sauce";

toppings.add("Shredded Mozzarella Cheese");

}

public void cut() {

System.out.println("Cutting the pizza into square slices");

}

}

[java] view
plaincopyprint?

package pizzafm;

public class ChicagoStyleClamPizza extends Pizza {

public ChicagoStyleClamPizza() {

name = "Chicago Style Clam Pizza";

dough = "Extra Thick Crust Dough";

sauce = "Plum Tomato Sauce";

toppings.add("Shredded Mozzarella Cheese");

toppings.add("Frozen Clams from Chesapeake Bay");

}

public void cut() {

System.out.println("Cutting the pizza into square slices");

}

}

[java] view
plaincopyprint?

package pizzafm;

public class ChicagoStylePepperoniPizza extends Pizza {

public ChicagoStylePepperoniPizza() {

name = "Chicago Style Pepperoni Pizza";

dough = "Extra Thick Crust Dough";

sauce = "Plum Tomato Sauce";

toppings.add("Shredded Mozzarella Cheese");

toppings.add("Black Olives");

toppings.add("Spinach");

toppings.add("Eggplant");

toppings.add("Sliced Pepperoni");

}

public void cut() {

System.out.println("Cutting the pizza into square slices");

}

}

[java] view
plaincopyprint?

package pizzafm;

public class ChicagoStyleVeggiePizza extends Pizza {

public ChicagoStyleVeggiePizza() {

name = "Chicago Deep Dish Veggie Pizza";

dough = "Extra Thick Crust Dough";

sauce = "Plum Tomato Sauce";

toppings.add("Shredded Mozzarella Cheese");

toppings.add("Black Olives");

toppings.add("Spinach");

toppings.add("Eggplant");

}

public void cut() {

System.out.println("Cutting the pizza into square slices");

}

}

/PizzaStore.java

此类也是声明为抽象的,实例化比萨的责任由具体的子类来实现

[java] view
plaincopyprint?

package pizzafm;

/**

* 2013/5/25

* @author wwj

* 让PizzaStore作为超类,让每个域类型都继承这个PizzaStore,每个子类各自决定如何制造披萨

*/

public abstract class PizzaStore {

public Pizza orderPizza(String type) {

Pizza pizza;

pizza = createPizza(type);

pizza.prepare();

pizza.bake();

pizza.cut();

pizza.box();

return pizza;

}

abstract Pizza createPizza(String type);

}

[java] view
plaincopyprint?

package pizzafm;

public class NYPizzaStore extends PizzaStore {

@Override

Pizza createPizza(String type) {

if(type.equals("cheese")){

return new NYStyleCheesePizza();

} else if(type.equals("veggie")) {

return new NYStyleVeggiePizza();

} else if(type.equals("clam")) {

return new NYStyleClamPizza();

} else if(type.equals("pepperoni")){

return new NYStylePepperoniPizza();

} else return null;

}

}

[java] view
plaincopyprint?

package pizzafm;

public class ChicagoPizzaStore extends PizzaStore {

@Override

Pizza createPizza(String type) {

if(type.equals("cheese")) {

return new ChicagoStyleCheesePizza();

} else if(type.equals("veggie")) {

return new ChicagoStyleVeggiePizza();

} else if(type.equals("clam")) {

return new ChicagoStyleClamPizza();

} else return null;

}

}

/PizzaTestDriver.java

[java] view
plaincopyprint?

package pizzafm;

/**

* 2013/5/25

* @author wwj

* 工厂模式测试驱动类

*/

public class PizzaTestDriver {

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() + "\n");

pizza = chicagoStore.orderPizza("cheese");

System.out.println("Joel ordered a " + pizza.getName() + "\n");

}

}

抽象工厂模式实现



/Pizza.java

[java] view
plaincopyprint?

package pizzaaf;

public abstract class Pizza {

String name;

Dough dough;

Sauce sauce;

Veggies veggies[];

Cheese cheese;

Pepperoni pepperoni;

Clams clam;

abstract void prepare(); //声明为抽象,在这个方法中那个我们需要搜集披萨所需的原料,而这些原料当然是来自原料工厂

void bake(){

System.out.println("Bake for 25 minutes at 350");

}

void cut() {

System.out.println("Cutting the pizza into diagonal slices");

}

void box() {

System.out.println("Place pizza in official PizzaStore box");

}

void setName(String name) {

this.name = name;

}

String getName() {

return name;

}

public String toString() {

StringBuffer result = new StringBuffer();

result.append("---- " + name + " ----\n");

if (dough != null) {

result.append(dough);

result.append("\n");

}

if (sauce != null) {

result.append(sauce);

result.append("\n");

}

if (cheese != null) {

result.append(cheese);

result.append("\n");

}

if (veggies != null) {

for (int i = 0; i < veggies.length; i++) {

result.append(veggies[i]);

if (i < veggies.length-1) {

result.append(", ");

}

}

result.append("\n");

}

if (clam != null) {

result.append(clam);

result.append("\n");

}

if (pepperoni != null) {

result.append(pepperoni);

result.append("\n");

}

return result.toString();

}

}

[java] view
plaincopyprint?

package pizzaaf;

public class CheesePizza extends Pizza {

PizzaIngredientFactory ingredientFactory;

public CheesePizza(PizzaIngredientFactory ingredientFactory) {

this.ingredientFactory = ingredientFactory;

}

@Override

void prepare() {

System.out.println("Preparing " + name);

dough = ingredientFactory.createDough();

sauce = ingredientFactory.createSauce();

cheese = ingredientFactory.createCheese();

}

}

[java] view
plaincopyprint?

package pizzaaf;

public class ClamPizza extends Pizza {

PizzaIngredientFactory ingredientFactory;

public ClamPizza(PizzaIngredientFactory ingredientFactory) {

this.ingredientFactory = ingredientFactory;

}

@Override

void prepare() {

System.out.println("PreParing " + name);

dough = ingredientFactory.createDough();

sauce = ingredientFactory.createSauce();

cheese = ingredientFactory.createCheese();

clam = ingredientFactory.createClam();

}

}

[java] view
plaincopyprint?

package pizzaaf;

public class PepperoniPizza extends Pizza {

PizzaIngredientFactory ingredientFactory;

public PepperoniPizza(PizzaIngredientFactory ingredientFactory) {

this.ingredientFactory = ingredientFactory;

}

void prepare() {

System.out.println("Preparing " + name);

dough = ingredientFactory.createDough();

sauce = ingredientFactory.createSauce();

cheese = ingredientFactory.createCheese();

veggies = ingredientFactory.createVeggies();

pepperoni = ingredientFactory.createPepperoni();

}

}

[java] view
plaincopyprint?

package pizzaaf;

public class VeggiePizza extends Pizza {

PizzaIngredientFactory ingredientFactory;

public VeggiePizza(PizzaIngredientFactory ingredientFactory) {

this.ingredientFactory = ingredientFactory;

}

void prepare() {

System.out.println("Preparing " + name);

dough = ingredientFactory.createDough();

sauce = ingredientFactory.createSauce();

cheese = ingredientFactory.createCheese();

veggies = ingredientFactory.createVeggies();

}

}

/PizzaIngredientFactory.java

[java] view
plaincopyprint?

package pizzaaf;

/**

* 建造原料工厂

* @author wwj

* 在接口中,每个原料都有一个对应的方法创造该原料

*/

public interface PizzaIngredientFactory {

public Dough createDough();

public Sauce createSauce();

public Cheese createCheese();

public Veggies[] createVeggies();

public Pepperoni createPepperoni();

public Clams createClam();

}

[java] view
plaincopyprint?

package pizzaaf;

/**

* 创建纽约原料工厂

* @author wwj

*

*/

public class NYPizzaIngredientFactory implements PizzaIngredientFactory {

@Override

public Dough createDough() {

return new ThinCrustDough();

}

@Override

public Sauce createSauce() {

return new MarinaraSauce();

}

@Override

public Cheese createCheese() {

return new ReggianoCheese();

}

@Override

public Veggies[] createVeggies() {

Veggies veggies[] = {new Garlic(), new Onion(), new MushRoom(), new RedPepper()};

return veggies;

}

@Override

public Clams createClam() {

return new FreshClams();

}

@Override

public Pepperoni createPepperoni() {

return new SlicePepproni();

}

}

[java] view
plaincopyprint?

package pizzaaf;

/**

* 芝加哥披萨原料工厂

* @author wwj

*

*/

public class ChicagoPizzaIngredientFactory implements PizzaIngredientFactory {

@Override

public Dough createDough() {

return new ThickCrustDough();

}

@Override

public Sauce createSauce() {

return new plumTomatoSauce();

}

@Override

public Cheese createCheese() {

return new Mozzarella();

}

@Override

public Veggies[] createVeggies() {

Veggies veggies[] = {new BlackOlives(), new Spinach(), new EggPlant()};

return veggies;

}

@Override

public Clams createClam() {

return new FrozenClams();

}

@Override

public Pepperoni createPepperoni() {

return new SlicedPepperoni();

}

}

所有原料接口,一系列产品族

[java] view
plaincopyprint?

package pizzaaf;

public interface Cheese {

@Override

public String toString();

}

[java] view
plaincopyprint?

package pizzaaf;

public interface Clams {

@Override

public String toString();

}

[java] view
plaincopyprint?

package pizzaaf;

public interface Dough {

@Override

public String toString();

}

[java] view
plaincopyprint?

package pizzaaf;

public interface Sauce {

@Override

public String toString();

}

[java] view
plaincopyprint?

package pizzaaf;

public interface Veggies {

@Override

public String toString();

}

[java] view
plaincopyprint?

package pizzaaf;

public interface Pepperoni {

@Override

public String toString();

}


实现Cheese的类

[java] view
plaincopyprint?

package pizzaaf;

public class Mozzarella implements Cheese {

public String toString() {

return "Shredded Mozzarella";

}

}

[java] view
plaincopyprint?

package pizzaaf;

public class ReggianoCheese implements Cheese {

public String toString() {

return "Reggiano Cheese";

}

}

实现Clams的类

[java] view
plaincopyprint?

package pizzaaf;

public class FreshClams implements Clams {

public String toString() {

return "Fresh Clams from Long Island Sound";

}

}

[java] view
plaincopyprint?

package pizzaaf;

public class FrozenClams implements Clams {

public String toString() {

return "Frozen Clams from Chesapeake Bay";

}

}


实现Sauce的类

[java] view
plaincopyprint?

package pizzaaf;

public class MarinaraSauce implements Sauce {

public String toString() {

return "Marinara Sauce";

}

}

[java] view
plaincopyprint?

package pizzaaf;

public class plumTomatoSauce implements Sauce {

public String toString() {

return "Tomato sauce with plum tomatoes";

}

}

实现Veggies的类

[java] view
plaincopyprint?

package pizzaaf;

public class EggPlant implements Veggies {

public String toString() {

return "Eggplant";

}

}

[java] view
plaincopyprint?

package pizzaaf;

public class Onion implements Veggies {

public String toString() {

return "Onion";

}

}

[java] view
plaincopyprint?

package pizzaaf;

public class Spinach implements Veggies {

public String toString() {

return "Spinach";

}

}

[java] view
plaincopyprint?

package pizzaaf;

public class MushRoom implements Veggies {

public String toString() {

return "Mushrooms";

}

}

实现Pepperoni的类


实现Dough的类

[java] view
plaincopyprint?

package pizzaaf;

public class ThickCrustDough implements Dough {

public String toString() {

return "ThickCrust style extra thick crust dough";

}

}

[java] view
plaincopyprint?

package pizzaaf;

public class ThinCrustDough implements Dough {

public String toString() {

return "Thin Crust Dough";

}

}

关于工厂模式已经介绍完,蛮多内容的是吧。
什么时候用工厂方法和抽象方法呢?
来听听它们的告白:
抽象工厂:我是抽象工厂,当你需要创建产品家族和想让制造的相关产品集合起来时,你可以使用我。
工厂方法:我是工厂方法,我可以把你的客户代码从实例化的具体类中解耦。或者如果你目前还不知道将来需要实例化哪些具体类时,也可以用我。我的使用方式简单,只要把握继承成子类,并实现我的工厂方法就行了。
内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息
标签: