对同样集合对象的操作并不是唯一的,10.总计与分析

方式动机

格局动机

设计形式 ( 二十 ) 访问者格局Visitor(对象行为型)

对于系统中的有些对象,它们存款和储蓄在同五个凑合中,且具有不一样的品类,而且对于该集合中的对象,可以承受一类称为访问者的指标来做客,而且不一致的访问者其访问格局有所差别,访问者情势为不留余地那类难题而诞生。
在其实使用时,对同样集合对象的操作并不是唯一的,对同一的成分对象恐怕存在种种差异的操作方法。
同时这一个操作办法并不稳定,大概还亟需追加新的操作,以满意新的政工须要。
那会儿,访问者方式便是一个值得考虑的消除方案。
访问者方式的目标是包裹一些施加于某种数据结构成分之上的操作,一旦这几个操作须求修改的话,接受这几个操作的数据结构可以保持不变。为差别门类的因素提供三种做客操作办法,且能够在不改动原有系统的图景下扩充新的操作方法,那正是访问者格局的形式动机。

对于系统中的有些对象,它们存款和储蓄在同1个汇合中,且富有不相同的档次,而且对于该集合中的对象,能够承受一类称为访问者的指标来拜访,而且差异的访问者其访问方式有所不一样,访问者方式为消除那类难点而诞生。
在事实上行使时,对同一集合对象的操作并不是唯一的,对同样的要素对象或然存在各样不一样的操作格局。
并且那几个操作方法并不安定,大概还必要扩展新的操作,以满足新的事情供给。
那儿,访问者格局就是三个值得考虑的消除方案。
访问者形式的目标是包裹一些施加于某种数据结构成分之上的操作,一旦这一个操作须要修改的话,接受这些操作的数据结构能够保持不变。为分歧品种的元素提供多样造访操作方法,且能够在不修改原有系统的意况下增添新的操作情势,那正是访问者情势的方式动机。

1.概述

方式定义
访问者格局(Visitor
Pattern):表示贰个功力于某指标协会中的各要素的操作,它使大家能够在不转移各因素的类的前提下定义效率于那一个要素的新操作。访问者情势是一种对象行为型形式。
Visitor Pattern: Represent an operation to be performed on the elements
of an object structure. Visitor lets you define a new operation without
changing the classes of the elements on which it operates.
Frequency of use: low
UML图
图片 1

方式定义
访问者情势(Visitor
Pattern):表示一个功力于某指标组织中的各因素的操作,它使大家可以在不转移各要素的类的前提下定义效用于这么些要素的新操作。访问者方式是一种对象行为型形式。
Visitor Pattern: Represent an operation to be performed on the elements
of an object structure. Visitor lets you define a new operation without
changing the classes of the elements on which it operates.
Frequency of use: low
UML图
图片 2

在软件开发进度中,对于系统中的有些对象,它们存款和储蓄在同三个集合collection中,且具备区其他体系,而且对于该集合中的目的,能够承受一类称为访问者的对象来访问,而且分裂的访问者其访问情势有所不一样。

事例1:顾客在超级市场中校选用的商品,如苹果、图书等位居购物车中,然后到收银员处付款。在购物进度中,顾客必要对那么些商品举行访问,以便确认那么些商品的身分,之后收银员总括价格时也急需拜访购物车内顾客所挑选的货品。

那会儿,购物车作为三个ObjectStructure(对象组织)用于存款和储蓄各类类型的商品,而消费者和收银员作为访问那个商品的访问者,他们需求对货物举行自小编批评和计价。分歧类别的货物其访问格局也大概不相同,如苹果供给过秤之后再计价,而图书不必要。

格局组织
访问者格局涵盖如下剧中人物:
Vistor: 抽象访问者
ConcreteVisitor: 具体访问者
Element: 抽象成分
ConcreteElement: 具体元素
ObjectStructure: 对象组织

情势结构
访问者方式涵盖如下脚色:
Vistor: 抽象访问者
ConcreteVisitor: 具体访问者
Element: 抽象成分
ConcreteElement: 具体成分
ObjectStructure: 对象协会

2.问题

