态度决定高度、企图决定版图、格局决定结局

导航

Visitor模式学习

意图:

表示一个作用于某对象结构中的各元素的操作。它使你可以在不改变各元素的类的前提下定义作用于这些元素的新操作。

似乎理解很麻烦,其实说白了,就是动态的给已经写好的代码(类)加入新的功能!

当然,首先,需要考虑到这个类将来需要添加功能,留下这么一个坑才行!起对应实现就是在你的类中的Accept方法.

其实,更加通俗点理解.你想给你的类添加功能,要么打开代码直接添加,要么把事情给别人做,然后给外界的感觉是这事情还是你完成的!而Visitor就是通过后者这种方式实现的.

 

看这段代码,它实现了Visitor模式,动态的给"Circle,Line"动态的添加了移动(Move)的行为:

namespace VisitorPattern
{
public abstract class Sharp
{
public virtual void Draw(){}
public virtual void Accept(Visitor v){}
}

public class Circle:Sharp
{
public override void Draw()
{
Console.WriteLine("Circle Draw");
}
public override void Accept(Visitor v)
{
v.Visit(this);
}
}
public class Line:Sharp
{
public override void Draw()
{
Console.WriteLine("Line Draw");
}
public override void Accept(Visitor v)
{
v.Visit(this);
}
}

public abstract class Visitor
{
public virtual void Visit(Circle c){}
public virtual void Visit(Line l){}
}

 

///提供Move功能的Visitor
public class MyVisitor:Visitor
{
public override void Visit(Circle c)
{
Console.WriteLine(c.ToString()+" Move");
}
public override void Visit(Line l)
{
Console.WriteLine(l.ToString()+" Move");
}
}

public class App
{
public static void Main()
{
Circle c = new Circle();
c.Draw();
MyVisitor v = new MyVisitor();
v.Visit(c);

Console.ReadLine();
}
}

}

通过最后的App客户代码调用可以看出,实际实现了Move的是MyVisitor,而不是Cricle,Line.但是结果却告诉我们,我们给Cricle,Line动态的添加了Move的行为.很不错的模式!

再次理解下,为啥要传递Cricle c ,Line l 给Vist方法 ? 其实这个完全就是一个路由指令给MyVisitor,告诉它我要调用的是哪个:它通过参数获得overload的方法.

 

看它的适用性中最重要一条:

定义对象结构的类很少改变,但经常需要在此结构上定义新的操作。改变对象结构类需要重定义对所有访问者的接口,这可能需要很大的代价。如果对象结构类经常改变,那么可能还是在这些类中定义这些操作较好。

开始接触的时候,总是以为通过Visitor模式,只能给类添加上一个新的方法.通过具体学习后,我决定尝试添加多个新的方法!

 

// 给Cricle,Line添加上一个序列到文件的方法:

public class WriteToFileVistor:Visitor
{
public override void Visit(Circle c)
{
Console.WriteLine(c.ToString()+ "序列化到文件中");
}
public override void Visit(Line l)
{
Console.WriteLine(l.ToString()+ "序列化到文件中");
}
}

//Client App

WriteToFileVistor wf = new WriteToFileVistor();
wf.Visit(new Line());

在听webcast过程中,李老师提到了"动态添加新功能"中的"动态"这个词的理解问题!是啊!确实需要严肃下,这个词,以前更多的理解是RunTime.但是很显然,Visitor模式并不是运行时添加了这些行为.所以这个理解是不全面的!

正如某些人理解灵活一样,啥叫灵活,通过选择不同传递LiseBox就叫灵活了吗?这个理解也有问题.灵活性要和系统的扩展性紧密结合才有意义!

完了!

posted on 2006-12-09 22:18  flyingchen  阅读(375)  评论(1编辑  收藏  举报