GOF23设计模式(创建型模式)工厂模式
目錄:
一:工廠模式的核心本質
二:關于面向對象的六大基本原則
三:工廠模式的三大類詳解(代碼示例,詳細分析)
首先,上咱本GOF23所有工廠模式的分類表格!!!
| 創建型模式 | 單例模式、工廠模式、抽象工廠模式、建造者模式、原型模式 |
| 結構型橫式 | 適配器模式、橋接模式、裝飾模式、組合模式、外觀模式、享元模式、代理模式 |
| 行為型模式 | 模版方法模式、命令模式、迭代器模式、觀察者模式、中介者模式、備忘錄模式、解釋器模式、狀態模式、策略模式、職責鏈模式、訪問者模式 |
?其中我們講的工廠模式為創建型模式!!!!
一:工廠模式的核心本質
- 實現了創建者和調用者的分離,實例化對象,用工廠方法代替new操作。
- 將選擇實現類、創建對象統一管理和控制。從而將調用者跟我們的實現類解耦。
我們要明確的一點,我們設計模式的基礎是面向對象編程(Object Oriented Programming,OOP),只要是提及設計模式,肯定都是基于面向對象編程的,所以我們的設計模式要以面向對象的基本原則為基礎!!!接下來,我給大家列出關于面向對象的六大基本原則!
二:面向對象的六大基本原則(其中OCP為總原則)
| 總原則:OCP(開閉原則, Open-Closed Principle) | 對擴展開放,對修改關閉。設計功能模塊的時候,應當使這個模塊在不被修改的前提下可以被擴展(功能) |
| DIP(依賴倒轉原則, Dependence Inversion Principle) | 依賴抽象不依賴具體,高層模塊不應該依賴底層模塊,兩者應該依賴抽象,抽象不應該依賴細節(具體實現),細節依賴抽象(依賴接口) 提高可維護性 |
| LOD(迪米特法則, Law of demeter) | 對象之間聯系越少越好,對于對象的使用,方法調用,具體內部細節知道的越少越好(高內聚,低耦合) 可維護性強。(盡量少與其他類有關系,利于解耦) |
| SRP(單一職責原則,Single responsibility principle) | 一個類或模塊應該只做一件事(一個類或者模塊對應一個功能類),高內聚,低耦合,專注于單一功能(高內聚) |
| ISP(接口隔離原則,Interface Segregation Principle) | 一個接口最好只有一個方法(功能),讓實現一個接口的類重寫一種方法(功能)。針對不同功能應該有不同接口,使接口的功能有選擇性,不強迫必須實現不需要的功能。 |
| CRP(組合/聚合原則,Composite Reuse Principle) | 盡量使用對象組合,而不是繼承對象達到功能復用的目的,一個新對象A能使用已有對象B達到功能復用(B對象的功能),就不要通過繼承(B)對象來達到功能復用 |
| LSP(里氏替換原則,Liskov Substitution Principle) | 對于父類出現的地方,都可以用子類代替(多態,繼承) |
三: 三大工廠模式剖析
詳細分類:
| 簡單工廠模式 | 用來生產同一等級結構中的任意產品。(對于增加新的產品,需要修改已有代碼) |
| 工廠方法模式 | 用來生產同一等級結構中的固定產品。(支持增加任意產品) |
| 抽象工廠模式 | 用來生產不同產品族的全部產品。(對于增加新的產品,無能為力,支持增加產品族) |
?讓我們一起來看看簡單工廠模式!!
?首先我,定義了一個Instrument 接口(樂器)
package 二_工廠模式;public interface Instrument {void sing();
}
然后定義了兩個類Guitar 和Piano 繼承Instrument 接口
package 二_工廠模式;public class Guitar implements Instrument {@Overridepublic void sing() {System.out.println("吉他~");}
}
package 二_工廠模式;public class Piano implements Instrument {@Overridepublic void sing() {System.out.println("鋼琴~");}
}
在沒有工廠的情況下:
package 二_工廠模式;public class noFactory {public static void main(String[] args) {Instrument i1 = new Guitar();Instrument i2 = new Piano();i1.sing();i2.sing();}
}
發現實例化出Guitar和Piano的兩個對象要和Instrument接口以及這兩個實現類都要打交道,有些臃腫,于是我們引入了工廠模式
1 . 簡單工廠模式
在前面代碼的基礎上定義一個工廠類InstrumentFactory,其中的方法都定義為靜態方法,直接通過類調用,其中創建對象有兩種實現方式,在一下代碼中給出!!
package 二_工廠模式;public class InstrumentFactory {public static Guitar creatGuitar() {return new Guitar();}public static Piano creatPiano() {return new Piano();}//或者這樣實現public static Instrument creatInstrument(String type) {Instrument i = null;if ("吉他".equals(type))i = new Guitar();else if ("鋼琴".equals(type))i = new Piano();return i;}
}
然后我們進行實例化只用和工廠打交道
package 二_工廠模式;public class simpleFactory {public static void main(String[] args) {InstrumentFactory.creatGuitar().sing();InstrumentFactory.creatPiano().sing();//或者這樣實現InstrumentFactory.creatInstrument("吉他").sing();InstrumentFactory.creatInstrument("鋼琴").sing();}
}
相比沒有工廠的情況下,我們減少了在主函數里創建一個對象需要接觸的類或者接口,實現了創建者和調用者的分離,實例化對象,用工廠方法代替new操作!!!
但是要增加新的類,比如"貝斯"類,必須修改工廠里已有的代碼!!這是簡單工廠模式的一個弊端!!
總結:
- 簡單工廠模式也叫靜態工廠模式、就是工廠類一般是使用靜態方法,通過接收的參數的不同來返回不同的對象實例
- 對于增加新產品必須修改已有的代碼!違反了OCP原則!不修改代碼的話,是無法擴展的。
2.?工廠方法模式
同樣在最前面的代碼基礎上增加一個工廠接口creatFactory
package 二_工廠模式;public interface creatFactory {Instrument creat();
}
然后再增加兩個具體的工廠實現類GuitarCreat和PianoCreat繼承creatFactory接口
package 二_工廠模式;public class GuitarCreat implements creatFactory {@Overridepublic Instrument creat() {return new Guitar();}
}
package 二_工廠模式;public class PianoCreat implements creatFactory {@Overridepublic Instrument creat() {return new Piano();}
}
然后我們進行實例化只用分別和這兩個工廠打交道
package 二_工廠模式;public class FunctionFactory {public static void main(String[] args) {new GuitarCreat().creat().sing();new PianoCreat().creat().sing();}
}
相比簡單工廠法,如果要增加新的類,比如"貝斯"類,不用修改工廠里已有的代碼,直接多加一個新的貝斯工廠實現工廠接口即可!!這是工廠方法模式的一個好處!!!?
?總結:
- 為了避免簡單工廠模式的缺點,此方法滿足了總原則:OCP原則
- 工廠方法模式和簡單工廠模式最大的不同在于,簡單工廠模式只有一個(對于一個項目或者一個獨立模塊而言)工廠類,而工廠方法模式有一組實現了相同接口的工廠類。
3.抽象工廠模式
簡介:
- 用來生產不同產品族的全部產品。(對于增加新的產品,無能為力;支持增加產品族)
- 抽象工廠模式是工廠方法模式的升級版本,在有多個業務品種、業努分類時,通過抽象工廠模式產生需要的對象是一種非常好的解決方式
首先我們明白什么是產品族,接下來我會以實現一個汽車工廠為例
我們把汽車拆分為Engine(發動機)、Seat(座位)、Tyre(輪胎)三部分
分別創建這三個接口~~
汽車就是一種產品,我們將汽車這個產品分為兩個產品族:
- 昂貴的汽車,包括LuxuryEngine、LuxurySeat、LuxuryTyre三個部分,分別實現了以上三個對應的接口
- 低端的汽車,包括LowEngine、LowSeat、LowTyre三個部分,分別實現了以上三個對應的接口
| package 二_工廠模式_抽象工廠模式; ? //發動機 public interface Engine { ??? void noice();//噪音 ??? void price();//價格 } ? class LowEngine implements Engine { ??? @Override ??? public void noice() { ??????? System.out.println("噪音很大"); ??? } ? ??? @Override ??? public void price() { ??????? System.out.println("價格便宜"); ??? } } ? class LuxuryEngine implements Engine { ??? @Override ??? public void noice() { ??????? System.out.println("噪音很小"); ??? } ? ??? @Override ??? public void price() { ??????? System.out.println("價格昂貴"); ??? } } | ? | package 二_工廠模式_抽象工廠模式; ? //座位 public interface Seat { ??? void comfortable();//舒適程度 ??? void functionality();//功能性 } ? class LowSeat implements Seat { ??? @Override ??? public void comfortable() { ??????? System.out.println("不舒服"); ??? } ? ??? @Override ??? public void functionality() { ??????? System.out.println("功能性很差"); ??? } } ? class LuxurySeat implements Seat { ??? @Override ??? public void comfortable() { ??????? System.out.println("很舒適"); ??? } ? ??? @Override ??? public void functionality() { ??????? System.out.println("功能性很強大"); ??? } } | ? | package 二_工廠模式_抽象工廠模式; ? //輪胎 public interface Tyre { ??? void durability();//耐用性 ??? void security();//安全性 } ? class LowTyre implements Tyre { ??? @Override ??? public void durability() { ??????? System.out.println("耐用性很差"); ??? } ? ??? @Override ??? public void security() { ??????? System.out.println("安全性很差"); ??? } } ? class LuxuryTyre implements Tyre { ??? public void durability() { ??????? System.out.println("耐用性很好"); ??? } ? ??? @Override ??? public void security() { ??????? System.out.println("安全性很好"); ??? } } |
?接下來,我們創建一個汽車工廠的接口CarFactory,并且為旗下的兩個產品族分別創建工廠LowFactory、LuxuryFactory、實現以上接口,用來創建Engine(發動機)、Seat(座位)、Tyre(輪胎)
package 二_工廠模式_抽象工廠模式;public interface CarFactory {Engine createEngine();Seat createSeat();Tyre createTyre();
}class LowFactory implements CarFactory {@Overridepublic Engine createEngine() {return new LowEngine();}@Overridepublic Seat createSeat() {return new LowSeat();}@Overridepublic Tyre createTyre() {return new LowTyre();}
}class LuxuryFactory implements CarFactory {@Overridepublic Engine createEngine() {return new LuxuryEngine();}@Overridepublic Seat createSeat() {return new LuxurySeat();}@Overridepublic Tyre createTyre() {return new LuxuryTyre();}
}
?最后,我們在一個主方法里測試,通過兩個產品族的工廠直接分別創建兩個產品族汽車的輪子,座椅和發動機
package 二_工廠模式_抽象工廠模式;public class client {public static void main(String[] args) {//高端汽車產品族CarFactory factory1 = new LuxuryFactory();factory1.createEngine().noice();factory1.createEngine().price();factory1.createSeat().comfortable();factory1.createSeat().functionality();factory1.createTyre().durability();factory1.createTyre().security();//低端汽車產品族CarFactory factory2 = new LowFactory();factory2.createEngine().noice();factory2.createEngine().price();factory2.createSeat().comfortable();factory2.createSeat().functionality();factory2.createTyre().durability();factory2.createTyre().security();}
}
根據結果,我們已經創建成功,這就是關于抽象工廠模式的一個實例!!!
THE END-------------------------------------------------------------------------------------------------------
總結
以上是生活随笔為你收集整理的GOF23设计模式(创建型模式)工厂模式的全部內容,希望文章能夠幫你解決所遇到的問題。
- 上一篇: GOF23设计模式(创建型模式)单例模式
- 下一篇: GOF23设计模式(创建型模式)建造者模