情势分析
访问者方式中指标协会存款和储蓄了不一样类型的成分对象,以供分歧访问者访问。
访问者情势包蕴八个层次结构,贰个是访问者层次结构,提供了止渴望梅访问者和现实访问者,二个是因素层次结构,提供了画饼充饥成分和求实因素。
同样的访问者能够以差其余法子访问不相同的因素,相同的因素得以接受不相同访问者以区别访问情势访问。在访问者形式中,增添新的访问者无须修改原有系统,系统具备较好的可扩充性。

形式分析
访问者方式中目的组织存款和储蓄了分化系列的因素对象,以供分化访问者访问。
访问者方式包蕴三个层次结构,1个是访问者层次结构,提供了指雁为羹访问者和现实性访问者,3个是因素层次结构,提供了抽象成分和实际因素。
一点差别也没有于的访问者能够以不相同的方法访问不一样的因素,相同的因素得以接受分化访问者以分化访问格局访问。在访问者模式中,扩大新的访问者无须修改原有系统,系统具备较好的可扩充性。

对同样集合对象的操作并不是唯一的,对同一的因素对象或者存在两种区其他操作办法。而且这么些操作办法并不安宁,倘诺对亟待追加新的操作,如何满意新的事务需求?

形式实例与分析
汉子和农妇—访问者形式示例代码
系统布局
图片 3
Vistor: 抽象访问者  Action.cs

格局实例与分析
夫君和女子—访问者情势示例代码
系统布局
图片 4
Vistor: 抽象访问者  Action.cs

3.缓解方案

namespace VisitorPattern
{
    abstract class Action
    {
        //得到男人结论或女人反应
        public abstract void GetManConclusion(Man concreateElementA);
        //得到女人结论或男人反应
        public abstract void GetWomanConclusion(Woman concreateElementB);
    }
}
namespace VisitorPattern
{
    abstract class Action
    {
        //得到男人结论或女人反应
        public abstract void GetManConclusion(Man concreateElementA);
        //得到女人结论或男人反应
        public abstract void GetWomanConclusion(Woman concreateElementB);
    }
}

访问者格局:表示2个功用于某目的协会中的各要素的操作。它使你能够在不转移各要素的类的前提下定义成效于那一个因素的新操作。

1)访问者情势中目的组织存款和储蓄了区别类型的成分对象,以供差别访问者访问。

2)访问者形式包蕴五个层次结构,二个是访问者层次结构,提供了抽象访问者和具体访问者,1个是因素层次结构,提供了说梅止渴成分和现实性因素。

一如既往的访问者能够以不相同的不二法门访问不相同的要素,相同的成分得以承受不相同访问者以差异访问格局访问。在访问者情势中,扩充新的访问者无须修改原有系统,系统有着较好的可扩充性

ConcreteVisitor: 具体访问者 Success.cs

ConcreteVisitor: 具体访问者 Success.cs

4.适用性

using System;

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

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

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

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

在下列意况下行使Vi s i t o r情势:

一个对象组织包蕴很多类对象,它们有两样的接口,而你想对这么些目的实施部分依靠于其具体类的操作。

需求对2个对象组织中的对象开始展览过多不比的同时不相干的操作,而你想制止让那些操作“污染”这几个指标的类。
Visitor使得你能够将相关的操作集中起来定义在3个类中。当该对象协会被众多用到共享时,用Visitor形式让每一个应用仅包蕴须要动用的操作。

定义对象协会的类很少改变,但时常索要在此布局上定义新的操作。改变指标协会类须求重定义对负有访问者的接口,这只怕必要非常大的代价。要是指标社团类平时改变,那么大概仍然在这个类中定义这一个操作较好。

Failing.cs

Failing.cs

5.结构

using System;

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

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

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

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

图片 5

Amativenness.cs

Amativenness.cs

6.情势的重组

using System;

namespace VisitorPattern
{
    class Amativenness : Action
    {
        public override void GetManConclusion(Man concreateElementA)
        {
            Console.WriteLine("{0}{1}时,凡事不懂也要装懂。", concreateElementA.GetType().Name, this.GetType().Name);
        }

        public override void GetWomanConclusion(Woman concreateElementB)
        {
            Console.WriteLine("{0}{1}时,遇事懂也装作不懂。", concreateElementB.GetType().Name, this.GetType().Name);
        }
    }
}
using System;

