by Sihui Huang
黃思慧
通過在Chipotle用餐了解模板方法設計模式 (Understanding the Template Method design pattern by eating at Chipotle)
Object-Oriented Design Patterns in Life— gain an intuitive understanding of OO design patterns by linking them with real-life examples.
生活中的面向對象設計模式-通過將它們與實際示例聯系起來,可以直觀地了解OO設計模式。
Template Method is a commonly used design pattern in programming and real life.
模板方法是編程和現實生活中常用的設計模式。
Before we dive into details of the pattern, let’s learn an important life lesson:
在深入研究模式的細節之前,讓我們學習一個重要的人生課程:
Chipotle 101:如何在Chipotle訂購。 (Chipotle 101: How to Order at Chipotle.)
There are four steps involved:
涉及四個步驟:
- Choose a “vessel”: Burrito vs. Bowl vs. Tacos vs. Salad 選擇一個“容器”:墨西哥卷餅,碗,玉米餅和沙拉
- Add meat: Chicken vs Steak vs. Barbacoa vs. Carnitas vs. Vegetarian 添加肉類:雞肉vs牛排vs. Barbacoa vs. Carnitas vs.素食主義者
- Add toppings: Tomato vs. Corn vs. Green Chili vs. Red Chili 添加澆頭:番茄,玉米,綠色辣椒,紅色辣椒
- Add extras & drinks: Chips vs. Guacamole vs. Salsa vs. Beer vs. Soda 添加額外功能和飲料:薯片,鱷梨調味醬,鱷梨醬,莎莎,啤酒和汽水
For example, my go-to order is Bowl + Steak + (Tomato + Corn) + Guacamole and my friend Amber’s go-to order is Burrito + Chicken + (Green Chili + Red Chili) + (Chips + Soda).
例如,我的下單是碗+牛排+(番茄+玉米)+鱷梨調味醬,而我的朋友琥珀的下單是墨西哥卷餅+雞肉+(綠辣椒+紅辣椒)+(薯片+蘇打)。
If we code our go-to orders in Ruby, they will look like:
如果我們使用Ruby編寫轉到訂單,則它們將如下所示:
When we order, we put everything we want into the vessel and return the stuffed vessel.
訂購時,我們會將所需的所有物品放入容器中,然后將填充的容器退還。
Unfortunately, Amber and I decided to go on a diet for a while. And we decided that when we ordered from Chipotle, we could only get tomato as a topping and no extras. So our choices are limited to:
不幸的是,我和琥珀決定節食一段時間。 然后我們決定,當我們從Chipotle訂購時,我們只能拿到番茄作為澆頭,而沒有多余的東西。 因此,我們的選擇僅限于:
- Vessel: Burrito vs. Bowl vs. Tacos vs. Salad 船只:墨西哥卷餅vs.碗vs.炸玉米餅vs.沙拉
- Meat: Chicken vs. Steak vs. Barbacoa vs. Carnitas vs. Vegetarian 肉類:雞肉,牛排,Barbacoa,Carnitas和素食主義者
- Toppings: Tomato 澆頭:番茄
- No extras & drinks 沒有額外的東西和飲料
During the diet, our go-to orders have to be modified to:
在節食期間,我們的常用訂單必須修改為:
- Sihui: Bowl + Steak + Tomato + No extras & drinks 四會:碗+牛排+番茄+沒有額外的飲料
- Amber: Burrito + Chicken + Tomato + No extras & drinks 琥珀色:墨西哥卷餅+雞肉+番茄+沒有額外的飲料
Putting our orders down in Ruby, we have the following:
在Ruby中下訂單,我們有以下幾點:
Since both our orders have the exact same toppings, extras, and order methods, it makes sense to pull them out as a parent class, DietOrder, and have DietOrderSihui and DietOrderAmber inherit from it.
由于我們的兩個訂單都具有完全相同的澆頭 , 附加功能和訂購方法,因此將它們作為父類DietOrder退出并讓DietOrderSihui和DietOrderAmber繼承是有意義的 。
Now our friend Ben wants to join our Chipotle Diet Club, and he likes Tacos with Carnitas. Then his order will be:
現在,我們的朋友Ben想加入我們的Chipotle Diet Club,他喜歡帶有肉堿的炸玉米餅。 那么他的命令將是:
Ta-da, you just learned the Template Method design pattern! ? ? ?
Ta-da,您剛剛了解了Template Method設計模式! ? ? ?
Don’t believe me?
不相信我嗎
Take a look at the definition of the Template Method:
看一下Template方法的定義:
The Template Method pattern is a behavioral design pattern that
模板方法模式是一種行為設計模式,
- defines the program skeleton of an algorithm in an operation,
-定義運算中算法的程序框架,
- deferrs some steps to subclasses.
-將某些步驟推遲到子類。
It lets one redefine certain steps of an algorithm without changing the algorithm’s structure.
它允許重新定義算法的某些步驟,而無需更改算法的結構。
Doesn’t this sound exactly like what we just did with our DietOrder and SihuiDietOrder/AmberDietOrder/BenDietOrder?
這聽起來不完全像我們對DietOrder和SihuiDietOrder / AmberDietOrder / BenDietOrder所做的那樣嗎?
DietOrder defines the order skeleton: one can only get tomato as a topping and no extras & drinks, and one orders by picking a vessel and putting everything inside the chosen vessel.
DietOrder定義了訂單框架:一個人只能獲得番茄作為澆頭,而沒有額外的飲料,而一個訂單則是通過撿起一個容器并將所有東西放入選定的容器中來完成的。
SihuiDietOrder/AmberDietOrder/BenDietOrder redefine the vessel and meat depending on our personal preferences.
SihuiDietOrder / AmberDietOrder / BenDietOrder根據我們的個人喜好重新定義容器和肉類。
Let’s say a month passed by, and Amber and I followed our diet strictly. We decided to reward ourselves with cheat days!
假設過去了一個月,我和Amber嚴格遵守飲食習慣。 我們決定用作弊的日子來獎勵自己!
On a cheat day, we have soda as our drinks. ??? And each of us can decide which day of the month will be our cheat day.
在作弊的一天,我們喝蘇打水。 ??? 而且我們每個人都可以決定每月的哪一天是我們的作弊日。
Since Ben is new to the club, he decides to stick to the diet strictly for a bit longer.
由于本是俱樂部的新成員,他決定嚴格堅持飲食更長的時間。
Let’s see how it looks in Ruby:
讓我們看看它在Ruby中的外觀:
In DietOrder, we ask if today is a cheat day. If so, we can have Soda as an extra. Otherwise, there are no extras. And by default, today is not a cheat day.
在DietOrder中 ,我們詢問今天是否是作弊日。 如果是這樣,我們可以額外提供汽水。 否則,將沒有額外費用。 而且默認情況下,今天不是騙人的日子。
Amber and I get to define our own cheat days:
我和琥珀要定義自己的作弊天數:
Since Ben is sticking with the diet strictly, he doesn’t get a cheat day.
由于本嚴格遵守飲食習慣,所以他一天都不會作弊。
His class doesn’t need to change.
他的課不需要改變。
The is_cheat_day? method is a hook.
is_cheat_day? 方法是一個鉤子。
A hook provides a way for a subclass to implement an optional part of an algorithm.
鉤子為子類提供了一種實現算法的可選部分的方法。
If the subclass doesn’t care about the part, it can skip it and use the default implementation in the parent class.
如果子類不關心該部分,則可以跳過該部分,并使用父類中的默認實現。
In our case, is_cheat_day? is optional. SihuiDietOrder and AmberDietOrder implement it because we want to have a cheat day each month. But Ben does not want to have a cheat day. So BenDietOrder skips implementing is_cheat_day? and uses the default one from DietOrder, which always returns false.
在我們的情況下, is_cheat_day? 是可選的。 SihuiDietOrder和AmberDietOrder實現了它,因為我們希望每個月都有一個作弊日。 但本不想不想作弊。 所以BenDietOrder跳過實現is_cheat_day嗎? 并使用DietOrder中的默認值(始終返回false)。
There are two important object-oriented design principles used in the Template Method:
模板方法中使用了兩個重要的面向對象設計原則:
1. Encapsulate what varies.
1.封裝變化的內容。
In our case, the varying parts are vessel, meat, and is_cheat_day?. We encapsulate them in subclasses. For the parts that don’t vary, toppings and extras, we leave them in the parent class.
在我們的例子中,不同的部分是vessel , meat和is_cheat_day ?。 我們將它們封裝在子類中。 對于不變的部分, 澆頭和附加料 ,我們將其留在父類中。
2. The Hollywood Principle: Don’t call us, we’ll call you.
2.好萊塢原則:請勿致電給我們,我們會致電給您。
Yes, The Hollywood Principle is a real thing.
是的,好萊塢原則是真實的東西 。
In Hollywood, movie producers will tell actors: “Don’t call us, we’ll call you if we find a role that fits you.”
在好萊塢,電影制片人會告訴演員:“不要打電話給我們,如果找到適合您的角色,我們就會打電話給您。”
In programming, low-level components can participate in the computation, like AmberDietOrder defining its own is_cheat_day?, but the high-level components control when and how, like DietOrder calls is_cheat_day? within extras.
在編程中,低級組件可以參與計算,例如AmberDietOrder定義自己的is_cheat_day?。 ,但高層組件控制何時和如何,例如DietOrder調用is_cheat_day? 在額外費用內。
外賣: (Takeaways:)
One definition =>
<一個定義= >
The Template Method pattern is a behavioral design pattern that
模板方法模式是一種行為設計模式,
- defines the program skeleton of an algorithm in an operation,
-定義運算中算法的程序框架,
- deferrs some steps to subclasses.
-將某些步驟推遲到子類。
It lets one redefine certain steps of an algorithm without changing the algorithm’s structure.
它允許重新定義算法的某些步驟,而無需更改算法的結構。
Two Design Principles =>
<兩個設計原理 >
1. Encapsulate what varies.
1.封裝變化的內容。
2. The Hollywood Principle: Don’t call us, we’ll call you.
2.好萊塢原則:請勿致電我們,我們會致電給您。
Or…
要么…
you can just take away a Chipotle order ? ? ?
您可以拿走一份Chipotle訂單嗎? ? ?
Next time, we take our design & food adventure to ???
下次,我們將我們的設計和美食之旅帶到???
翻譯自: https://www.freecodecamp.org/news/understanding-the-template-method-design-pattern-by-eating-at-chipotle-37f6e029f065/