上一篇文章介紹過了優化語法的四種結構型設計模式,這篇文章主要會從優化程式碼結構的幾種 Pattern 開始介紹
接下來會繼續從優化程式碼結構的四種結構型設計模式開始介紹
- Adapter Pattern
- Bridge Pattern
- Facade Pattern
- Flyweight Pattern
Design Patterns 依照目的分成三群:
Adapter Pattern
在這個範例中,有兩個介面
- MotorcycleFactory 代表原有的機車工廠
- NewMotorcycleFactory 代表新的機車工廠
新的機車工廠的製造方式不同 (produce -> create),所以透過 NewMotorcycleFactoryAdapter 多轉一層,讓原有的程式在不改變寫法的情況下,可以使用新的機車工廠物件 (新的方法) 去製造機車。
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36
| class MotorcycleFactory { constructor(name) { this.name = name; } produce() { console.log(`${this.name} 生產了一輛機車`); } }
class NewMotorcycleFactory { constructor(name) { this.name = name; } create() { console.log(`${this.name} 創建了一輛機車`); } }
class NewMotorcycleFactoryAdapter extends MotorcycleFactory { constructor(newMotorcycleFactory) { super(newMotorcycleFactory.name); this.newMotorcycleFactory = newMotorcycleFactory; } produce() { return this.newMotorcycleFactory.create(); } }
let newMotorcycleFactory = new NewMotorcycleFactory("新機車工廠"); let adapter = new NewMotorcycleFactoryAdapter(newMotorcycleFactory);
adapter.produce();
|
Bridge Pattern
假設你想要生產機車,會需要像是引擎跟底盤等等屬性。
當如果要增加引擎、底盤的種類來組出新款機車,就需要 Bridge pattern,讓機車實作後只需要呼叫 Bridge 介面的方法即可。
總結來說,Bridge pattern 可以幫助你在物件的實作和介面之間建立 Bridge 關係,讓你可以更靈活地應對系統的變化。
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70
| class SportBikeEngine { start() { console.log("Starting sport bike engine..."); } }
class CruiserEngine { start() { console.log("Starting cruiser engine..."); } }
class SportBikeChassis { ride() { console.log("Riding sport bike chassis..."); } }
class CruiserChassis { ride() { console.log("Riding cruiser chassis..."); } }
class Motorcycle { constructor(brand, engineType, chassisType) { this.brand = brand; this.engineType = engineType; this.chassisType = chassisType; }
start() { this.engineType.start(); }
ride() { this.chassisType.ride(); } }
class BridgeBike extends Motorcycle { constructor(brand, engineType, chassisType) { super(brand, engineType, chassisType); }
riding() { this.ride(); } }
const sportBikeEngine = new SportBikeEngine(); const cruiserEngine = new CruiserEngine();
const sportBikeChassis = new SportBikeChassis(); const cruiserChassis = new CruiserChassis();
const sportBike = new BridgeBike("Honda", sportBikeEngine, sportBikeChassis); const cruiser = new BridgeBike("SYM", cruiserEngine, cruiserChassis); const mixedMotor = new BridgeBike("Custom", sportBikeEngine, cruiserChassis);
sportBike.start(); sportBike.riding();
cruiser.start(); cruiser.riding();
mixedMotor.start(); mixedMotor.riding();
|
Facade Pattern
你各位知道嗎?! React 最常用的竟然用的就是 Facade Pattern!
是把一堆難懂的東西,包裝成一個簡單易懂的東西,讓使用者用起來更方便。
以單純的 JavaScript 範例來說,Google Map API 就是一個 Facade Pattern,透過一個 Map 物件把複雜的圖層與地理資訊操作封裝起來。
1 2 3 4 5 6 7 8 9 10
| let map;
function initMap() { map = new google.maps.Map(document.getElementById("map"), { center: { lat: -34.397, lng: 150.644 }, zoom: 8, }); }
window.initMap = initMap;
|
React 的元件跟 Hooks 也是異曲同工之妙,useSWR
來說就封裝了 data、error、loading 的邏輯。
而元件則是把實作都包裝在元件中,我們只需要關注傳入的 props 就可以運用元件。
1 2 3
| const { data, error, isLoading } = useSWR("/api/user", fetcher);
<BreadCrumb model={items} home={home} />;
|
Flyweight Pattern
當需要大量創建相同或類似的物件時,可以使用 Flyweight Pattern 模式,讓這些物件共用一個記憶體空間,從而減少記憶體的使用量。
其實也就是之前提到的單體模式的延伸
1 2 3 4 5 6 7 8 9 10 11
| class Motorcycle { constructor(brand, model, color) { if (instance) return instance; if (!instance) { this.brand = brand; this.model = model; this.color = color; instance = this; } } }
|
可以進一步的建立機車工廠來做一個 Flyweight Pattern
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21
| const MotorcycleFactory = (function () { const motorcyclePool = {};
function getMotorcycle(brand, model, color) { const key = brand + model + color;
if (!motorcyclePool[key]) { motorcyclePool[key] = new Motorcycle(brand, model, color); }
return motorcyclePool[key]; }
return { getMotorcycle: getMotorcycle, }; })();
const motorcycle1 = MotorcycleFactory.getMotorcycle("Yamaha", "NMAX", "Black"); const motorcycle2 = MotorcycleFactory.getMotorcycle("Honda", "PCX", "Red"); const motorcycle3 = MotorcycleFactory.getMotorcycle("Yamaha", "NMAX", "Black");
|
喜歡這篇文章,請幫忙拍拍手喔 🤣