11.设计模式之《访问器模式》

背景

在软件构建的过程中,由于需求的变化会导致所有子类都要更新,在不改变原始框架的情况下如何扩展?

例子

比如说有个水果基类,下面有苹果,橘子,香蕉, 之前的代码一般是这样写的,比如说剥皮这个函数,每个具体水果的方式不一样,会有自己的实现方式。由于需求一直增加的,可以预见到以后的还会有榨汁,油炸,刺身等各种操作,如果每次去改源代码就不行,不符合开闭原则。

//berfore
class Fruit
{
public:
   virtual void Func_1();
   virtual void Func_2();
   virtual void Func_3();
}


class Apple : public Fruit
{
public:
   virtual void Func_1() override;
   virtual void Func_2() override;
   virtual void Func_3() override;
}

class Orange : public Fruit
{
public:
   virtual void Func_1() override;
   virtual void Func_2() override;
   virtual void Func_3() override;
}

新的方式

//after
class Fruit
{
public:
   virtual void accept(Visitor& vistor) = 0;
}

class Apple : public Fruit
{
public:
   void accept(Vistor& vistor) override
   {
       vistor.visit(*this);
       //vistor.visitApple(*this);
   }
}

class Orange : public Fruit
{
public:
   void accept(Vistor& vistor) override
   {
       vistor.visit(*this);
       //vistor.visitOrange(*this);
   }
}

class Vistor
{
public:
   //可以用函数重载或者用不同函数名
   virtual void visit(Apple& a);
   virtual void visit(Orange& a);
   //virtual void visitApple(Apple& a);
   //virtual void visitOrange(Orange& a);
}
//----------------------------------------
//----------------------------------------
//新添加的操作
class Func_1 : public Vistor
{
public:
   virtual void visit(Apple& a) override;
   virtual void visit(Orange& a) override;
}

int main
{
   auto Func_1 = new Func_1();
   auto apple = new Apple();
   apple->accept(*Func_1);
}

这个设计模式有一个缺陷,就是你在使用这个类的时候要保证这个类的子类个数是确定的。

总结

为什么不用第一种方式,假如你是一个厨师,当下的水果可以煎炸炒,当时你预期未来还有人去创新新的做法,那么你就可以用visit模式,毕竟水果种类短期几百年内很难进化出新品种。

题外话,装饰模式其实也是一个不改变原始数据结构添加新的行为,其实还是有点不同,一般装饰者模式是对某个行为再加个预处理或者处理,比如炸行为,可以炸之前裹点面包糠,这种可以用装饰模式,因为在装饰模式实现的时候,需要用public来继承炸接口,所以装饰模式结束后,理论上新的接口并没有增加,只是对原来的炸行为上加了预处理。

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值