namespace VisitorPattern
{
    class Amativenness : Action
    {
        public override void GetManConclusion(Man concreateElementA)
        {
            Console.WriteLine("{0}{1}时,凡事不懂也要装懂。", concreateElementA.GetType().Name, this.GetType().Name);
        }

        public override void GetWomanConclusion(Woman concreateElementB)
        {
            Console.WriteLine("{0}{1}时,遇事懂也装作不懂。", concreateElementB.GetType().Name, this.GetType().Name);
        }
    }
}

访问者形式涵盖如下剧中人物:
空洞访问者(Vistor): —
为该对象协会中ConcreteElement的每1个类声明一个Visit操作。该操作的名字和特
征标识了发送Visit请求给该访问者的老大类。那使得访问者能够分明正被访问成分
的具体的类。那样访问者就足以经过该因素的一定接口直接访问它。
具体访问者(ConcreteVisitor): —
完毕种种由Visitor声明的操作。各类操作达成本算法的一部分,而该算法片断乃是
对应于结构中目的的类。ConcreteVisitor为该算法提供了上下文并蕴藏它的一部分境况。
这一状态日常在遍历该组织的进程中积聚结果。
 抽象成分(Element):定义二个Accept操作,它以1个访问者为参数。
实际因素(ConcreteElement):
  完结Accept操作,该操作以二个访问者为参数。
目的组织(ObjectStructure): 能枚举它的成分。能够提供二个高层的接口以允许该访问者访问它的要素。能够是二个复合或者多少个集聚,如三个列表或二个无序聚集。

Element: 抽象成分 Person.cs

Element: 抽象成分 Person.cs

7.效果

namespace VisitorPattern
{
    abstract class Person
    {
        //接受
        public abstract void Accept(Action visitor);
    }
}
namespace VisitorPattern
{
    abstract class Person
    {
        //接受
        public abstract void Accept(Action visitor);
    }
}

访问者模式的独到之处:

•使得扩充新的拜会操作变得很不难。如若有的操作注重于1个扑朔迷离的布局对象的话,那么一般而言,扩充新的操作会很复杂。而利用访问者方式,增添新的操作就象征扩张多少个新的拜会者类,由此,变得很简单。

•将关于因素对象的拜会行为集中到3个访问者对象中,而不是分散到2个个的要素类中。

•访问者方式能够跨过多少个类的级差结构访问属于不一致的阶段结构的成员类。迭代子只可以访问属于同1个门类等级结构的成员对象,而无法访问属于不一样等级结构的靶子。访问者形式能够做到那或多或少。

•让用户可以在不改动现有类层次结构的情事下,定义该类层次结构的操作。

访问者形式的后天不足:

•扩张新的因素类很不便。在访问者形式中,每扩充二个新的要素类都意味要在抽象访问者剧中人物中加进四个新的空洞操作,并在每二个实际访问者类中扩充对应的具体操作,违背了“开闭原则”的渴求。

•破坏封装。访问者形式供给访问者对象访问并调用每三个成分对象的操作,那象征成分对象有时候必须暴光一些友好的内部操作和个中情形,不然无法供访问者访问。

ConcreteElement: 具体成分 Man.cs

ConcreteElement: 具体成分 Man.cs

8.实现

using System;

namespace VisitorPattern
{
    class Man : Person
    {
        public override void Accept(Action visitor)
        {
            visitor.GetManConclusion(this);
        }
    }
}
using System;

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

咱俩是了phppan提供叁个事例:

 

[php] view
plain
data-mod=”popu_168″> data-mod=”popu_168″> copy

 

