最近看了一篇关于装饰者模式的文章,深有体会,感觉在某种特定情况下通过装饰者模式来思考和组织代码真的是非常方便,下面我们通过一个例子来理解这里所说的“某种特定情况”。
最近哥开了一家开心花甲粉的小吃店,不知道你去过没有,没有的话应该去尝试一下,挺好吃的。
开心花甲粉是一家面条类的小吃店,主要的配料有:
面(米线、河粉、桂林米粉...)、油、盐、酱油、水、辣椒、胡椒粉、鸡蛋、虾、花甲(一种壳类生物)、鱿鱼、生蚝、肉丸、金针菇、香菜...
根据配料,我们能够组合多种花甲粉:
花甲粉1:面、油、盐、水、胡椒粉、虾、香菜;
花甲粉2:米线、油、盐、水、辣椒、花甲、虾、金针菇、香菜;
...
根据组合我们估计很难写的完,这就意味着,我们在实现开心花甲粉这个系统的时候,如果将每种花甲粉作为一个类录入的话,这无疑就是和自己过不去,更关键的一点是,以后如果想要扩展出来,比如有客人他喜欢加些西洋菜在粉里面,那又要在系统中录入许多类,维护起来非常艰难。显然,在这种情况下,我们已经不能够为每种花甲粉定义一个类了。
在这种非常关键的时候,装饰者模式的强大设计力量就显示出来。
那么,具体怎么做?
首先,我们明白,花甲粉是一种面食,以面料为主,其他辅料都是为面料服务的,那么
面、米线...就是被装饰者,花甲、辣椒...就是装饰者。
面、米线、花甲、辣椒...都属于食材,嗯,我们可以把它们抽象成一个食材类父类的子类。
在这里我们的代码是这样的:
接着,我们将创建一个米线的子类,这个类继承自食材类,类名是Mixian,
然后我们创建一个辅料类,这个类是盐、水、香菜、虾...的父类。
同样的,这个类首先继承自食材类,代码如下:
它有一个初始化方法initWithIngredients:withName:,意义在于通过配合其他食材进而生成新的食材,因为它们都继承自食材类,这也是装饰者模式的重点。
现在,我们来创建油、水、盐、花甲、香菜、金针菇等配料类。
类名分别是:FoodOil、Water、Salt、Clam、Caraway、NeedleMushroom。
现在,我们用上面列举的食材来创建一种花甲粉,代码如下:
运行这段代码,控制台显示: