实现一个LazyMan,可以按照以下方式调用:
LazyMan(“Hank”)输出:Hi! This is Hank!
LazyMan(“Hank”);
// 输出:
// Hi! This is Hank!
LazyMan(“Hank”).sleep(10).eat(“dinner”);
// 输出
// Hi! This is Hank!
// 等待10秒..
// Wake up after 10
// Eat dinner~
LazyMan(“Hank”).eat(“dinner”).eat(“supper”);
// 输出
// Hi This is Hank!
// Eat dinner~
// Eat supper~
LazyMan(“Hank”).sleepFirst(5).eat(“supper”)
//输出
//等待5秒
// Wake up after 5
// Hi This is Hank!
// Eat supper
以此类推。
考察的内容大概包括:
- 方法链式调用
- 类的使用和面向对象编程的思路
- 设计模式的应用
- 代码的解耦
- 最少知识原则,也即 迪米特法则(Law of Demeter)
- 代码的书写结构和命名
思路:
- 看题目输出示例,可以确定这是拟人化的输出,也就是说:应该编写一个类来定义一类人,叫做LazyMan。可以输出名字、吃饭、睡觉等行为。
- 从输出的句子可以看出,sleepFrist的优先级是最高的,其他行为的优先级一致。
- 从三个例子来看,都得先调用LazyMan来初始化一个人,才能继续后续行为,所以LazyMan是一个接口。
- 句子是按调用方法的次序进行顺序执行的,是一个队列。
function LazyMan(name) {
const queue = [];
const lazyMan = {
sayHi() {
queue.push(() => {
console.log(`hi this is ${name}`);
this.next();
});
},
eat(food) {
queue.push(() => {
console.log(`eat ${food}`);
this.next();
});
return this;
},
sleep(time) {
queue.push(() => {
setTimeout(() => {
console.log(`wake up after ${time}s`);
this.next();
}, time * 1000);
});
return this;
},
sleepFirst(time) {
queue.unshift(() => {
setTimeout(() => {
console.log(`wake up after ${time}s`);
this.next();
}, time * 1000);
});
return this;
},
next() {
const fn = queue.shift();
fn && fn();
},
};
lazyMan.sayHi();
setTimeout(() => {
lazyMan.next();
});
return lazyMan;
}
LazyMan('hhh')
.sleep(5)
.eat('apple')
.sleepFirst(3);
网上有一个大神写的用观察者模式写的例子,需要学习一下。