真功夫餐厅推出了套餐系列,所有套餐都由炖汤+快餐饭+小食组成。
目前餐厅提供的套餐如下:
套餐一:花旗参鸡汤+排骨饭+卤蛋。
套餐二:虫草花老鸭汤+叉烧饭+蒸蛋。
不同的套餐由不同的套餐厨师在服务员的指挥下加工制作。如顾客点了套餐一,服务员就让负责制作套餐一的厨师先初始化套餐一(生成套餐一对象)、然后做炖汤,做快餐饭,做小食,最后返回套餐一;如顾客点了套餐二,服务员就让负责制作套餐二的厨师先初始化套餐二(生成套餐二对象)、然后做炖汤,做快餐饭,做小食,最后返回套餐二;将来还要方便推出更多品种的套餐。
请给出设计方案来模拟场景:顾客先点了套餐一,再点了套餐二。
(作答时可以在较详细地描述设计思路后画出类图,也可以简单描述设计思路后直接给出java代码)
正确答案:
套餐是复杂产品,由炖汤、快餐饭和小食三部分构成,复杂对象的创建适合采用建造者模式。
可以这样来模拟:
套餐作为复杂产品类,包含套餐名、炖汤、快餐饭、小食这几个属性(简单起见这几个属性都可以设置为字符串类型)。套餐厨师作为抽象建造者,是一个抽象类,包含一个套餐引用,有初始化套餐方法和做炖汤、做快餐饭和做小食这四个抽象方法,有一个返回套餐的普通方法,该方法直接将套餐引用返回。
套餐一厨师和套餐二厨师作为具体建造者继承自套餐厨师。套餐一厨师的初始化套餐方法就是创建一个套餐对象并赋值给套餐引用然后将该套餐对象的套餐名设置为套餐一,其做炖汤方法就是将套餐对象的炖汤属性设置为花旗参鸡汤,其做快餐饭方法就是将套餐对象的快餐饭属性设置为排骨饭,其做小食方法就是将套餐对象的小食属性设置为卤蛋。套餐二厨师的初始化套餐方法就是创建一个套餐对象并赋值给套餐引用然后将该套餐对象的套餐名设置为套餐二,其做炖汤方法就是将套餐对象的炖汤属性设置为虫草花老鸭汤,其做快餐饭方法就是将套餐对象的快餐饭属性设置为叉烧饭,其做小食方法就是将套餐对象的小食属性设置为蒸蛋。
定义一个服务员类作为指挥者类,该服务员类中包含有两个套餐厨师引用,其中一个套餐厨师引用指向一个套餐一厨师对象,另一个套餐厨师引用指向一个套餐二厨师对象,包含一个制作套餐方法,制作套餐方法的返回值是一个套餐引用,包含一个套餐厨师引用参数,在制作套餐方法中依次调用该套餐厨师引用参数的初始化快餐方法、做炖汤方法、做快餐饭方法、做小食方法和返回快餐方法。服务员类还包含一个点套餐一方法和一个点套餐二方法,这两个方法的返回值都是一个套餐引用。点套餐一方法的实现就是直接调用制作快餐方法,调用时将套餐一厨师对象的引用传递给该方法作为参数;点套餐二方法的实现就是直接调用制作快餐方法,调用时将套餐二厨师对象的引用传递给该方法作为参数。
这样的话在客户端先创建服务员对象,然后调用其点套餐一方法和点套餐二方法先后获得套餐一对象和套餐二对象就好。(当然设计方案不是唯一的,也可以让服务员类中不包含套餐厨师引用,只有一个制作套餐方法,在客户端中创建一个套餐一厨师对象和一个套餐二厨师对象。点套餐一时就调用服务员的制作套餐方法,将套餐一厨师对象传递给该方法;点套餐二时同样是调用服务员的制作套餐方法,只是将套餐二厨师对象传递给该方法)