[设计模式]工厂模式——静态工厂方法(实际不是一种设计模式)
简介
根据《head first 设计模式》所述,工厂模式共有三种:简单/静态工厂、工厂方法和抽象工厂。
注:其实静态工厂不是一个设计模式,它更像是一种编程习惯。但是这里是根据[1]所做的笔记,为了方便管理区分,假称它是工厂模式的一种。
本文介绍静态工厂方法。
1、定义:利用静态方法定义一个简单的工厂,是静态工厂。
2、原因:使用静态工厂模式,是因为不需要使用创建对象的方法来实例化对象,因此可以使用静态方法来创建一个简单的工厂。
3、缺点:
· 不能通过继承来改变创建对象的行为。
· 类如果不含有公有的或者受保护的构造方法,就不能被继承。
4、优点:
·通常来说,想要获取实例最常用的方法是被调用类提供一个公有的构造方法,但是使用静态工厂方法会有更好地弹性,当实现方法改变的时候,只需要更改静态工厂方法就可以了。
· 和构造方法不一样,静态工厂方法可以有自己明确的名字。
· 不必每次调用时都创建一个新对象。使用静态工厂方法对外提供单例,就是事先准备好一个实例,然后多次调用即可,这样可以减少重复创建实例,不好的地方是需要注意线程安全问题。
· 可以返回原返回类型的任何子类的对象。
5、具体实现(完整代码):
- 静态工厂:处理创建对象的细节
public class SimplePizzaFactory{ public Pizza createPizza(String type){ Pizza pizza = null; if(type.equals("cheese")){ return new CheesePizza(); }else if(type.equals("pepperoni")){ return new PepperoniPizza(); }else if(type.equals("clam")){ return new ClamPizza(); }else if(type.equals("veggie")){ return new VeggiePizza(); }else return null; } }
- 客户端:用来使用静态工厂来创建对象
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 abstract class Pizza { String name;//名称 String dough;//面团类型 String sauce;//酱料类型 ArrayList<String> toppings = new ArrayList<String>();//一套佐料 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)); } } 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"); } public String getName(){ return name; } public String toString(){ StringBuffer display = new StringBuffer(); display.append("------" + name + "-----\n"); display.append(dough + "\n"); display.append(sauce + "\n"); for(String topping : toppings){ display.append(topping + "\n"); } return display.toString(); } }
- 具体产品类:
//芝士披萨 public class CheesePizza extends Pizza{ public CheesePizza(){ name = "Cheese Pizza"; dough = "Cheese Dough"; sauce = "CheeseSauce"; toppings.add("Cheese Cheese"); } } //蛤蜊披萨 public class ClamPizza extends Pizza{ public ClamPizza(){ name = "Clam Pizza"; dough = "Clam Dough"; sauce = "Clam Sauce"; toppings.add("Clam"); } } //意式腊肠披萨 public class PepperoniPizza extends Pizza{ public PepperoniPizza(){ name = "Pepperoni Pizza"; dough = "Pepperoni Dough"; sauce = "Pepperoni Sauce"; toppings.add("Pepperoni"); } } //素食披萨 public class VeggiePizza extends Pizza{ public VeggiePizza(){ name = "Veggie Pizza"; dough = "Veggie Dough"; sauce = "Veggie Sauce"; toppings.add("Veggie"); } }
- 测试:
public class PizzaTest{ public static void main(String[] args){ SimplePizzaFactory factory = new SimplePizzaFactory(); PizzaStore store = new PizzaStore(factory); Pizza pizza = store.orderPizza("cheese"); System.out.println("Ethan ordered a " + pizza.getName() + "\n"); System.out.println(pizza); pizza = store.orderPizza("veggie"); System.out.println("Joel ordered a " + pizza.getName() + '\n'); System.out.println(pizza); } }
运行结果如下图所示:
参考资料:
[1] head first 设计模式