设计模式学习笔记:工厂模式
Posted 滴滴哒滴哒
tags:
篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了设计模式学习笔记:工厂模式相关的知识,希望对你有一定的参考价值。
接下来,我们来说下抽象工厂模式。
抽象工厂模式提供一个接口,用于创建相关或依赖对象的家族,而不需要明确指定具体类。
在这里我们可以看到这里指的“家族”,这是区别于普通工厂模式应用上比较大的差别。在一般的应用场景里,家族都指的是生产过程中有一定关联的产品,例如:pizza店里面的原料制作。
在前例中,因为各地加盟店开张,我们需要因地制宜地调整pizza的原料。纽约的Pizza用到的原料是大蒜番茄酱料,Reggiano干酪以及新鲜的蛤蜊……而芝加哥的Pizza用到的是不同的原料。我们可以看到Pizza依赖于这种原料家族,并且原料之间拥有相关性。
我们先设计一个接口,用来生产各种原料。
public interface PizzaIngredientFactory
//在接口中,每个原料都对应一种方法去创建该原料
public Dough createDough();
public Sauce createSauce();
public Cheese createCheese();
public Veggies[] createVeggies();
public Pepperoni createPepperoni();
public Clams createClam();
我们用具体的原料工厂去实现它:
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 new Veggies[0];
@Override
public Pepperoni createPepperoni()
return new SlicedPepperoni();
@Override
public Clams createClam()
return new FreshClams();
public class ChicagoIngredientFactory 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 Pepperoni createPepperoni()
return new SlicedPepperoni();
@Override
public Clams createClam()
return new FrozenClams();
原料准备好了,我们现在要去做Pizza了
public abstract class Pizza
String name;
Dough dough;
Sauce sauce;
Veggies veggies[];
Cheese cheese;
Pepperoni pepperoni;
Clams clams;
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;
@Override
public String toString()
return "Pizza" +
"name='" + name + '\\'' +
", dough=" + dough +
", sauce=" + sauce +
", veggies=" + Arrays.toString(veggies) +
", cheese=" + cheese +
", pepperoni=" + pepperoni +
", clams=" + clams +
'';
public class CheesePizza extends Pizza
PizzaIngredientFactory ingredientFactory;
//要制作Pizza,需要工厂提供原料,所以每个Pizza类都需要从构造器参数中得到一个工厂,并把这个工厂存储到一个实例变量中去
public CheesePizza(PizzaIngredientFactory ingredientFactory)
this.ingredientFactory = ingredientFactory;
@Override
void prepare()
System.out.println("Preparing" + name);
dough = ingredientFactory.createDough();
sauce = ingredientFactory.createSauce();
cheese = ingredientFactory.createCheese();
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();
clams = ingredientFactory.createClam();
最后我们保证各地的Store能够跟IngredientFactory挂上钩,这样就完成了
public class NYPizzaStore extends PizzaStore
@Override
Pizza createPizza(String type)
Pizza pizza = null;
PizzaIngredientFactory ingredientFactory = new NYPizzaIngredientFactory();
if (type.equals("cheese"))
pizza = new CheesePizza(ingredientFactory);
pizza.setName("New York Style Cheese Pizza");
else if (type.equals("clam"))
pizza = new ClamPizza(ingredientFactory);
return pizza;
在抽象工厂中,我们引入了新类型的工厂,来创建Pizza原料家族。通过抽象工厂所提供的接口,可以创建产品的家族,利用这个接口书写代码避免了在上下文中出现各式各样的工厂(CheeseFactory,ClamsFactory……),实现了“解耦”。
接下来我们来详细比较一下抽象工厂和普通工厂的差异:
1.普通工厂通过生产类的子类来创建对象,用这种做法,客户只需要知道他们所使用的抽象类型就可以了,而由子类去决定具体类型。
抽象工厂提供一个产品家族的抽象类型,这个类型的子类定义了产品被产生的方法。要使用这个工厂,必须要先实例化它,然后将它传入一些针对抽象类型所写的代码中。
2.普通工厂一般使用继承,抽象工厂使用的是对象的组合。
3.最明显的差异是抽象工厂是用来创建产品家族的。
以上是关于设计模式学习笔记:工厂模式的主要内容,如果未能解决你的问题,请参考以下文章