一文必懂-工厂模式
工廠模式
- 工廠模式
- 傳統(tǒng)方式創(chuàng)建一類對象
- 優(yōu)缺點(diǎn)
- 簡單工廠模式
- 工廠方法模式
- 應(yīng)用場景與優(yōu)點(diǎn)
- 抽象方法模式
- 應(yīng)用場景
- 優(yōu)點(diǎn)
- JDK源碼中的應(yīng)用:
- 工廠方法與抽象工廠的區(qū)別
今天也是干的一天
工廠模式
工廠模式分為簡單工廠、工廠方法與抽象工廠模式;
傳統(tǒng)方式創(chuàng)建一類對象
Pizza.java
package com.yxj.factory.simplefactory.pizzastore.pizza;//將Pizza 類做成抽象 public abstract class Pizza {protected String name; //名字//準(zhǔn)備原材料, 不同的披薩不一樣,因此,我們做成抽象方法public abstract void prepare();public void bake() {System.out.println(name + " baking;");}public void cut() {System.out.println(name + " cutting;");}//打包public void box() {System.out.println(name + " boxing;");}public void setName(String name) {this.name = name;} }CheesePizza.java
package com.yxj.factory.simplefactory.pizzastore.pizza;public class CheesePizza extends Pizza {@Overridepublic void prepare() {// TODO Auto-generated method stubSystem.out.println(" 給制作奶酪披薩 準(zhǔn)備原材料 ");}}GreekPizza.java
package com.yxj.factory.simplefactory.pizzastore.pizza;public class GreekPizza extends Pizza {@Overridepublic void prepare() {// TODO Auto-generated method stubSystem.out.println(" 給希臘披薩 準(zhǔn)備原材料 ");}}OrderPizza.java
public class OrderPizza {//構(gòu)造器public OrderPizza() {Pizza pizza = null;String orderType; // 訂購披薩的類型do {orderType = getType();if (orderType.equals("greek")) {pizza = new GreekPizza();pizza.setName(" 希臘披薩 ");} else if (orderType.equals("cheese")) {pizza = new CheesePizza();pizza.setName(" 奶酪披薩 ");} else if (orderType.equals("pepper")) {pizza = new PepperPizza();pizza.setName("胡椒披薩");} else {break;}//輸出pizza 制作過程pizza.prepare();pizza.bake();pizza.cut();pizza.box();} while (true);}// 寫一個(gè)方法,可以獲取客戶希望訂購的披薩種類private String getType() {try {BufferedReader strin = new BufferedReader(new InputStreamReader(System.in));System.out.println("input pizza 種類:");String str = strin.readLine();return str;} catch (IOException e) {e.printStackTrace();return "";}}}PepperPizza.java
package com.yxj.factory.simplefactory.pizzastore.pizza;public class PepperPizza extends Pizza {@Overridepublic void prepare() {// TODO Auto-generated method stubSystem.out.println(" 給胡椒披薩準(zhǔn)備原材料 ");}}PizzaStore.java
package com.yxj.factory.simplefactory.pizzastore.order;//相當(dāng)于一個(gè)客戶端,發(fā)出訂購 public class PizzaStore {public static void main(String[] args) {// TODO Auto-generated method stubnew OrderPizza();}}優(yōu)缺點(diǎn)
- 簡單、容易理解
- 違反了OCP原則,即對擴(kuò)展開放,對修改關(guān)閉。即當(dāng)我們給類增加新功能的時(shí)候,盡量不修改已經(jīng)寫好的代碼,或者盡可能少修改代碼。
- 比如我們這時(shí)要新增加一個(gè)Pizza的種類(CheesePizza披薩),我們需要做如下修改.
- 也許有人會(huì)說,不就一個(gè)地方修改了代碼嗎?但是在工作中,可能在其他的地方也有創(chuàng)建Pizza代碼,意味著其他的地方也要修改,而創(chuàng)建Pizza代碼的地方,有很多處的情況下,就麻煩了。
- 思路:把創(chuàng)建Pizza對象封裝到一個(gè)類中,這樣我們有新的Pizza種類時(shí),只需要修改該
類就可,其它有創(chuàng)建到Pizza對象的代碼就不需要修改了.-> 簡單工廠模式
簡單工廠模式
簡單工廠模式是屬于創(chuàng)建型模式、是工廠模式的一種。簡單工廠模式就是由一個(gè)對象(對應(yīng)一個(gè)SimpleFactory類)決定創(chuàng)建出哪一產(chǎn)品類的實(shí)例。
核心類SimpleFactory
OrderPizza2.java
public class OrderPizza2 {Pizza pizza = null;String orderType = "";// 構(gòu)造器public OrderPizza2() {do {orderType = getType();pizza = SimpleFactory.createPizza2(orderType);// 輸出pizzaif (pizza != null) { // 訂購成功pizza.prepare();pizza.bake();pizza.cut();pizza.box();} else {System.out.println(" 訂購披薩失敗 ");break;}} while (true);}// 寫一個(gè)方法,可以獲取客戶希望訂購的披薩種類private String getType() {try {BufferedReader strin = new BufferedReader(new InputStreamReader(System.in));System.out.println("input pizza 種類:");String str = strin.readLine();return str;} catch (IOException e) {e.printStackTrace();return "";}} }- 核心就是SimpleFactory的實(shí)現(xiàn),使用該類負(fù)責(zé)實(shí)例的創(chuàng)建,符合OCP開閉原則;
工廠方法模式
定義一個(gè)用于創(chuàng)建對象的接口,讓子類決定實(shí)例化哪一個(gè)類。Factory Method使得一個(gè)類的實(shí)例化延遲到子類;
package com.tuling.designpattern.factorymethod;/*** @author 玄霄* @Slogan 致敬大師,致敬未來的你*/ public class FactoryMethodTest {public static void main(String[] args) {Application application= new ConcreteProductB();Product product=application.getObject();product.method1();} }interface Product{void method1(); }class ProductA implements Product{@Overridepublic void method1() {System.out.println( "ProductA.method1 executed." );} }class ProductB implements Product{@Overridepublic void method1() {System.out.println( "ProductB.method1 executed." );} }// 簡單工廠 class SimpleFactory{public static Product createProduct(String type){if ("A".equals( type )){return new ProductA();}return null;} }// 變化 , 共同點(diǎn) abstract class Application {// 工廠方法public abstract Product createProduct();public Product getObject() {Product product=createProduct();// ......這是公共不變的部分代碼return product;} }class ConcreteProductA extends Application{@Overridepublic Product createProduct() {ProductA productA=new ProductA();return productA;} }class ConcreteProductB extends Application{@Overridepublic Product createProduct() {ProductB productB=new ProductB();return productB;} }應(yīng)用場景與優(yōu)點(diǎn)
- 當(dāng)你不知道改使用對象的確切類型的時(shí)候
- 當(dāng)你希望為庫或框架提供擴(kuò)展其內(nèi)部組件的方法時(shí)
優(yōu)點(diǎn):
- 將具體產(chǎn)品和創(chuàng)建者解耦
- 符合單一職責(zé)原則
- 符合開閉原則
抽象方法模式
提供一個(gè)創(chuàng)建一系列相關(guān)或互相依賴對象的接口,而無需指定他們的具體的類
- AbstractProductA:創(chuàng)建A類產(chǎn)品所實(shí)現(xiàn)的接口,該接口包含了A類產(chǎn)品中共有的方法;
- ProductA1,ProductA2:A類的具體產(chǎn)品;
- AbstractProductB:創(chuàng)建B類產(chǎn)品所實(shí)現(xiàn)的接口,該接口包含了B類產(chǎn)品中共有的方法;
- ProductB1,ProductB2:B類的具體產(chǎn)品
- AbstracyFactory:包含了創(chuàng)建的A類、B類產(chǎn)品的接口方法;
- ConcreteFactory1: 創(chuàng)建 “1”系列的產(chǎn)品,即ProductA1,ProductB1;
- ConcreteFactory2: 創(chuàng)建 “2”系列的產(chǎn)品,即ProductA2,ProductB2;
應(yīng)用場景
- 程序需要處理不同系列的相關(guān)產(chǎn)品,但是您不希望它依賴于這些產(chǎn)品的具體類時(shí)
- 可以使用抽象工廠
優(yōu)點(diǎn)
JDK源碼中的應(yīng)用:
java.sql.Connection java.sql.Driver工廠方法與抽象工廠的區(qū)別
當(dāng)抽象工廠接口方法只有一個(gè)時(shí),就變成了工廠方法模式;
千軍萬馬一將在,探囊取物有何難
總結(jié)
- 上一篇: 别人家的键盘--机械键盘
- 下一篇: C语言画心