由于需求的改变,某些类常常需要增加新的功能,但由于种种原因这些类层次必须保持稳定,不允许开发人员随意修改。对此,访问者模式可以在不更改类层次结构的前提下透明的为各个类动态添加新的功能。
访问者模式通过双重分派(double dispatch)的方法来透明的为各个类添加新的功能,第一重分派是指Accept方法的多态,第二重分派是指Visit方法的多态。
public abstract class Visitor
{
public abstract void Put(Goods tv);
}
public class SizeVisitor : Visitor
{
public override void Put(Goods goods)
{
Console.WriteLine("按尺寸{0}大小排放", goods.size);
}
}
public class StatusVisitor : Visitor
{
public override void Put(Goods goods)
{
Console.WriteLine("按商品新旧值{0}排放", goods.state);
}
}
public abstract class Goods
{
public abstract void Operate(Visitor visitor);
public int size
{
get;
set;
}
public int state
{
get;
set;
}
}
public class TV : Goods
{
public override void Operate(Visitor visitor)
{
visitor.Put(this);
}
}
public class Computer : Goods
{
public override void Operate(Visitor visitor)
{
visitor.Put(this);
}
}
public class StorgeDeal
{
private List<Goods> goodsList = new List<Goods>();
public void AddGoods(Goods goods)
{
goodsList.Add(goods);
}
public void Operate(Visitor visitor)
{
foreach (var item in goodsList)
{
item.Operate(visitor);
}
}
}
static void Main(string[] args)
{
StorgeDeal deal = new StorgeDeal();
deal.AddGoods(new TV());
deal.AddGoods(new Computer());
deal.Operate(new SizeVisitor());
deal.Operate(new StatusVisitor());
deal.Operate(new TestVisitor());
Console.Read();
}
优点:
1、使得新增新的访问操作变得更加简单。
2、能够使得用户在不修改现有类的层次结构下,定义该类层次结构的操作。
3、将有关元素对象的访问行为集中到一个访问者对象中,而不是分散搞一个个的元素类中。
缺点:
1、增加新的元素类很困难。在访问者模式中,每增加一个新的元素类都意味着要在抽象访问者角色中增加一个新的抽象操作,并在每一个具体访问者类中增加相应的具体操作,违背了“开闭原则”的要求。
2、破坏封装。当采用访问者模式的时候,就会打破组合类的封装。