data-mod=”popu_169″> print?

  1. <?php  
  2. /** 
  3.  * 访问者形式 
  4.  * @author guisu 
  5.  *  
  6.  */  
  7.   
  8. interface Visitor {  
  9.     public  class=”keyword”>function visitConcreteElementA(ConcreteElementA  class=”vars”>$elementA);  
  10.     public  class=”keyword”>function visitConcreteElementB(concreteElementB  class=”vars”>$elementB);  
  11. }  
  12.   
  13. interface Element {  
  14.     public  class=”keyword”>function accept(Visitor  class=”vars”>$visitor);  
  15. }  
  16.   
  17. /** 
  18.  * 具体的访问者1 
  19.  */  
  20. class ConcreteVisitor1  class=”keyword”>implements Visitor {  
  21.     public  class=”keyword”>function visitConcreteElementA(ConcreteElementA  class=”vars”>$elementA){  
  22.         echo  class=”vars”>$elementA->getName(), class=”string”>’ visitd by ConcerteVisitor1 <br />’;  
  23.     }  
  24.   
  25.     public  class=”keyword”>function visitConcreteElementB(ConcreteElementB  class=”vars”>$elementB){  
  26.         echo  class=”vars”>$elementB->getName(). class=”string”>’ visited by ConcerteVisitor1 <br />’;  
  27.     }  
  28.   
  29. }  
  30.   
  31. /** 
  32.  * 具体的访问者2 
  33.  */  
  34. class ConcreteVisitor2  class=”keyword”>implements Visitor {  
  35.     public  class=”keyword”>function visitConcreteElementA(ConcreteElementA  class=”vars”>$elementA){  
  36.         echo  class=”vars”>$elementA->getName(),    class=”string”>’ visitd by ConcerteVisitor2 <br />’;  
  37.     }  
  38.   
  39.     public  class=”keyword”>function visitConcreteElementB(ConcreteElementB  class=”vars”>$elementB){  
  40.         echo  class=”vars”>$elementB->getName(),  class=”string”>’ visited by ConcerteVisitor2 <br />’;  
  41.     }  
  42.   
  43. }  
  44.   
  45. /** 
  46.  * 具体因素A 
  47.  */  
  48. class ConcreteElementA  class=”keyword”>implements Element {  
  49.     private class=”vars”>$_name;  
  50.   
  51.     public  class=”keyword”>function __construct( class=”vars”>$name){  
  52.         $this->_name = class=”vars”>$name;  
  53.     }  
  54.   
  55.     public  class=”keyword”>function getName(){  
  56.         return class=”vars”>$this->_name;  
  57.     }  
  58.   
  59.     /** 
  60. class=”comment”>     * 接受访问者调用它针对该因素的新办法 
  61.      * @param Visitor $visitor 
  62.      */  
  63.     public  class=”keyword”>function accept(Visitor  class=”vars”>$visitor){  
  64.          class=”vars”>$visitor->visitConcreteElementA( class=”vars”>$this);  
  65.     }  
  66.   
  67. }  
  68.   
  69. /** 
  70.  *  具体因素B 
  71.  */  
  72. class ConcreteElementB  class=”keyword”>implements Element {  
  73.     private class=”vars”>$_name;  
  74.   
  75.     public  class=”keyword”>function __construct( class=”vars”>$name){  
  76.         $this->_name = class=”vars”>$name;  
  77.     }  
  78.   
  79.     public  class=”keyword”>function getName(){  
  80.         return class=”vars”>$this->_name;  
  81.     }  
  82.   
  83.     /** 
  84. class=”comment”>     * 接受访问者调用它针对该因素的新方式 
  85.      * @param Visitor $visitor 
  86.      */  
  87.     public  class=”keyword”>function accept(Visitor  class=”vars”>$visitor){  
  88.          class=”vars”>$visitor->visitConcreteElementB( class=”vars”>$this);  
  89.     }  
  90.   
  91. }  
  92.   
  93. /** 
  94.  * 对象协会 即成分的集合 
  95.  */  
  96. class ObjectStructure {  
  97.     private class=”vars”>$_collection;  
  98.   
  99.     public  class=”keyword”>function __construct(){  
  100.         $this->_collection = class=”keyword”>array();  
  101.     }  
  102.   
  103.   
  104.     public  class=”keyword”>function attach(Element  class=”vars”>$element){  
  105.         returnarray_push( class=”vars”>$this->_collection, class=”vars”>$element);  
  106.     }  
  107.   
  108.     public  class=”keyword”>function detach(Element  class=”vars”>$element){  
  109.         $index= class=”func”>array_search($element, class=”vars”>$this->_collection);  
  110.         if( class=”vars”>$index!==FALSE){  
  111.             unset( class=”vars”>$this->_collection[ class=”vars”>$index]);  
  112.         }  
  113.   
  114.         return class=”vars”>$index;  
  115.     }  
  116.   
  117.     public  class=”keyword”>function accept(Visitor  class=”vars”>$visitor){  
  118.         foreach( class=”vars”>$this->_collection as class=”vars”>$element){  
  119.             $element->accept( class=”vars”>$visitor);  
  120.         }  
  121.     }  
  122. }  
  123.   
  124. class Client {  
  125.   
  126.     /** 
  127.      * Main program. 
  128.      */  
  129.     public  class=”keyword”>static  class=”keyword”>function main(){  
  130.         $elementA =  class=”keyword”>new ConcreteElementA( class=”string”>”ElementA”);  
  131.         $elementB =  class=”keyword”>new ConcreteElementB( class=”string”>”ElementB”);  
  132.         $elementA2 =  class=”keyword”>new ConcreteElementB( class=”string”>”ElementA2″);  
  133.         $visitor1 =  class=”keyword”>new ConcreteVisitor1();  
  134.         $visitor2 =  class=”keyword”>new ConcreteVisitor2();  
  135.   
  136.         $os =  class=”keyword”>new ObjectStructure();  
  137.         $os->attach( class=”vars”>$elementA);  
  138.         $os->attach( class=”vars”>$elementB);  
  139.         $os->attach( class=”vars”>$elementA2);  
  140.         $os->detach( class=”vars”>$elementA);  
  141.         $os->accept( class=”vars”>$visitor1);  
  142.         $os->accept( class=”vars”>$visitor2);  
  143.     }  
  144.   
  145. }  
  146.   
  147. Client::main();  
  148. ?>   

