工厂方法-Factory method
这应该是大家学design pattern第一个遇到的pattern吧,这个pattern有两个角色
一个是 Factory另一个是 Product简单说就是透过Factory来生产Product,client只需要告诉Factory,我要一个什么Product,然后就得到他要的Product了。
架构图长这样:
範例
我现在要去吃pizza了,所以需要定义:
Factory: PizzaStoreProduct: Pizza当然都要是AbstractClass 或 interface,不应该把实作内容直接写在这边,物件导向语言的其中一个守则:针对介面写程式,不是针对实践方法写程式
宣告Factory
public abstract class PizzaStore { public abstract Pizza createPizza(String type); public Pizza orderPizza(String type) { // client只要呼叫这个method就好 Pizza pizza = createPizza(type); pizza.prepare(); pizza.bake(); pizza.cut(); pizza.box(); return pizza; }}
宣告Product
package com.example.designpattern.creational.factory_method.example2;public abstract class Pizza { String name; String dough; String sauce; // method都不是宣告为abstract,如果subClass不用客製,就不用override void prepare() { System.out.println("Preparing: " + name + ", " + dough + ", " + sauce ); System.out.println("Tossing dough..."); }; void bake() { System.out.println("Bake for 25 minutes at 350"); } void cut() { System.out.println("Cutting pizza into diagonal slices"); } void box() { System.out.println("Place pizza in official PizzaStore box"); }}
有了Factory跟Product后,就可以继承他们来写concreteClass了
先写Factory,NYPizzaStore
package com.example.designpattern.creational.factory_method.example2;public class NYPizzaStore extends PizzaStore { @Override public Pizza createPizza(String type) { Pizza pizza = null; // 这间PizzaStore可以生产两种Pizza if("cheese".equals(type)) { pizza = new NYCheesePizza(); } else if ("sausage".equals(type)) { pizza = new NYSausagePizza(); } return pizza; } @Override public Pizza orderPizza(String type) { return super.orderPizza(type); }}
再来是Product,第一种Product NYCheesePizza
package com.example.designpattern.creational.factory_method.example2;public class NYCheesePizza extends Pizza { String name = "NYCheesePizza"; String dough = "crispy"; String sauce = "cheese sauce"; @Override void prepare() { System.out.println("Amazing~~~ " + name +" , " + dough + " , " + sauce); } @Override void bake() { System.out.println("Bake for 15 minutes at 400"); } @Override void cut() { System.out.println("Cutting pizza into 8 slices"); }}
第二种Prodcut NYSausaePizze
package com.example.designpattern.creational.factory_method.example2;public class NYSausagePizza extends Pizza { String name = "NY Sausage pizze"; String dough = "Thick"; String sauce = "Marinara sauce"; @Override void prepare() { System.out.println(name +" , " + dough + " , " + sauce); }}
Client 要来点pizza了
package com.example.designpattern.creational.factory_method.example2;public class PizzaClient { public static void main(String[] args) { // 进入NYPizzaStore PizzaStore pizzaStore = new NYPizzaStore(); // 我要cheese pizza,啪,cheesePizza Pizza cheesePizza = pizzaStore.orderPizza("cheese"); System.out.println("---------------"); // 我要sausage pizza,啪,sausagePizza Pizza sausagePizza = pizzaStore.orderPizza("sausage"); } /* output: Amazing~~~ NYCheesePizza , crispy , cheese sauce Bake for 15 minutes at 400 Cutting pizza into 8 slices Place pizza in official PizzaStore box --------------- NY Sausage pizze , Thick , Marinara sauce Bake for 25 minutes at 350 Cutting pizza into diagonal slices Place pizza in official PizzaStore box */}
Reference:
https://refactoring.guru/design-patterns/factory-method
https://www.oreilly.com/library/view/head-first-design/0596007124/