设计模式(21)---访问者模式

一、定义

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

解释:一个对象,如果它的元素是固定的,那么可以使用访问者模式定义它们的操作,使得操作可以自由的增加或者减少而不影响系统的其它部分。

二、UML类图及基本代码

基本代码:

abstract class Visitor
    {
        public abstract void VisitConcreteElementA(ConcreteElementA concreteElementA);
        public abstract void VisitConcreteElementB(ConcreteElementB concreteElementB);
    }

    class ConcreteVisitor1 : Visitor
    {
        public override void VisitConcreteElementA(ConcreteElementA concreteElementA)
        {
            Console.WriteLine("{0}被{1}访问", concreteElementA.GetType().Name, this.GetType().Name);
        }

        public override void VisitConcreteElementB(ConcreteElementB concreteElementB)
        {
            Console.WriteLine("{0}被{1}访问", concreteElementB.GetType().Name, this.GetType().Name);
        }
    }

    class ConcreteVisitor2: Visitor
    {
        public override void VisitConcreteElementA(ConcreteElementA concreteElementA)
        {
            Console.WriteLine("{0}被{1}访问", concreteElementA.GetType().Name, this.GetType().Name);
        }

        public override void VisitConcreteElementB(ConcreteElementB concreteElementB)
        {
            Console.WriteLine("{0}被{1}访问", concreteElementB.GetType().Name, this.GetType().Name);
        }
    }

    abstract class Element
    {
        public abstract void Accept(Visitor visitor);
    }

    class ConcreteElementA : Element
    {
        public override void Accept(Visitor visitor)
        {
            visitor.VisitConcreteElementA(this);
        }

        public void OperationA()
        { }
    }

    class ConcreteElementB : Element
    {
        public override void Accept(Visitor visitor)
        {
            visitor.VisitConcreteElementB(this);
        }

        public void OperationB()
        { }
    }

    class ObjectStructure
    {
        private IList<Element> elements = new List<Element>();

        public void Attach(Element element)
        {
            elements.Add(element);
        }

        public void Detach(Element element)
        {
            elements.Remove(element);
        }

        public void Accept(Visitor visitor)
        {
            foreach (Element e in elements)
            {
                e.Accept(visitor);
            }
        }
    }

客户端调用及其允许结果:

ObjectStructure os = new ObjectStructure();
            os.Attach(new ConcreteElementA());
            os.Attach(new ConcreteElementB());

            ConcreteVisitor1 v1 = new ConcreteVisitor1();
            ConcreteVisitor2 v2 = new ConcreteVisitor2();

            os.Accept(v1);
            os.Accept(v2);

三、实例说明

  介绍男人和女人之间的区别。现在元素包括男人和女人是固定的,但是它们的区别即操作不多种多样的,例如:男人成功时,背后多半有一个伟大的女人,女人成功时,背后大多有一个不成功的男人;男人失败时,闷头喝酒,谁也不用劝,女人失败时,眼泪汪汪,谁也劝不了,等等。代码说明:

首先编写抽象人类和具体的对象男人、女人:

abstract class Person
    {
        public abstract void Accept(Action action);
    }

    class Man : Person
    {
        public override void Accept(Action action)
        {
            action.GetManConclusion(this);
        }
    }

    class Woman : Person
    {
        public override void Accept(Action action)
        {
            action.GetWomanConclusion(this);
        }
    }

然后编写元素的抽象操作类和具体的操作行为:

abstract class Action
    {
        public abstract void GetManConclusion(Man concreteElementA);
        public abstract void GetWomanConclusion(Woman concreteElementB);
    }

    class Success : Action
    {
        public override void GetManConclusion(Man concreteElementA)
        {
            Console.WriteLine("{0}{1}时,背后多半有一个伟大的女人", concreteElementA.GetType().Name, this.GetType().Name);
        }

        public override void GetWomanConclusion(Woman concreteElementB)
        {
            Console.WriteLine("{0}{1}时,背后大多有一个不成功的男人", concreteElementB.GetType().Name, this.GetType().Name);
        }
    }

    class Fail : Action
    {
        public override void GetManConclusion(Man concreteElementA)
        {
            Console.WriteLine("{0}{1}时,闷头喝酒,谁也不用劝", concreteElementA.GetType().Name, this.GetType().Name);
        }

        public override void GetWomanConclusion(Woman concreteElementB)
        {
            Console.WriteLine("{0}{1}时,眼泪汪汪,谁也劝不了", concreteElementB.GetType().Name, this.GetType().Name);
        }
    }

