访问者模式 -- 大话设计模式
在今天,读书有时是件“麻烦”事。它需要你付出时间,付出精力,还要付出一份心境。--仅以《大话设计模式》来祭奠那逝去的……
访问者模式:表示作用于某对象结构中的各元素操作。它使你可以在不改变各元素类的前提下作用于这些元素的新操作
大多时候你并不需要访问者模式,但当你一旦需要访问者模式时,那就真的需要它了
1.男人和女人的区别
男人成功时,背后往往有一个伟大的女人;女人成功时,背后往往有一个不成功的男人;
将成功、失败和结婚等抽象成状态类,再定义一个人类抽象类(该抽象类,并非真正的人类抽象类,并不包含人类所具有的属性和行为)
/// <summary>
/// 人类抽象类(并非真正的人类抽象类,并不包含人类所具有的属性和行为)
/// </summary>
public abstract class PersonElement
{
/// <summary>
/// 定义一个accept操作,它以一个访问者为参数
/// </summary>
public abstract void Accept(Action visitor);
}
/// <summary>
/// 状态抽象类(将男人或者女人的结论、反应抽象为状态)
/// </summary>
public abstract class Action
{
public abstract void GetManConclusion(ManElement elementA);
public abstract void GetWomanConclusion(WomanElement elementB);
}
定义成功、失败和结婚等状态类
/// <summary>
/// 成功(PersonElement成功的Action)
/// </summary>
public class Success : Action
{
public override void GetManConclusion(ManElement elementA)
{
Console.WriteLine("男人成功时,背后多半有一个伟大的女人");
}
public override void GetWomanConclusion(WomanElement elementB)
{
Console.WriteLine("女人成功时,背后多半有一个不成功的男人");
}
}
定义“男人”和“女人”,当他们接受Actoin所访问时,做出相应处理(这里包含一个双分派技术,首先客户端程序中将具体的Action作为参数传给了“男人”完成了一次分派,然后“男人”调用参数所拥有的获取男人反应行为,将自己this作为参数传递了进去,完成第二次分派)
/// <summary>
/// 男人类
/// </summary>
public class ManElement : PersonElement
{
public override void Accept(Action visitor)
{
visitor.GetManConclusion(this);
}
}
/// <summary>
/// 女人类
/// </summary>
public class WomanElement : PersonElement
{
public override void Accept(Action visitor)
{
visitor.GetWomanConclusion(this);
}
}
由于总是需要“男人”和”女人“在不同的状态对比,因此定义该类进行遍历,得到不同的反应(客户端调用时,可以使用也可以不使用)
/// <summary>
/// 对象结构类(由于总是需要“男人”和”女人“在不同的状态对比,因此定义该类进行遍历,得到不同的反应)
/// </summary>
public class ObjectStructure
{
private IList<PersonElement> elements = new List<PersonElement>();
/// <summary>
/// 添加元素
/// </summary>
public void Attach(PersonElement element)
{
elements.Add(element);
}
/// <summary>
/// 移除元素
/// </summary>
public void Detach(PersonElement element)
{
elements.Remove(element);
}
/// <summary>
/// 查看显示
/// </summary>
public void Display(Action visitor)
{
foreach (var v in elements)
{
v.Accept(visitor);
}
}
}
开启场景模拟
static void Main(string[] args)
{
//面对成功
Success v1 = new Success();
//男人的结果
new ManElement().Accept(v1);
//女人的结果
new WomanElement().Accept(v1);
//使用结构对象进行遍历
ObjectStructure o = new ObjectStructure();
o.Attach(new ManElement());
o.Attach(new WomanElement());
o.Display(v1);
}

浙公网安备 33010602011771号