Woman.cs

Woman.cs

9.与其它有关方式

using System;

namespace VisitorPattern
{
    class Woman : Person
    {
        public override void Accept(Action visitor)
        {
            visitor.GetWomanConclusion(this);
        }
    }
}
using System;

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

•迭代器形式)由于访问者形式须求对目的组织进行操作,而指标组织本人是二个因素对象的聚众,由此访问者情势日常供给与迭代器格局联用,在指标协会中使用迭代器来遍历成分对象。

•组合方式)在访问者形式中,成分对象恐怕存在容器对象和叶子对象,由此能够构成组合方式来开始展览规划。

ObjectStructure: 对象组织 ObjectStructure.cs

ObjectStructure: 对象组织 ObjectStructure.cs

10.扩展

using System.Collections.Generic;

namespace VisitorPattern
{
    //对象结构
    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 visitor)
        {
            foreach (Person e in elements)
            {
                e.Accept(visitor);
            }
        }
    }
}
using System.Collections.Generic;

namespace VisitorPattern
{
    //对象结构
    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 visitor)
        {
            foreach (Person e in elements)
            {
                e.Accept(visitor);
            }
        }
    }
}

倾斜的“开闭原则” 

•访问者格局以一种倾斜的主意扶助“开闭原则”,扩大新的访问者方便,可是扩展新的成分很不便。

面向对象的规划原则中最重要的正是所谓的”开一闭”原则。2个软件系统的设计应当尽量做到对扩张开放,对修改关闭。达到这些原则的门道就是遵守”对转移的包装”的口径。这几个标准讲的是在实行软件系统的规划时,应当设法找出三个软件系统中会变化的一些,将之封装起来。
过多系统能够遵守算法和数据结构分开,也正是说一些指标涵盖算法,而另一对对象涵盖数据,接受算法的操作。假设如此的种类有相比稳定的数据结构,又有易于变化的算法的话,使用访问者格局正是相比较合适的,因为访问者形式使得算法操作的增多变得简单。
反过来,借使那样3个类别的数据结构对象易于变动,平时要有新的数额对象扩张进去的话,就不相符接纳访问者方式。因为在访问者方式中增添新的节点很难堪,要提到到在空虚访问者和兼具的切实可行访问者中加进新的方法。

 

Client:客户类

Client:客户类

10.总括与分析

using System;

namespace VisitorPattern
{
    class Program
    {
        static void Main(string[] args)
        {
            ObjectStructure o = new ObjectStructure();
            o.Attach(new Man());
            o.Attach(new Woman());
            //成功时的反应
            Success v1 = new Success();
            o.Display(v1);
            //失败时的反应
            Failing v2 = new Failing();
            o.Display(v2);
            //恋爱时的反应
            Amativenness v3 = new Amativenness();
            o.Display(v3);
            Console.Read();
        }
    }
}
using System;

