设计模式学习笔记(二十四)Visitor访问者(行为型模式)

背景:类层次结构的变化。类层次结构中可能经常由于引入新的操作而使类型变得脆弱。

动机(Motivation)

在软件构建过程中,由于需求的改变,某些类层次结构中常常需要增加新的行为(方法),如果直接在基类中做这样的更改,将会给子类带来很繁重的变更负担,甚至破坏原有设计。

如何在不更改类层次结构的前提下,在运行时根据需要透明地为类层次结构上的各个类动态添加新的操作,从而避免上述问题?


意图(Intent)

表示一个作用于某对象结构中各元素的操作,它可以在不改变各元素的类的前提下定义作用于这些元素的新的操作。
                                ——《设计模式》GoF


示例代码


//未使用Visitor模式时出现的问题

abstract class Shape
{
 public abstract void Draw();
 
 //如果在类层次建立之后再建立以下方法——造成所有子类必须更改,否则编译会出错
 public abstract void MoveTo(Point p);
 
}

public class Rectangle:Shape
{
 public override void Draw()
 {
  //...
  
 }
}

public class Circle:Shape
{
 public override void Draw()
 {
  //...
  
 }
}

 


//使用Visitor模式的代码

abstract class Shape
{
 public abstract void Draw();
 
 //预料到将来可能会引入新的操作
 public abstract void Accept(ShapeVisitor visitor);
 
}


public abstract class ShapeVisitor
{
 public abstract void Visit(Rectangle shape);
 
 public abstract void Visit(Circle shape);
  
}


public class Rectangle:Shape
{
 public override void Draw()
 {
  //...
  
 }
 
 public override void Accept(ShapeVisitor v)
 {
  v.Visit(this);
 }
}

public class Circle:Shape
{
 public override void Draw()
 {
  //...
  
 }
 
 public override void Accept(ShapeVisitor v)
 {
  v.Visit(this);
 }
 
}


public class MyVisitor:ShapeVisitor
{
 public override void Visit(Rectangle shape)
 {
  //增加对Rectangle的操作
 }
 public override void Visit(Circle shape)
 {
  //增加对Circle的操作
 }
  
}

class App
{
 ShapeVisitor visitor;
 
 public App(ShapeVisitor visitor)
 {
  this.visitor = visitor;
 }
 public static void Process(Shape shape)
 {
  shape.Accept(visitor);
  //...
  
 }
}

/***************

App app = new App(new Myvisotor());
app.Process(new Circle());

***************/


Visitor模式的几个要点

1)Visitor模式通过所谓“双重分发”(Double dispatch)来实现在不更改Element类层次结构的前提下,在运行旱船暖为类层次结构上的各个类动态添加新的操作。
2)所谓双重分发即Visitor模式中间包括了两个多态分发(注意其中的多态机制):第一个为accept方法的多态辨析;第二个为visit方法的多态辨析。
3)Visitor模式的最大缺点在于基类层次结构(增加新的Element子类),会导致Visitor类的改变。因此Visitor模式适用于“Element类层次结构稳定,而其中的操作却经常面临频繁改动”。

 

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

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值