最后编写一个结构类,它枚举元素,提供一个高层的接口以允许访问者访问它的元素

class ObjectStructure
    {
        private IList<Person> elements = new List<Person>();

        public void Attach(Person element)
        {
            elements.Add(element);
        }

        public void Detach(Person element)
        {
            elements.Remove(element);
        }

        public void Display(Action action)
        {
            foreach (Person e in elements)
            {
                e.Accept(action);
            }
        }
    }

客户端调用及其结果:

ObjectStructure os = new ObjectStructure();
            os.Attach(new Man());
            os.Attach(new Woman());

            Success s = new Success();
            os.Display(s);

            Fail f = new Fail();
            os.Display(f);

四、优缺点及适用场景

优点:

访问者模式使得添加新的操作变得容易。如果一些操作依赖于一个复杂的结构对象的话,那么一般而言,添加新的操作会变得很复杂。而使用访问者模式,增加新的操作就意味着添加一个新的访问者类。因此,使得添加新的操作变得容易。

缺点:

增加新的元素类变得困难。每增加一个新的元素意味着要在抽象访问者角色中增加一个新的抽象操作,并在每一个具体访问者类中添加相应的具体操作。

适用场景:

说白了,就是能显示其优点回避其缺点的地方都可以适用。

时间: 2024-10-14 02:28:42

设计模式(21)---访问者模式的相关文章

设计模式学习总结(21) 访问者模式

本系列主要记录设计模式的意图是什么,它要解决一个什么问题,什么时候可以使用它:它是如何解决的,掌握它的结构图,记住它的关键代码:能够想到至少两个它的应用实例,一个生活中的,一个软件中的:这个模式的优缺点是什么,其有哪些使用场景,在使用时要注意什么. 尊重作者,转载请注明晔阳的Bloghttp://blog.csdn.net/hacke2 21.访问者模式 意图:主要讲数据结构与数据操作分离 主要解决:稳定的数据结构和易变的操作耦合问题 什么时候使用:与类本不相关的,为了避免这个污染 ,使用访问者

设计模式之访问者模式(Visitor)摘录

23种GOF设计模式一般分为三大类:创建型模式.结构型模式.行为模式. 创建型模式抽象了实例化过程,它们帮助一个系统独立于如何创建.组合和表示它的那些对象.一个类创建型模式使用继承改变被实例化的类,而一个对象创建型模式将实例化委托给另一个对象.创建型模式有两个不断出现的主旋律.第一,它们都将关于该系统使用哪些具体的类的信息封装起来.第二,它们隐藏了这些类的实例是如何被创建和放在一起的.整个系统关于这些对象所知道的是由抽象类所定义的接口.因此,创建型模式在什么被创建,谁创建它,它是怎样被创建的,以

PHP教程:掌握php设计模式之访问者模式

PHP教程:掌握php设计模式之访问者模式 这篇文章主要帮助大家轻松掌握php设计模式之访问者模式,感兴趣的小伙伴们可以参考一下 访问者模式解决的问题 在我们的代码编写过程当中,经常需要对一些类似的对象添加一些的代码,我们以一个计算机对象打印组成部分为例来看下: /** * 抽象基类 */ abstract class Unit { /** *获取名称 */ abstract public function getName(); } /** * Cpu类 */ class Cpu extends

【设计模式】——访问者模式

访问者模式(Visitor),表示一个作用于某对象结构中的各元素的操作.它使你可以在不改变各元素的类的前提下定义作用于这些元素的新操作. 访问者模式结构图 访问者模式使用与数据结构相对比较稳定的系统,即数据结构和作用与结构上的操作之间的耦合解脱开,使得操作集合可以相对自由的演化.其目的,要把处理从数据结构分离开来.很多系统可以按照算法和数据结构分开,如果这样的系统有比较稳定的数据结构,又有易于变化的算法的话,使用访问者模式就是比较合适的,因为访问者模式使得算法操作的增加变得容易.反之,如果这样的

