# 开一家餐厅吧

# 开一家餐厅吧(一)

# 课程目标

通过一个新的系列课程,我们来学习更多的 JavaScript 知识,比如如何在 JavaScript 使用面向对象编程,如何在你的设计中应用设计模式.

# 课程描述

需求

我们现在要开一个餐厅啦,餐厅里面有服务员,有厨师,有顾客。学习面向对象,为餐厅和几个角色创建自己的类吧。

餐厅可以招聘或者解雇职员,职员越多,就越能够满足更多的顾客需求,从而赚取更多的钱

餐厅里的容量是有限的,当顾客坐满了,其他顾客需要排队

服务员的工作有两个职责,一个是负责点菜,另外一个是上菜

厨师的职责就一个,烹饪食物

顾客可以做两件事情,一个是点菜,一个是吃

系列任务的第一个部分,我们先只实现类的编写。并通过大量阅读掌握 JavaScript 的面向对象编程

阅读

设计

下面的设计只是草案,根据自己理解和需要自行设计

  • 餐厅类
    • 属性:金钱,座位数量、职员列表
    • 方法:招聘职员,解雇职员
  • 职员类
    • 属性:ID,姓名,工资
    • 方法:完成一次工作
  • 服务员类,继承自职员
    • 完成一次工作:如果参数是个数组,则记录客人点菜,如果参数不是数组则是上菜行为
  • 厨师类,继承自职员
    • 完成一次工作:烹饪出菜品
  • 顾客类
    • 方法:点菜,吃
  • 菜品类
    • 属性:名字、烹饪成本、价格

编码

  • 请分别使用 ES5 和 ES6 来实现以上类的定义

测试用例

测试用例伪代码,在 Chrome 控制台中执行

var ifeRestaurant = new Restaurant({
    cash: 1000000,
    seats: 20,
    staff: []
});

var newCook = new Cook("Tony", 10000);
ifeRestaurant.hire(newCook);

console.log(ifeRestaurant.staff);

ifeRestaurant.fire(newCook);
console.log(ifeRestaurant.staff);

# 开一家餐厅吧(二)

# 课程目标

通过完善餐厅的功能,来学习 JavaScript 面向对象编程,及一些基本的设计模式

# 课程描述

需求

我们上个任务已经创造了各个角色,现在,我们希望让各个角色动起来。

我们假设只有一个厨师,一个服务员,一个座位。而且餐厅老板是个偏执狂,他喜欢简单,他需要保证餐厅永远只有一个厨师,一个服务员和一个座位。

整个餐厅的运作流程是这样的,顾客入座,服务员招待顾客点菜,点完菜后告诉厨师,厨师做好菜后服务员上菜,顾客用餐,然后换下一个顾客

你需要设计一个菜单,然后设计一个顾客随机点菜的方法

阅读

设计

首先,我们需要重新来设计我们的厨师、服务员的类,阅读上面的文章,按照单例的方式来进行设计

第二,我们需要解决对象与对象之间的交流问题,在这个简单的餐厅中,当顾客入座时,服务员使用服务点菜方法,调用顾客的点菜方法得到顾客点的菜,然后服务员去告诉厨师需要做什么菜,厨师开始做菜,做完菜以后告诉服务员去上菜,上菜完成后,顾客开始用餐,吃完后,下一个顾客进来。在这个流程中,你可以给每个类都创建对应的交流沟通相关的方法来实现。

第三,实现一个顾客队列

第四,实现一个菜单,包括菜名、价格,然后实现一个点菜的方法,我们默认顾客每次只点一个菜

编码

基于提供的设计思路来完成上面的需求,通过 Console.log 来打印出餐厅运作的情况

# 开一家餐厅吧(三)

# 课程目标

通过今天的练习,来继续深入练习,如何通过编程中的抽象设计、封装来解决实际问题

尝试把我们提供的学习资料中的内容,运用到任务编码中

# 课程描述

需求

在真实世界中,点菜、烹饪、用餐都是需要时间的,我们给我们的餐厅加上时间的因素。

我们假设每一个时间单位是 1 秒(可配置)。

  • 点菜需要 3 个时间单位
  • 做菜的时间不一定,每个菜需要的时间不一样,所以需要在菜单的数据中添加一个字段,描述这个菜需要用的时间,比如在 1-10 个时间单位这个区间
  • 用餐时间,每个菜的用餐时间为 3 个时间单位,如果顾客点了 n 个菜,则需要 3 * n 个时间单位 我们再做一些小调整,顾客点菜不一定只点一个了,可以是多个菜

阅读

设计

我们先做一些小的调整:

  • 菜单数据增加烹饪这个菜需要的时间的字段
  • 顾客点菜的函数变成随机点多个菜

接下来,对每一个行为加上时间的因素,我们推荐使用 Promise 的方式,然后整个流程可以如下

  • 顾客入座,顾客开始用 3 个时间单位想要吃什么菜,时间到后 then,告诉服务员
  • 服务员告诉厨师,假设他们之间交流是不需要时间的
  • 厨师开始烹饪,每烹饪好一个菜 then 叫服务员上菜,同时开始做下一个菜,先假设上菜是不需要时间的
  • 服务员上菜后,顾客开始用餐,点的全部菜都吃完后 then 付款,同时下一个顾客入座

