• <ins id="pjuwb"></ins>
    <blockquote id="pjuwb"><pre id="pjuwb"></pre></blockquote>
    <noscript id="pjuwb"></noscript>
          <sup id="pjuwb"><pre id="pjuwb"></pre></sup>
            <dd id="pjuwb"></dd>
            <abbr id="pjuwb"></abbr>

            C++ Programmer's Cookbook

            {C++ 基礎(chǔ)} {C++ 高級(jí)} {C#界面,C++核心算法} {設(shè)計(jì)模式} {C#基礎(chǔ)}

            模式設(shè)計(jì)c#--行為型--visitor

            名稱 Visitor
            結(jié)構(gòu) r_visitor.bmp
            意圖 表示一個(gè)作用于某對(duì)象結(jié)構(gòu)中的各元素的操作。它使你可以在不改變各元素的類的前提下定義作用于這些元素的新操作。
            適用性
            • 一個(gè)對(duì)象結(jié)構(gòu)包含很多類對(duì)象,它們有不同的接口,而你想對(duì)這些對(duì)象實(shí)施一些依賴于其具體類的操作。
            • 需要對(duì)一個(gè)對(duì)象結(jié)構(gòu)中的對(duì)象進(jìn)行很多不同的并且不相關(guān)的操作,而你想避免讓這些操作“污染”這些對(duì)象的類。Vi s i t o r 使得你可以將相關(guān)的操作集中起來定義在一個(gè)類中。當(dāng)該對(duì)象結(jié)構(gòu)被很多應(yīng)用共享時(shí),用Vi s i t o r 模式讓每個(gè)應(yīng)用僅包含需要用到的操作。
            • 定義對(duì)象結(jié)構(gòu)的類很少改變,但經(jīng)常需要在此結(jié)構(gòu)上定義新的操作。改變對(duì)象結(jié)構(gòu)類需要重定義對(duì)所有訪問者的接口,這可能需要很大的代價(jià)。如果對(duì)象結(jié)構(gòu)類經(jīng)常改變,那么可能還是在這些類中定義這些操作較好。


            // Visitor pattern -- Structural example

            using System;
            using System.Collections;

            namespace DoFactory.GangOfFour.Visitor.Structural
            {
            ??
            ??// MainApp test application

            ??class MainApp
            ??{
            ????staticvoid Main()
            ????{
            ??????// Setup structure
            ??????ObjectStructure o = new ObjectStructure();
            ??????o.Attach(new ConcreteElementA());
            ??????o.Attach(new ConcreteElementB());

            ??????// Create visitor objects
            ??????ConcreteVisitor1 v1 = new ConcreteVisitor1();
            ??????ConcreteVisitor2 v2 = new ConcreteVisitor2();

            ??????// Structure accepting visitors
            ??????o.Accept(v1);
            ??????o.Accept(v2);

            ??????// Wait for user
            ??????Console.Read();
            ????}
            ??}

            ??// "Visitor"

            ??abstractclass Visitor
            ??{
            ????publicabstractvoid VisitConcreteElementA(
            ??????ConcreteElementA concreteElementA);
            ????publicabstractvoid VisitConcreteElementB(
            ??????ConcreteElementB concreteElementB);
            ??}

            ??// "ConcreteVisitor1"

            ??class ConcreteVisitor1 : Visitor
            ??{
            ????publicoverridevoid VisitConcreteElementA(
            ??????ConcreteElementA concreteElementA)
            ????{
            ??????Console.WriteLine("{0} visited by {1}",
            ????????concreteElementA.GetType().Name, this.GetType().Name);
            ????}

            ????publicoverridevoid VisitConcreteElementB(
            ??????ConcreteElementB concreteElementB)
            ????{
            ??????Console.WriteLine("{0} visited by {1}",
            ????????concreteElementB.GetType().Name, this.GetType().Name);
            ????}
            ??}

            ??// "ConcreteVisitor2"

            ??class ConcreteVisitor2 : Visitor
            ??{
            ????publicoverridevoid VisitConcreteElementA(
            ??????ConcreteElementA concreteElementA)
            ????{
            ??????Console.WriteLine("{0} visited by {1}",
            ????????concreteElementA.GetType().Name, this.GetType().Name);
            ????}

            ????publicoverridevoid VisitConcreteElementB(
            ??????ConcreteElementB concreteElementB)
            ????{
            ??????Console.WriteLine("{0} visited by {1}",
            ????????concreteElementB.GetType().Name, this.GetType().Name);
            ????}
            ??}

            ??// "Element"

            ??abstractclass Element
            ??{
            ????publicabstractvoid Accept(Visitor visitor);
            ??}

            ??// "ConcreteElementA"

            ??class ConcreteElementA : Element
            ??{
            ????publicoverridevoid Accept(Visitor visitor)
            ????{
            ??????visitor.VisitConcreteElementA(this);
            ????}

            ????publicvoid OperationA()
            ????{
            ????}
            ??}

            ??// "ConcreteElementB"

            ??class ConcreteElementB : Element
            ??{
            ????publicoverridevoid Accept(Visitor visitor)
            ????{
            ??????visitor.VisitConcreteElementB(this);
            ????}

            ????publicvoid OperationB()
            ????{
            ????}
            ??}

            ??// "ObjectStructure"

            ??class ObjectStructure
            ??{
            ????private ArrayList elements = new ArrayList();

            ????publicvoid Attach(Element element)
            ????{
            ??????elements.Add(element);
            ????}

            ????publicvoid Detach(Element element)
            ????{
            ??????elements.Remove(element);
            ????}

            ????publicvoid Accept(Visitor visitor)
            ????{
            ??????foreach (Element e in elements)
            ??????{
            ????????e.Accept(visitor);
            ??????}
            ????}
            ??}
            }
            Output
            ConcreteElementA visited by ConcreteVisitor1
            ConcreteElementB visited by ConcreteVisitor1
            ConcreteElementA visited by ConcreteVisitor2
            ConcreteElementB visited by ConcreteVisitor2

            posted on 2006-01-03 16:18 夢在天涯 閱讀(1250) 評(píng)論(2)  編輯 收藏 引用 所屬分類: Design pattern

            評(píng)論

            # re: 模式設(shè)計(jì)c#--行為型--visitor 2006-04-25 16:48 夢在天涯

            訪問者模式的目的是封裝一些施加于某種數(shù)據(jù)結(jié)構(gòu)元素之上的操作。一旦這些操作需要修改的話,接受這個(gè)操作的數(shù)據(jù)結(jié)構(gòu)則可以保持不變。

            問題提出

            System.Collection命名空間下提供了大量集合操作對(duì)象。但大多數(shù)情況下處理的都是同類對(duì)象的聚集。換言之,在聚集上采取的操作都是一些針對(duì)同類型對(duì)象的同類操作。但是如果針對(duì)一個(gè)保存有不同類型對(duì)象的聚集采取某種操作該怎么辦呢?

            粗看上去,這似乎不是什么難題??墒侨绻枰槍?duì)一個(gè)包含不同類型元素的聚集采取某種操作,而操作的細(xì)節(jié)根據(jù)元素的類型不同而有所不同時(shí),就會(huì)出現(xiàn)必須對(duì)元素類型做類型判斷的條件轉(zhuǎn)移語句。這個(gè)時(shí)候,使用訪問者模式就是一個(gè)值得考慮的解決方案。

            訪問者模式

            訪問者模式適用于數(shù)據(jù)結(jié)構(gòu)相對(duì)未定的系統(tǒng),它把數(shù)據(jù)結(jié)構(gòu)和作用于結(jié)構(gòu)上的操作之間的耦合解脫開,使得操作集合可以相對(duì)自由地演化。

            數(shù)據(jù)結(jié)構(gòu)的每一個(gè)節(jié)點(diǎn)都可以接受一個(gè)訪問者的調(diào)用,此節(jié)點(diǎn)向訪問者對(duì)象傳入節(jié)點(diǎn)對(duì)象,而訪問者對(duì)象則反過來執(zhí)行節(jié)點(diǎn)對(duì)象的操作。這樣的過程叫做"雙重分派"。節(jié)點(diǎn)調(diào)用訪問者,將它自己傳入,訪問者則將某算法針對(duì)此節(jié)點(diǎn)執(zhí)行。

            雙重分派意味著施加于節(jié)點(diǎn)之上的操作是基于訪問者和節(jié)點(diǎn)本身的數(shù)據(jù)類型,而不僅僅是其中的一者。

              回復(fù)  更多評(píng)論   

            # re: 模式設(shè)計(jì)c#--行為型--visitor 2006-04-25 16:49 夢在天涯

            在什么情況下應(yīng)當(dāng)使用訪問者模式
            有意思的是,在很多情況下不使用設(shè)計(jì)模式反而會(huì)得到一個(gè)較好的設(shè)計(jì)。換言之,每一個(gè)設(shè)計(jì)模式都有其不應(yīng)當(dāng)使用的情況。訪問者模式也有其不應(yīng)當(dāng)使用的情況,讓我們
            先看一看訪問者模式不應(yīng)當(dāng)在什么情況下使用。

            傾斜的可擴(kuò)展性

            訪問者模式僅應(yīng)當(dāng)在被訪問的類結(jié)構(gòu)非常穩(wěn)定的情況下使用。換言之,系統(tǒng)很少出現(xiàn)需要加入新節(jié)點(diǎn)的情況。如果出現(xiàn)需要加入新節(jié)點(diǎn)的情況,那么就必須在每一個(gè)訪問對(duì)象里加入一個(gè)對(duì)應(yīng)于這個(gè)新節(jié)點(diǎn)的訪問操作,而這是對(duì)一個(gè)系統(tǒng)的大規(guī)模修改,因而是違背"開一閉"原則的。

            訪問者模式允許在節(jié)點(diǎn)中加入新的方法,相應(yīng)的僅僅需要在一個(gè)新的訪問者類中加入此方法,而不需要在每一個(gè)訪問者類中都加入此方法。

            顯然,訪問者模式提供了傾斜的可擴(kuò)展性設(shè)計(jì):方法集合的可擴(kuò)展性和類集合的不可擴(kuò)展性。換言之,如果系統(tǒng)的數(shù)據(jù)結(jié)構(gòu)是頻繁變化的,則不適合使用訪問者模式。

            "開一閉"原則和對(duì)變化的封裝

            面向?qū)ο蟮脑O(shè)計(jì)原則中最重要的便是所謂的"開一閉"原則。一個(gè)軟件系統(tǒng)的設(shè)計(jì)應(yīng)當(dāng)盡量做到對(duì)擴(kuò)展開放,對(duì)修改關(guān)閉。達(dá)到這個(gè)原則的途徑就是遵循"對(duì)變化的封裝"的原則。這個(gè)原則講的是在進(jìn)行軟件系統(tǒng)的設(shè)計(jì)時(shí),應(yīng)當(dāng)設(shè)法找出一個(gè)軟件系統(tǒng)中會(huì)變化的部分,將之封裝起來。

            很多系統(tǒng)可以按照算法和數(shù)據(jù)結(jié)構(gòu)分開,也就是說一些對(duì)象含有算法,而另一些對(duì)象含有數(shù)據(jù),接受算法的操作。如果這樣的系統(tǒng)有比較穩(wěn)定的數(shù)據(jù)結(jié)構(gòu),又有易于變化的算法的話,使用訪問者模式就是比較合適的,因?yàn)樵L問者模式使得算法操作的增加變得容易。

            反過來,如果這樣一個(gè)系統(tǒng)的數(shù)據(jù)結(jié)構(gòu)對(duì)象易于變化,經(jīng)常要有新的數(shù)據(jù)對(duì)象增加進(jìn)來的話,就不適合使用訪問者模式。因?yàn)樵谠L問者模式中增加新的節(jié)點(diǎn)很困難,要涉及到在抽象訪問者和所有的具體訪問者中增加新的方法。


            六、 使用訪問者模式的優(yōu)點(diǎn)和缺點(diǎn)
            訪問者模式有如下的優(yōu)點(diǎn):

            訪問者模式使得增加新的操作變得很容易。如果一些操作依賴于一個(gè)復(fù)雜的結(jié)構(gòu)對(duì)象的話,那么一般而言,增加新的操作會(huì)很復(fù)雜。而使用訪問者模式,增加新的操作就意味著增加一個(gè)新的訪問者類,因此,變得很容易。
            訪問者模式將有關(guān)的行為集中到一個(gè)訪問者對(duì)象中,而不是分散到一個(gè)個(gè)的節(jié)點(diǎn)類中。
            訪問者模式可以跨過幾個(gè)類的等級(jí)結(jié)構(gòu)訪問屬于不同的等級(jí)結(jié)構(gòu)的成員類。迭代子只能訪問屬于同一個(gè)類型等級(jí)結(jié)構(gòu)的成員對(duì)象,而不能訪問屬于不同等級(jí)結(jié)構(gòu)的對(duì)象。訪問者模式可以做到這一點(diǎn)。
            積累狀態(tài)。每一個(gè)單獨(dú)的訪問者對(duì)象都集中了相關(guān)的行為,從而也就可以在訪問的過程中將執(zhí)行操作的狀態(tài)積累在自己內(nèi)部,而不是分散到很多的節(jié)點(diǎn)對(duì)象中。這是有益于系統(tǒng)維護(hù)的優(yōu)點(diǎn)。
            訪問者模式有如下的缺點(diǎn):

            增加新的節(jié)點(diǎn)類變得很困難。每增加一個(gè)新的節(jié)點(diǎn)都意味著要在抽象訪問者角色中增加一個(gè)新的抽象操作,并在每一個(gè)具體訪問者類中增加相應(yīng)的具體操作。
            破壞封裝。訪問者模式要求訪問者對(duì)象訪問并調(diào)用每一個(gè)節(jié)點(diǎn)對(duì)象的操作,這隱含了一個(gè)對(duì)所有節(jié)點(diǎn)對(duì)象的要求:它們必須暴露一些自己的操作和內(nèi)部狀態(tài)。不然,訪問者的訪問就變得沒有意義。由于訪問者對(duì)象自己會(huì)積累訪問操作所需的狀態(tài),從而使這些狀態(tài)不再存儲(chǔ)在節(jié)點(diǎn)對(duì)象中,這也是破壞封裝的。
              回復(fù)  更多評(píng)論   

            公告

            EMail:itech001#126.com

            導(dǎo)航

            統(tǒng)計(jì)

            • 隨筆 - 461
            • 文章 - 4
            • 評(píng)論 - 746
            • 引用 - 0

            常用鏈接

            隨筆分類

            隨筆檔案

            收藏夾

            Blogs

            c#(csharp)

            C++(cpp)

            Enlish

            Forums(bbs)

            My self

            Often go

            Useful Webs

            Xml/Uml/html

            搜索

            •  

            積分與排名

            • 積分 - 1807577
            • 排名 - 5

            最新評(píng)論

            閱讀排行榜

            久久笫一福利免费导航| 久久国产热精品波多野结衣AV| 99热成人精品热久久669| 97久久久久人妻精品专区| 国产亚洲综合久久系列| 精品国产热久久久福利| 97精品依人久久久大香线蕉97| 77777亚洲午夜久久多喷| 久久亚洲电影| 成人久久精品一区二区三区| 亚洲国产成人精品女人久久久 | 日本加勒比久久精品| 久久精品国产亚洲AV蜜臀色欲| 国产精品天天影视久久综合网| 色综合久久中文字幕综合网| 久久精品国产99久久丝袜| 精品国产乱码久久久久久呢| 国产亚州精品女人久久久久久| 久久人人爽人人爽人人片AV高清| 国产欧美一区二区久久| 欧美黑人激情性久久| 国产精品亚洲美女久久久| 久久久久久久综合日本| 久久被窝电影亚洲爽爽爽| 久久成人永久免费播放| 久久精品亚洲中文字幕无码麻豆 | 国产精品99久久久久久宅男| 亚洲色欲久久久综合网东京热| 久久久久久av无码免费看大片| 久久综合九色欧美综合狠狠| a级毛片无码兔费真人久久| 久久精品国产亚洲αv忘忧草| 四虎影视久久久免费观看| 国产精品伊人久久伊人电影| 欧美精品一本久久男人的天堂 | 久久久久久一区国产精品| 国产一区二区精品久久| 久久国产一区二区| 精品久久久久久中文字幕| 午夜人妻久久久久久久久| 99精品国产99久久久久久97|