ruby s设计模式_设计模式:生活与Ruby中的指挥与礼宾

ruby s设计模式

by Sihui Huang

黄思慧

设计模式:生活与Ruby中的指挥与礼宾 (Design Patterns: Command and Concierge in Life and Ruby)

The Command Pattern’s definition is a stressful one to look at. The formal definition is that it:

命令模式的定义是一个令人费解的定义。 正式定义是:

  • encapsulates a request as an object

    将请求封装为对象
  • thereby letting you parameterize other objects with different requests, queue or log requests, and support undoable operations.

    因此,您可以使用不同的请求,队列或日志请求来参数化其他对象,并支持可撤消的操作。

Let’s forget about it for a second and take a trip to Hawaii.

让我们先忘记它,然后去夏威夷旅行。

And live in a luxury hotel.

并住在豪华酒店。

We spent the day on the beach, scuba dived, and did some sightseeing. It’s time to get back to the hotel to chill, eat, and plan for the next day.

我们在沙滩上度过了一天,潜水了,并做了一些观光活动。 现在该回到酒店放松,饮食并计划第二天了。

After getting back to the hotel, we want to:

回到酒店后,我们要:

  1. Get room service for dinner

    享用晚餐的客房服务
  2. Get laundry service because we didn’t bring extra clothes

    因为我们没有带额外的衣服而获得洗衣服务
  3. Get a travel guide for Kauai, the island we are going to tomorrow

    获取前往明天要去的岛屿考艾岛的旅行指南

We check out the hotel’s service menu and find three service items matching our needs.

我们查看酒店的服务菜单,找到三个符合我们需求的服务项目。

We then call the front desk to place these three requests. A concierge picks up our call, writes down our list of requests, and acts on each service request as instructed by the service menu.

然后,我们致电前台提出这三个请求。 礼宾服务员接听我们的电话,写下我们的请求列表,并按照服务菜单的指示处理每个服务请求。

Then each staff member executes according to each specific request:

然后,每个员工根据每个特定的请求执行:

  1. The chef in the kitchen starts cooking

    厨房的厨师开始做饭
  2. The cleaning department send a staff to our room to pick up our clothes

    清洁部门派工作人员到我们房间去洗衣服
  3. The staff in the lobby grabs a travel guide and delivers it to our room

    大堂的工作人员抓住旅行指南并将其送到我们的房间

Let’s recap what just happened.

让我们回顾一下刚刚发生的事情。

a. We selected the services we wanted from the menu and submitted them to a concierge.

一个。 我们从菜单中选择了所需的服务,并将其提交给礼宾服务。

b. The concierge wrote these service requests down as a list.

b。 礼宾员将这些服务请求记为列表。

c. After we hung up, instructed by the service menu, the concierge sent our requests to corresponding departments.

C。 挂断电话后,根据服务菜单的指示,礼宾部将我们的请求发送到了相应的部门。

d. Each department executed on the given request.

d。 每个部门都根据给定的请求执行。

让我们看看Ruby中的动作。 (Let’s see the actions in Ruby.)

1. We submitted these three requests to the concierge:

1.我们向看门人提交了这三个请求:

2. These requests went into a list the concierge keeps track of:

2.这些请求进入了礼宾跟踪的列表:

Let’s see that in action (console):

让我们看看实际情况(控制台):

As we can see, after we submitted three requests, these requests were in a request_list taking care by concierge.

正如我们所看到的,之后we提出三个请求,这些请求是在一个request_list通过照顾concierge

3. Instructed by the service menu, the concierge sent our requests to corresponding departments.

3.在服务菜单的指导下,礼宾部将我们的请求发送到了相应的部门。

The code above should work fine.

上面的代码应该可以正常工作。

Except for one thing….

除了一件事…。

It smells bad.

气味不好。

Specifically, the part where we have the switch cases:

具体来说,我们拥有开关盒的部分:

Why does this part smell bad?

为什么这部分气味难闻?

  1. If the hotel offers twenty services, instead of three, the method will be really long.

    如果酒店提供二十项服务,而不是三项,则方法将非常漫长。
  2. We want to offer new services or remove an existing service. However, each time we have to open the Concierge class and redefine the act_on_requestsmethod.

    我们要提供新服务或删除现有服务。 但是,每次我们必须打开Concierge类并重新定义act_on_requests方法。

The method knows too much and requires frequent changes. Having these two combinations together is almost always a bad thing.

方法了解太多,需要经常进行更改将这两种组合在一起几乎总是一件坏事。

Why?

为什么?