# 把餐厅运营情况可视化出来

需求

上个任务中,我们让大家通过 Console.log 的方式来看餐厅运营情况,这次我们需要把做一个界面来展现餐厅运营情况。

另外为了逼真,很多行为都需要耗时了,具体需求如下:

  • 需要一个数字来实时显示餐厅的现金数量
  • 用一个厨师的图片,在图片附近显示厨师的状态:空闲 或者是 在做 XXX 菜,还差多少时间做完,并在旁边显示待做的菜列表
  • 用一个服务员的图片,展示服务员的状态,顾客点菜的时候,服务员在顾客这边,厨师做菜的时候,服务员在厨师那边,上菜的时候,又到了厨师那边,服务员的移动是需要时间的,在厨师和顾客之间的单程移动需要 0.5 个时间单位,这意味着:
    • 服务员给顾客点完菜后,把点的菜送到厨师那里,需要 0.5 个时间单位
    • 厨师烹饪好菜后,服务员从厨师这里上菜到顾客那里,需要 0.5 个时间单位,然后再回到厨师那里又需要 0.5 个时间单位
    • 如果你有余力,可以做成一个动画,没有时间的话,就在时间单位到后直接改变状态(文字显示或位置均可)就行
  • 用一个顾客的图片,展示顾客的状态,点菜中(并显示还差多少时间点好),点好后,显示顾客点的菜的 List 及每个菜的状态(还未上,正在吃(还差多久吃完),已吃完)
  • 有一个排队的顾客 List 显示在页面中。

需要注意:

  • 厨师做好一个菜以后,叫服务员后,就可以去做下一个菜了,不需要等服务员是否开始上菜
  • 注意优化服务员的位置,尽量使得服务员在空闲的时候,去往下一个任务的起始点。比如:
    • 上菜后,如果顾客点的菜没上完,那服务员应该回到厨师那里准备上下一个菜
    • 上菜后,如果顾客点的菜上完了,则服务员应该留在顾客旁边准备收银及服务下一个顾客

# 开一家餐厅吧(四)

# 课程目标

通过今天的练习,来继续深入练习,如何通过编程中的抽象设计、封装来解决实际问题

尝试把我们提供的学习资料中的内容,运用到任务编码中

# 课程描述

阅读

# 抠门的老板把餐厅扩建了

需求

上一个任务中,我们的餐厅只有一个厨师,一个服务员和一个座位,老板觉得赚太少了,所以要增加座位,但是老板很抠门,还是不愿意增加服务员和厨师

所以,你的厨师和服务员要同时服务好多人,而顾客的到来也不再是源源不断了,设计一个顾客随机到达的方法。

我们做几个假设

  • 服务员不能同时为多个顾客点菜,也就是说,服务员为一个顾客点完菜后,必须到厨师那里告诉厨师要做什么菜,然后再去服务下一个顾客
  • 厨师可以同时为一个菜做多份,当厨师准备做一个菜时,如果待做的列表里有同样的菜,那厨师可以一次性把几份都做出来
  • 对应上一条,服务员上菜时候可以上多份,但服务员在顾客与顾客之间移动不需要时间。 针对顾客随机到达,我们可以设计一个方法,每 n 个时间单位随机生成 m 个顾客,在有空余座位的时候,则入座,否则则排队,如果排队超过 k 个人,则后续的顾客选择不排队了去吃其他家。

依然用可视化的方式进行呈现。

设计及编码

其实这个任务和上一个任务,没有太本质的区别,多个顾客只是提升了任务量,对于厨师和服务员的调度,没有太大区别。

所以,你不妨先重构上一个任务,保证你代码中,厨师与服务员,和顾客是解耦的,这样在这个任务中,你只需要处理顾客相关的逻辑。

# 老板终于加人了

需求

老板发现,因为厨师和服务员没增加,所以虽然增加了座位,但是,收入增加得并不明显,所以他终于舍得多招一些厨师和服务员了。

在页面上新增两个按钮,分别是新增厨师和新增服务员,同时对于每个厨师和服务员,新增开除的操作。

只要有顾客需要服务,则有空的服务员第一时间去服务,如果有菜需要做,则有空的厨师开始做

设计及编码

任何一个顾客进店后,就发出一个信息(触发事件)“客人到了”,然后所有空余服务员中按某种顺序排后的第一个对这个消息进行响应并消费(进行服务),服务员为顾客点完菜后,把点菜单放在后厨白板上(发出这个信息),第一个做完菜的厨师看见这个信息后,就开始做这个菜(消费掉这条消息)。

上菜同理。

# 上了点餐 APP

需求

服务员太多太花钱,老板开发了个 APP 让顾客自己点菜,服务员只需要上菜就行了。

基于上一个任务,服务员不再需要点菜,客人入座后直接开始点菜

设计及编码

要求是,基于上一个任务,尽量不改变顾客点菜及厨师开始做菜的相关方法,考虑如何把三者进行解耦,通过消息、事件或者其他机制来实现

# 提交

把代码及预览地址进行提交

# 总结

依然把今天的学习用时,收获,问题进行记录

# 预告

下一个任务,我们将迎接全新的任务