通过在Chipotle用餐了解模板方法设计模式

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:

涉及四个步骤:

  1. Choose a “vessel”: Burrito vs. Bowl vs. Tacos vs. Salad

    选择一个“容器”:墨西哥卷饼,碗,玉米饼和沙拉
  2. Add meat: Chicken vs Steak vs. Barbacoa vs. Carnitas vs. Vegetarian

    添加肉类:鸡肉vs牛排vs. Barbacoa vs. Carnitas vs.素食主义者
  3. Add toppings: Tomato vs. Corn vs. Green Chili vs. Red Chili

    添加浇头:番茄,玉米,绿色辣椒,红色辣椒
  4. 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订购时,我们只能拿到番茄作为浇头,而没有多余的东西。 因此,我们的选择仅限于:

  1. Vessel: Burrito vs. Bowl vs. Tacos vs. Salad

    船只:墨西哥卷饼vs.碗vs.炸玉米饼vs.沙拉
  2. Meat: Chicken vs. Steak vs. Barbacoa vs. Carnitas vs. Vegetarian

    肉类:鸡肉,牛排,Barbacoa,Carnitas和素食主义者
  3. Toppings: Tomato

    浇头:番茄
  4. 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退出并让DietOrderSihuiDietOrderAmber继承是有意义的

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?

这听起来不完全像我们对DietOrderSihuiDietOrder / 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.

在我们的例子中,不同的部分是vesselmeatis_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 =&gt;

<两个设计原理 >

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/

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值