今天讲一下,简单工厂模式。
当我们看到“new”的时候,就会想到“具体”,一般我们的程序都要求面相接口编程:父类引用指向子类对象,而对象的创建这块一般就是会发生变化的部分,看看下面的例子:
以一个披萨店(PizzaStore)为例,需要制造出奶酪披萨(CheesePizza),香肠披萨(PepperoniPizza),披萨模板完成后,就是披萨筹备,烘焙,切,装盒,完工。
/**
* 披萨
*/
abstract public class Pizza {
/**
* 披萨名
*/
String name;
/**
* 披萨面
*/
String dough;
/**
* 调汁
*/
String sauce;
/**
* 配料
*/
ArrayList toppings = new ArrayList();
public String getName() {
return name;
}
/**
* 筹备
*/
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);
}
public String toString() {
// code to display pizza name and ingredients
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 class PizzaStore {
public Pizza orderPizza(String type) {
Pizza pizza = null;
if (type.equals("cheese")) {
pizza = new CheesePizza();
} else if (type.equals("pepperoni")) {
pizza = new PepperoniPizza();
}
pizza.prepare();
pizza.bake();
pizza.cut();
pizza.box();
return pizza;
}
}
/**
* 奶酪披萨
*/
public class CheesePizza extends Pizza {
public CheesePizza() {
name = "Cheese Pizza";
dough = "Regular Crust";
sauce = "Marinara Pizza Sauce";
toppings.add("Fresh Mozzarella");
toppings.add("Parmesan");
}
}
/**
* 香肠披萨
*/
public class PepperoniPizza extends Pizza {
public PepperoniPizza() {
name = "Pepperoni Pizza";
dough = "Crust";
sauce = "Marinara sauce";
toppings.add("Sliced Pepperoni");
toppings.add("Sliced Onion");
toppings.add("Grated parmesan cheese");
}
}
OK,披萨算是做好了,现在可以吃了,但之后需求变化,需要添加素披萨(VeggiePizza),并且香肠披萨(PepperoniPizza)销量不好,不在生产,这时就的修改代码。
此时可以想到前面提到的编程原则:对扩展开放,对修改关闭。 那好,简单工厂模式可以登场了,修改后代码如下:
/**
* 素披萨
*/
public class VeggiePizza extends Pizza {
public VeggiePizza() {
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");
}
}
/**
* 披萨店
*
*/
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;
}
}
/**
* 简单披萨工厂
*/
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("veggie")) {
pizza = new VeggiePizza();
}
return pizza;
}
}
/**
* 披萨测试
*/
public class PizzaTestDrive {
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");
}
}
这里修改了披萨店,增加了披萨工厂,披萨以后不需要在关注怎么产披萨,直接告诉工厂去生产就OK。
好,这里我们可以看出来,简单工厂模式是如此的简单,总结下简单工厂模式:其实就是将变化的代码进行封装,且封装在一个类中,这样,当需要变化的时候,我们只要关注一个类就行了,
OK,在这里,简单工厂模式貌似就不像是一种模式,更像是一种编程习惯:对于变化的代码,尽量封装下,可以封装成方法,在这里只不过封装到一个类中了