22.设计模式_访问者模式

一.引言 在上一篇博文中分享了责任链模式,责任链模式主要应用在系统中的某些功能需要多个对象参与才能完成的场景.在这篇博文中,我将为大家分享我对访问者模式的理解. 二.访问者模式介绍 2.1 访问者模式的定义 访问者模式是封装一些施加于某种数据结构之上的操作.一旦这些操作需要修改的话,接受这个操作的数据结构则可以保存不变.访问者模式适用于数据结构相对稳定的系统, 它把数据结构和作用于数据结构之上的操作之间的耦合度降低,使得操作集合可以相对自由地改变. 数据结构的每一个节点都可以接受一个访问者的调用

设计模式(17) 访问者模式(VISITOR) C++实现

意图: 表示一个作用于某对象结构的各元素的操作.它使你可以再不改变各元素的类的前提下定义作用于这些元素的新操作. 动机: 之前在学校的最后一个小项目就是做一个编译器,当时使用的就是访问者模式. 在静态分析阶段,将源程序表示为一个抽象语法树,编译器需要在抽象语法树的基础上实施某些操作以进行静态语义分析.可能需要定义许多操作以进行类型检查.代码优化.流程分析.检查变量是否在使用前被赋值,等等. 这个需求的特点是:要求对不同的节点进行不同的处理. 常规设计方法:不同的节点封装不同的操作. 缺点是,节点

C#设计模式(22)——访问者模式(Vistor Pattern)

一.引言 在上一篇博文中分享了责任链模式,责任链模式主要应用在系统中的某些功能需要多个对象参与才能完成的场景.在这篇博文中,我将为大家分享我对访问者模式的理解. 二.访问者模式介绍 2.1 访问者模式的定义 访问者模式是封装一些施加于某种数据结构之上的操作.一旦这些操作需要修改的话,接受这个操作的数据结构则可以保存不变.访问者模式适用于数据结构相对稳定的系统, 它把数据结构和作用于数据结构之上的操作之间的耦合度降低,使得操作集合可以相对自由地改变. 数据结构的每一个节点都可以接受一个访问者的调用

【设计模式】访问者模式

在访问者模式(Visitor Pattern)中,我们使用了一个访问者类,它改变了元素类的执行算法.通过这种方式,元素的执行算法可以随着访问者改变而改变.这种类型的设计模式属于行为型模式.根据模式,元素对象已接受访问者对象,这样访问者对象就可以处理元素对象上的操作. 介绍 意图:主要将数据结构与数据操作分离. 主要解决:稳定的数据结构和易变的操作耦合问题. 何时使用:需要对一个对象结构中的对象进行很多不同的并且不相关的操作,而需要避免让这些操作"污染"这些对象的类,使用访问者模式将这些

JAVA设计模式之 访问者模式【Visitor Pattern】

一.概述 访问者模式是一种较为复杂的行为型设计模式,它包含访问者和被访问元素两个主要组成部分,这些被访问的元素通常具有不同的类型,且不同的访问者可以对它们进行不同的访问操作.在使用访问者模式时,被访问元素通常不是单独存在的,它们存储在一个集合中,这个集合被称为"对象结构",访问者通过遍历对象结构实现对其中存储的元素的逐个操作.访问者模式是一种对象行为型模式. 二.适用场景 当有多种类型的访问者(或是操作者) 对一组被访问者对象集合(或是对象结构)进行操作(其中对象集合也包含多种类型对象

【设计模式】—— 访问者模式Visitor

对于某个对象或者一组对象,不同的访问者,产生的结果不同,执行操作也不同.此时,就是访问者模式的典型应用了. 应用场景 1 不同的子类,依赖于不同的其他对象 2 需要对一组对象,进行许多不相关的操作,又不想在类中是现在这些方法 3 定义的类很少改变,但是执行的操作却经常发生改变. 回到顶部 模式结构 Context 环境角色 class Context{ List<Node> list = new ArrayList(); public void add(Node node) { list.ad