一 概要
1.1 行为型模式
- 特别关注对象之间的通信。描述类或对象之间怎样相互协作共同完成单个对象都无法单独完成的任务,以及怎样分配职责。
1.2 定义
- 将作用于某种数据结构中的各元素的操作分离出来封装成独立的类,使其在不改变数据结构的前提下可以添加作用于这些元素的新的操作,为数据结构中的每个元素提供多种访问方式。它将对数据的操作与数据结构进行分离,是行为类模式中最复杂的一种模式。
二 UML类图
![在这里插入图片描述](https://i-blog.csdnimg.cn/blog_migrate/26dd16fa74ffa568b8866b0b47f6f9a7.png)
三 例子
class Program
{
static void Main(string[] args)
{
ObjectStructure.Add(new ElementA());
ObjectStructure.Add(new ElementB());
ObjectStructure.VisitorElement(new VisitorA());
ObjectStructure.VisitorElement(new VisitorB());
}
}
public class ObjectStructure
{
private static List<Element> elements = new List<Element>();
public static void Add(Element element)
{
elements.Add(element);
}
public static void Remove(Element element)
{
elements.Remove(element);
}
public static void VisitorElement(Visitor visitor)
{
foreach (var element in elements)
{
element.Accept(visitor);
}
}
}
public interface Element
{
void Accept(Visitor visitor);
}
public class ElementA : Element
{
public void Accept(Visitor visitor)
{
visitor.VisitElementA(this);
}
}
public class ElementB : Element
{
public void Accept(Visitor visitor)
{
visitor.VisitElementB(this);
}
}
public interface Visitor
{
void VisitElementA(ElementA elementA);
void VisitElementB(ElementB elementB);
}
public class VisitorA : Visitor
{
public void VisitElementA(ElementA elementA)
{
}
public void VisitElementB(ElementB elementB)
{
}
}
public class VisitorB : Visitor
{
public void VisitElementA(ElementA elementA)
{
}
public void VisitElementB(ElementB elementB)
{
}
}
四 优缺点
4.1 优点
- 增加新的操作比较容易。 只需要增加新的访问者。访问者将有关的行为集中到一个访问者对象中。
4.2 缺点
- 增加新的元素类很困难。在访问者模式中,每增加一个新的元素类,都要在每一个具体访问者类中增加相应的具体操作,这违背了“开闭原则”。
- 破坏封装。访问者模式中具体元素对访问者公布细节,这破坏了对象的封装性。
- 违反了依赖倒置原则。访问者模式依赖了具体类,而没有依赖抽象类。
五 使用场景
- 对象结构相对稳定,但其操作算法经常变化的程序。
- 对象结构中的对象需要提供多种不同且不相关的操作,而且要避免让这些操作的变化影响对象的结构。
- 对象结构包含很多类型的对象,希望对这些对象实施一些依赖于其具体类型的操作。