1.“new”有什么不對勁?
在我們沒有接觸到工廠模式(簡單工廠、工廠方法模式、抽象工廠模式)之前,我們實體化物件唯一的方法就是通過“new”關鍵字來完成,但是,大量的使用“new”關鍵字來實體化物件會違背一些設計原則,因為代碼與具體的型別綁在一起,從而導致過多的依賴于細節而非抽象,這樣代碼就很難適應需求變化,
在面向物件編程中我們大量的使用到了繼承、多型的特性,但是在使用這些特性時往往會延申出一些新的問題,例如在一個有繼承模塊的代碼當中,如果子類發生新增或洗掉,這就不得不去使用類的“呼叫層”做出相應的修改,因為你new的都是具體的型別,當下層發生變動就不得不去上層進行修改,對于這樣的場景來說,實際上它也違背了設計模式原則之一的“開閉原則”,即對擴展開放,對修改關閉,這會不利于程式的穩定和擴展,
2.舉例反映問題
接下來將通過代碼案例來反映出,在一個使用繼承模塊的代碼當中,大量使用“new”關鍵字,在設計層面會帶來什么樣的缺陷,我們以一個汽車銷售系統作為背景,其中汽車型別UML圖如下:

其中有一個賣車的方法使用到了“new”來實體化車型物件,相應的代碼如下:
1 //賣車方法
2 public void SellCar(string carType)
3 {
4 Car car;
5 if(carType=="寶馬 X3")
6 {
7 car=new Bmwx3();
8 }
9 else if(carType=="吉普牧馬人")
10 {
11 car=new Jeeper();
12 }
13 else if(carType=="奔馳G63")
14 {
15 car=new BenzG63();
16 }
17
18 TestDrive(car);//試駕
19 Collection(car);//收款
20 License(car);//上牌
21 }
在實際的生活當中我們應該都知道,4s店賣的車型不可能是一層不變的,而是經常性的會發生產品的更新換代,所以會不斷對車型做出新增或刪減,如果汽車銷售系統中使用了以上的代碼,這就意味這每次車型模塊的調整都要同步到“賣車方法”中,并且隨著公司規模的增大所賣的車型會增多,在新增車型后代碼中出現大量的else if,這會顯得非常臃腫,在洗掉時還可能誤刪,
即便你說你的“汽車銷售系統只賣一種車”(也就是只new一種物件型別),你可能還是會在使用建構式創建物件時要加入引數的情形,這些變化都會促使你因為下層模塊的調整而影響到上層模塊,

3.改善方法
1.編程當中任何需求或代碼都是無法避免的,而我們能做到就是運用設計模式的思想,能夠將程式更好的去適應變化,其中的一個思想就是:“找出變化的部分,把它們從不變的部分分離出來”,以上面的“汽車銷售系統”中的賣車方法為例,分析變化如下:

2.然后,我們將變化的部分單獨的封裝到一個類的靜態方法中,該類的靜態方法將專門用于創建具體的汽車物件,代碼如下:
1 public class CarFactory
2 {
3 public static Car CreateCarInstance(string type)
4 {
5 Car car=null;
6 if(carType=="寶馬 X3")
7 {
8 car=new Bmwx3();
9 }
10 else if(carType=="吉普牧馬人")
11 {
12 car=new Jeeper();
13 }
14 else if(carType=="奔馳G63")
15 {
16 car=new BenzG63();
17 }
18 return car;
19 }
20 }
3.在抽離并封裝變化后,我們將對“賣車方法”中的實體化車物件部分進行改造,
1 public void SellCar(string carType)
2 {
3 Car car=CarFactory.CreateCarInstance(carType);
4
5 TestDrive(car);//試駕
6 Collection(car);//收款
7 License(car);//上牌
8 }
根據以上的三個步驟,其實一個簡單工廠創建物件的方式就已經形成了,其中專門創建物件的Factory類我們稱之為工廠,它實體化的物件我們稱之為產品,此時我們創建物件的方式不在是"new",而是通過一個靜態方法,
對于上層模塊(賣車方法),在也不用擔心下層模塊(汽車車型)的變化而牽連到自身,它只有根據指定的型別創建對應的車型物件即可,并且上層模塊(賣車方法)也不用在承擔物件創建的細節,減少大量代碼和復雜度,
另外簡單工廠也解決了物件創建復用的問題,例如4s店的汽車保險系統、汽車維修系統等等都會用到實體化車型物件,這樣的話,如果車型發生修改我們只用調整簡單工廠類即可而其他(呼叫層)都不必受到改動的牽連,
4.定義
簡單工廠又稱之為靜態工廠方法,它屬于創建型模式中的一種簡單運用,
嚴格來講它其實并不屬于一種設計模式,反而比較像我們在遵循設計模式原則時的一種編程習慣,你要你能夠在編程中遵循并靈活運用:迪米特法則(最少知道原則)、依賴倒置(依賴抽象,不依賴細節)、里氏替換(子類替代父類)這些原則,其實就會無形當中使用簡單工廠來實作物件的實體化,而并非只使用“new”,
5.短板
使用簡單工廠實體化物件雖然解決了一些問題,但是有同時存在一些新的問題,因為我們的簡單工廠本身就是一個具體的型別,這違反了面向介面(抽象)編程的思想,
還是以汽車銷售作為背景來說,假如你依賴的這個A工廠因為疫情出現停產,又或者因為你要擴張你的車型使用新的工廠,那么此時你依賴的A工廠(具體的類)就很難做出擴展,而只能因為你換了工廠導致上層模塊都要跟著調整,所以,后續誕生出的“工廠方法模式”和“抽象工廠模式”,就是在不斷解決因為變化而帶來各種的問題,
知識改變命運轉載請註明出處,本文鏈接:https://www.uj5u.com/ruanti/472390.html
標籤:其他
上一篇:【OOP】模板與STL初步
