设计模式——访问者模式

背景介绍

这里有一个 Human ,和所有人类一样,这个 Human 同样要解决他的温饱问题:
在这里插入图片描述

访问者模式解决的就是在 Food 结构稳定的前提下,需要访问 Food 及其子类。

问题出现

Human 刚开始时也像大多数人吃东西一样,吃 Meat 有 吃 Meat 的吃法,吃 Vegetable 有吃 Vegetable 的吃法:

void Human::Eat(Food* food) {
   
     if ((Meat * m = dynamic_cast<Meat *>(food)_!=NULL) {
   
                //human 吃 m
                m->MeatFunction();
     } else if ((Vegetable * v = dynamic_cast<Vegetable *>(food)_!=NULL) ) {
   
		   //human 吃 v
                v->VegetableFunction();
     }
}

但是我们很容易就看出问题:

  1. 使用 if-else 结构,多了不容易处理
  2. 使用了动态类型识别和向下转型,违背了里氏替换原则,不易扩展
  3. 由于 Meat 和 Vegetable 会有不同的外部接口,难以在 Eat 中形成一致的行为

解决问题

聪明的 Human 很快就想到,他可以将 Eat 行为的具体实现,转移到 Food 及其子类中,并在子类中给出不同的实现:
在这里插入图片描述

再次分析

我们再仔细考虑下,问题真的全部解决了吗?

  1. 如果 Human 创造了子类 Male 类和 Female 类呢
  2. 如果 Human 系列增加一个 Cook(Food *) 操作呢
    在这里插入图片描述

我们知道 Male 和 Female 吃 Food 方式是不同的。比如说 Male 对 Meat 的要求是大块的,对 Vegetable 的要求是多油的;而 Female 对 Meat 的要求是小块的,对 Vegetable 的要求则是清淡的。那么 Human 增加这两个子类后,Food 的方法实现如下:

void Meat::BeEaten(Human * human){
   
     if ( (Female * female = dynamic_cast<Female * >(human))!= NULL ) {
   
              // meat 被 female 吃
     } else if ((Male * male = dynamic_cast<Male * >(human))!= NULL ) {
   
              
  • 0
    点赞
  • 1
    收藏
    觉得还不错? 一键收藏
  • 1
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值