zoukankan      html  css  js  c++  java
  • 访问者模式

    访问者模式

    春天 2008-12-17 17:02:37 阅读140 评论0 字号: 订阅

    访问者模式适用于数据结构相对未定的系统,它把数据结构和作用于结构上的操作的偶合脱开,使得操作集合可以相对自由的演化。数据结构的每一结点可以接受一个访问者的调用,访问者将某种算法针对此结点执行。


    访问者模式包含;以下角色

    • 抽象访问者(IVisitor):声明一个或多个访问操作,形成所有具体元素角色必须实现的接口。
    • 具体访问者(Visitor):实现抽象访问者声明的所有接口
    • 抽象节点(AbstractNode):接受访问者对象作为参量,声明一个接受操作。
    • 具体节点(Node):实现抽象元素所规定的接受操作。
    • 结构对象(ObjectStructure):可以遍历结构中的所有元素。

    如果这样的系统有比较稳定的数据结构,又有易于变化的算法的话,使用访问者模式就是比较合适的,因为访问者模式使得算法操作的增加变得容易。反过来,如果这样一个系统的数据结构对象易于变化,经常要有新的数据对象增加进来的话,就不适合使用访问者模式。因为在访问者模式中增加新的节点很困难,要涉及到在抽象访问者和所有的具体访问者中增加新的方法。


    访问者模式的优点


    1、访问者模式使得增加新的操作变得很容易。
    如果一些操作依赖于一个复杂的结构对象的话,那么一般而言,增加新的操作会很复杂。而使用访问者模式,增加新的操作就意味着增加一个新的访问者类,因此,变得很容易。访问者模式将有关的行为集中到一个访问者对象中,而不是分散到一个个的节点类中。


    2、访问者模式可以跨过几个类的等级结构访问属于不同的等级结构的成员类。
    迭代子只能访问属于同一个类型等级结构的成员对象,而不能访问属于不同等级结构的对象。访问者模式可以做到这一点。


    3、积累状态
    每一个单独的访问者对象都集中了相关的行为,从而也就可以在访问的过程中将执行操作的状态积累在自己内部,而不是分散到很多的节点对象中。这是有益于系统维护的优点。


    访问者模式的缺点


    1、增加新的节点类变得很困难。
    每增加一个新的节点都意味着要在抽象访问者角色中增加一个新的抽象操作,并在每一个具体访问者类中增加相应的具体操作。


    2、破坏封装。

    访问者模式要求访问者对象访问并调用每一个节点对象的操作,这隐含了一个对所有节点对象的要求:它们必须暴露一些自己的操作和内部状态。不然,访问者的访问就变得没有意义。由于访问者对象自己会积累访问操作所需的状态,从而使这些状态不再存储在节点对象中,这也是破坏封装的。

    Imagenamespace DesignPattern.Visitor
    ImageImage
    Image{
    Image
    public interface IVisitor
    ImageImage
    Image{
    Image
    void Visit(NodeA node);
    Image
    void Visit(NodeB node);
    Image }

    Image
    Image
    public abstract class AbstractNode
    ImageImage
    Image{
    Image
    public abstract void Accept(IVisitor visitor);
    Image }

    Image
    Image
    public class VisitorA : IVisitor
    ImageImage
    Image{
    Image
    public void Visit(NodeA node)
    ImageImage
    Image{
    Image Console.Write(
    "Visitor A invoke : "+node.OperationA());
    Image }

    Image
    Image
    public void Visit(NodeB node)
    ImageImage
    Image{
    Image Console.Write(
    "/r/nVisitor A invoke : "+node.OperationB());
    Image }

    Image }

    Image
    Image
    public class VisitorB : IVisitor
    ImageImage
    Image{
    Image
    public void Visit(NodeA node)
    ImageImage
    Image{
    Image Console.Write(
    "Visitor B invoke : "+node.OperationA());
    Image }

    Image
    Image
    public void Visit(NodeB node)
    ImageImage
    Image{
    Image Console.Write(
    "/r/nVisitor B invoke : "+node.OperationB());
    Image }

    Image }

    Image
    Image
    public class NodeA : AbstractNode
    ImageImage
    Image{
    Image
    public override void Accept(IVisitor ivisitor)
    ImageImage
    Image{
    Image ivisitor.Visit(
    this);
    Image }

    Image
    public string OperationA()
    ImageImage
    Image{
    Image
    return "NodeA is visited";
    Image }

    Image }

    Image
    Image
    public class NodeB : AbstractNode
    ImageImage
    Image{
    Image
    public override void Accept(IVisitor ivisitor)
    ImageImage
    Image{
    Image ivisitor.Visit(
    this);
    Image }

    Image
    Image
    public string OperationB()
    ImageImage
    Image{
    Image
    return "NodeB is visited";
    Image }

    Image }

    Image
    Image
    public class ObjectStructure
    ImageImage
    Image{
    Image
    private ArrayList nodes;
    Image
    Image
    public ObjectStructure()
    ImageImage
    Image{
    Image
    this.nodes=new ArrayList();
    Image }

    Image
    Image
    public void Action(IVisitor ivisitor)
    ImageImage
    Image{
    Image
    foreach(AbstractNode node in nodes)
    Image node.Accept(ivisitor);
    Image }

    Image
    Image
    public void Add(AbstractNode node)
    ImageImage
    Image{
    Image
    this.nodes.Add(node);
    Image }

    Image }

    Image
    Image
    public class Client
    ImageImage
    Image{
    Image
    public static void Main()
    ImageImage
    Image{
    Image ObjectStructure aObjects
    =new ObjectStructure();
    Image aObjects.Add(
    new NodeA());
    Image aObjects.Add(
    new NodeB());
    Image IVisitor ivisitor
    =new VisitorA();
    Image aObjects.Action(ivisitor);
    Image }

    Image }

    Image}
  • 相关阅读:
    MySQL 对于千万级的大表要怎么优化?
    Spring Cloud中文社区
    什么是QPS,PV
    http://www.rabbitmq.com/documentation.html
    redis
    MySQL分区表
    linux命令综合
    Python-MRO
    Python3 错误和异常
    装饰器
  • 原文地址:https://www.cnblogs.com/xiayong123/p/3717281.html
Copyright © 2011-2022 走看看