namespace VisitorPattern
{
    class Program
    {
        static void Main(string[] args)
        {
            ObjectStructure o = new ObjectStructure();
            o.Attach(new Man());
            o.Attach(new Woman());
            //成功时的反应
            Success v1 = new Success();
            o.Display(v1);
            //失败时的反应
            Failing v2 = new Failing();
            o.Display(v2);
            //恋爱时的反应
            Amativenness v3 = new Amativenness();
            o.Display(v3);
            Console.Read();
        }
    }
}

 

方式优缺点
访问者格局的帮助和益处
 使得扩张新的拜会操作变得很简单。

将有关因素对象的造访行为集中到2个访问者对象中,而不是散落到1个个的要素类中。
 能够跨过类的阶段结构访问属于不一致的阶段结构的成分类。
 让用户能够在不修改现有类层次结构的气象下,定义该类层次结构的操作。
访问者方式的欠缺

增添新的因素类很不便。在访问者方式中,每扩张1个新的成分类都表示要在空洞访问者角色中增添一个新的空洞操作,并在每3个现实访问者类中加进对应的具体操作,违背了“开闭原则”的渴求。

破坏封装。访问者格局供给访问者对象访问并调用每多个因素对象的操作,这意味成分对象有时候必须揭穿一些投机的其中操作和中间景观,不然不能供访问者访问。

形式优缺点
访问者格局的长处
 使得扩张新的走访操作变得很不难。

将有关因素对象的造访行为集中到一个访问者对象中,而不是散落到三个个的成分类中。
 能够跨过类的阶段结构访问属于分裂的等级结构的成分类。
 让用户能够在不改动现有类层次结构的场馆下,定义该类层次结构的操作。
访问者情势的缺陷

增添新的成分类很费力。在访问者格局中,每扩充四个新的因素类都表示要在虚幻访问者角色中追加1个新的虚幻操作,并在每一个切实可行访问者类中加进对应的具体操作,违背了“开闭原则”的须求。

破坏封装。访问者情势要求访问者对象访问并调用每一种因素对象的操作,那意味成分对象有时候必须暴光一些自己的当中操作和中间景观,不然不恐怕供访问者访问。

 

情势适用条件
在以下意况下可以接纳访问者格局:

一个指标组织包括众多档次的指标,希望对那个指标实施部分依靠其现实品种的操作。在访问者中针对各类具体的花色都提供了一个访问操作,分化体系的靶子足以有例外的拜会操作。

需求对多少个目的协会中的对象进行过多不比的同时不相干的操作,而急需防止让那个操作“污染”这一个指标的类,也不指望在加码新操作时修改那几个类。访问者情势使得大家能够将相关的走访操作集中起来定义在访问者类中,对象组织得以被多个例外的访问者类所使用,将对象自作者与目的的拜会操作分离。
 对象组织中指标对应的类很少改变,但时常索要在此指标协会上定义新的操作。

方式适用条件
在偏下情况下得以动用访问者情势:

3个目的组织包罗众多品类的对象,希望对那几个指标执香港行政局地凭借其具体品种的操作。在访问者中针对每一个具体的品种都提供了三个访问操作,差异种类的指标能够有两样的拜访操作。

要求对二个目的社团中的对象开始展览过多不一的同时不相干的操作,而必要幸免让这么些操作“污染”那几个目的的类,也不期望在扩充新操作时修改那个类。访问者格局使得大家得以将有关的造访操作集中起来定义在访问者类中,对象组织得以被四个例外的访问者类所使用,将对象自小编与对象的访问操作分离。
 对象组织中目的对应的类很少改变,但日常需求在此指标组织上定义新的操作。

 

 

【声明与谢谢】
本文,站在诸多高个子的肩头上,借鉴和引用了累累旁人拥有版权的文章或撰文,在此,对前人们的进献致谢。并同时宣布引用的剧情、原作者或缘于(一些出自互连网的始末笔者非常小概追述本源,深表遗憾)。

【证明与多谢】
正文,站在广大高个子的肩头上,借鉴和引用了众多旁人拥有版权的作品或撰文,在此,对前人们的进献致谢。并同时公布引用的剧情、原小编或出自(一些出自互联网的始末笔者不能够追述本源,深表遗憾)。