A method that requires frequent changes is a method you need to update often. Each time you update a piece of code is an opportunity to introduce new bugs to the system.

需要频繁更改的方法是您需要经常更新的方法。 每次更新一段代码时,都有机会向系统引入新的错误。

When the method also knows a ton — and it’s long — the chances of messing it up when updating increases significantly. That’s the reasoning behind a design principle we talked about earlierencapsulate what varies.

如果该方法还知道很多(而且很长),那么在更新时将其弄乱的可能性就会大大增加。 这就是我们前面提到的设计原则背后的原因- 封装变化。

该重构了! (Time to Refactor!)

There must be a better way than this:

肯定有比这更好的方法:

Take a closer look and think about it.

仔细看看并考虑一下。

Let’s rephrase what the code is doing in English. We loop through the requests on the request list. For each request, according to its service type, we give the corresponding department related data and execute the request. Essentially, we loop through the requests and execute each of them accordingly.

让我们重新说明一下代码在用英语做什么。 我们遍历请求列表中的请求。 对于每个请求,我们根据其服务类型提供相应部门的相关数据并执行该请求。 本质上,我们遍历请求并相应地执行每个请求。

But what if each request actually knew how to execute itself?

但是,如果每个请求实际上都知道如何执行该怎么办?

Then the method can be as simple as:

然后该方法可以很简单:

Instead of letting the act_on_requests method decide how each request should be handled, we distribute that responsibility and knowledge back to each request and let it decide how to itself should be handled.

与其让act_on_requests方法决定如何处理每个请求, act_on_requests将责任和知识分配回每个请求并让其决定如何处理自身。

With that being said, our requests could look like this:

话虽如此,我们的要求可能如下所示:

And the updated Concierge will look like:

更新后的Concierge将如下所示:

With the updated codes, here is how we, customers of the hotel, send requests to the concierge.

使用更新的代码,这就是我们(酒店的客户)如何向礼宾发送请求。

It is pretty easy to create another service.

创建另一个服务非常容易。

For example, the hotel also allows us to reserve SPA:

例如,酒店还允许我们预订SPA:

The service not only supports execute (making a spa reservation) but also undo (canceling the reservation).

该服务不仅支持execute (进行水疗中心预订),还支持undo (取消水疗中心预订)。

Let’s say the hotel also provides another way to request services without having to call the concierge — a service requesting panel:

假设酒店还提供了另一种无需致电礼宾即可请求服务的方式-服务请求面板:

We can just press the button and the service with a default setting will be delivered to our room.

我们只需按一下按钮,默认设置的服务就会被发送到我们的房间。

Here is the code for the ServicePanel:

这是ServicePanel的代码:

And here is how we can create a service panel:

这是我们如何创建服务面板的方法:

??我们现在正在使用命令模式! (??We are now using the Command Pattern!??)

Let’s revisit the definition of the Command Pattern. It:

让我们回顾一下命令模式的定义。 它:

  • encapsulates a request as an object

    将请求封装为对象
  • thereby letting you parameterize other objects with different requests, queue or log requests, and support undoable operations.

    因此,您可以使用不同的请求,队列或日志请求来参数化其他对象,并支持可撤消的操作。
1. “encapsulates a request as an object”
1.“将请求封装为对象”

Each of the services classes we created, RoomService, LaundryService, TripPlanningService, and SpaReservationService, is an example of encapsulating a request as an object.

我们创建的每个服务类RoomServiceLaundryServiceTripPlanningServiceSpaReservationService都是将请求封装为对象的示例。

Recap:

回顾:

2. “thereby letting you parameterize other objects with different requests,”
2.“因此,您可以用不同的请求来参数化其他对象,”

The ServicePanel is an example of parameterizing an object with different requests.

ServicePanel是使用不同请求参数化对象的示例。

Recap:

回顾:

3. “queue or log requests,”
3.“排队或记录请求”

Our requests were queued while the concierge was taking them over the phone.

当礼宾部接听电话时,我们的请求已排队。

Recap:

回顾:

4. and support undoable operations.
4.并支持不可撤销的操作。

SpaReservationService supports undo.

SpaReservationService支持undo

Recap:

回顾:

Thanks for reading!

谢谢阅读!

Don’t forget to subscribe. :D

不要忘记订阅。 :D

This was originally published on my blog, Design patterns in life and Ruby.

这最初发表在我的博客《 生活中的设计模式》和《 Ruby》中

翻译自: https://www.freecodecamp.org/news/design-patterns-command-and-concierge-in-life-and-ruby-aab9815817ea/

ruby s设计模式

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值