【参考文献】
《设计形式—可复用面向对象软件的根底》小编: [美] 埃里克h Gamma / RichardHelm / 拉尔夫 Johnson / John Vlissides 译者: 李英军 / 马晓星 / 蔡敏 /
刘建中 等 机械工业出版社
《重构—改革既有代码的规划》我: 马丁 Fowler译者:候捷
中夏族民共和国电力出版社
《敏捷软件开发—原则、方式与实践》笔者: 罗Bert C. 马丁 南开东军事和政院学出版社
《程序员修炼之道—从小工到大家》作者: Andrew Hunt / 大卫 Thomas电子工业出版社
《Head First 设计情势》作者: Freeman 译者: O’Reilly Taiwan公司中华夏族民共和国电力出版社
《设计情势之禅》 小编: 秦小波 机械工业出版社
MSDN WebCast 《C#面向对象设计方式纵横谈》 助教:李建忠
刘伟(Liu-Wei). 设计方式. 新加坡:南开东军政高校学出版社, 贰零壹壹.
Liu Wei. 设计情势实训教程. 法国巴黎:复旦东军事和政院学出版社, 二〇一二.
《大话设计方式》 小编: 程杰 哈工大东军事和政院学出版社
《C#图解教程》作者: 索Liss 译者: 苏林 / 朱晔 人民邮政和邮电通讯出版社
《你必须精通的.NET》小编: 王涛
《项目中的.NET》小编: 李天平 电子工业出版社
《Microsoft .NET集团级应用架构划设想计》作者: (美)埃斯波西托等撰写 译者:
陈黎夫
http://www.dofactory.com/Patterns/Patterns.aspx .NET Design Patterns
http://www.cnblogs.com/zhenyulu 博客作者:吕震宇
http://www.cnblogs.com/terrylee 博客我:李会军
http://www.cnblogs.com/anlyren/ 博客作者:anlyren
http://www.cnblogs.com/idior 博客小编:idior
http://www.cnblogs.com/allenlooplee 博客小编:Allen lee
http://blog.csdn.net/ai92 博客小编:ai92
http://www.cnblogs.com/umlonline/ 博客我:张传波
http://www.cnblogs.com/lovecherry/ 博客小编:LoveCherry 

【参考文献】
《设计形式—可复用面向对象软件的功底》小编: [美] 埃里克h Gamma / RichardHelm / 拉尔夫 约翰逊 / John Vlissides 译者: 李英军 / 马晓星 / 蔡敏 /
刘建中 等 机械工业出版社
《重构—改正既有代码的统一筹划》我: 马丁 Fowler译者:候捷
中夏族民共和国电力出版社
《敏捷软件开发—原则、形式与实践》作者: 罗伯特 C. 马丁 浙大大学出版社
《程序员修炼之道—从小工到大方》作者: Andrew Hunt / 大卫 托马斯电子工业出版社
《Head First 设计方式》笔者: Freeman 译者: O’Reilly Taiwan公司中华夏族民共和国电力出版社
《设计格局之禅》 我: 秦小波 机械工业出版社
MSDN WebCast 《C#面向对象设计方式纵横谈》 助教:李建忠
刘伟(Liu-Wei). 设计方式. 香港(Hong Kong):哈工业余大学学高校出版社, 贰零壹壹.
Liu Wei. 设计情势实验和培养和操练教程. 新加坡:南开东军事和政院学出版社, 二零一二.
《大话设计情势》 作者: 程杰 哈工业余大学学东军事和政院学出版社
《C#图解教程》作者: 索Liss 译者: 苏林 / 朱晔 人民邮电出版社
《你无法不通晓的.NET》笔者: 王涛
《项目中的.NET》小编: 李天平 电子工业出版社
《Microsoft .NET集团级应用架构划设想计》小编: (美)埃斯波西托等撰写 译者:
陈黎夫
http://www.dofactory.com/Patterns/Patterns.aspx .NET Design Patterns
http://www.cnblogs.com/zhenyulu 博客笔者:吕震宇
http://www.cnblogs.com/terrylee 博客我:李会军
http://www.cnblogs.com/anlyren/ 博客小编:anlyren
http://www.cnblogs.com/idior 博客小编:idior
http://www.cnblogs.com/allenlooplee 博客作者:Allen lee
http://blog.csdn.net/ai92 博客作者:ai92
http://www.cnblogs.com/umlonline/ 博客笔者:张传波
http://www.cnblogs.com/lovecherry/ 博客笔者:LoveCherry 

相关文章