亚洲欧美第一页_禁久久精品乱码_粉嫩av一区二区三区免费野_久草精品视频

? 歡迎來到蟲蟲下載站! | ?? 資源下載 ?? 資源專輯 ?? 關(guān)于我們
? 蟲蟲下載站

?? pat5k-1.htm

?? 四人幫《設(shè)計(jì)模式》一書英文版本
?? HTM
?? 第 1 頁(yè) / 共 3 頁(yè)
字號(hào):
<A NAME="auto1042"></A>
<LI><EM>Adding new ConcreteElement classes is hard.</EM>
The Visitor pattern makes it hard to add new subclasses of Element. Each
new ConcreteElement gives rise to a new abstract operation on Visitor and
a corresponding implementation in every ConcreteVisitor class. Sometimes a
default implementation can be provided in Visitor that can be inherited
by most of the ConcreteVisitors, but this is the exception rather than
the rule.

<A NAME="auto1043"></A>
<P>So the key consideration in applying the Visitor pattern is whether you
are mostly likely to change the algorithm applied over an object
structure or the classes of objects that make up the structure. The
Visitor class hierarchy can be difficult to maintain when new
ConcreteElement classes are added frequently. In such cases, it's
probably easier just to define operations on the classes that make up
the structure. If the Element class hierarchy is stable, but you are
continually adding operations or changing algorithms, then the Visitor
pattern will help you manage the changes.</P>

</LI>

<A NAME="trav-across-class"></A>
<LI><EM>Visiting across class hierarchies.</EM>
An iterator (see <A HREF="pat5dfs-1.htm" tppabs="http://ultra/development/DesignPatterns/lowres/pat5dfs.htm" TARGET="_mainDisplayFrame">Iterator (257)</A>) can visit the objects in a
structure as it traverses them by calling their operations. But an iterator
can't work across object structures with different types of elements. For
example, the Iterator interface defined on
<A HREF="pat5dfs-1.htm#class_Iterator_declaration" tppabs="http://ultra/development/DesignPatterns/lowres/pat5dfs.htm#class_Iterator_declaration" TARGET="_mainDisplayFrame">page 263</A> can access only objects of type <CODE>Item</CODE>:

<A NAME="auto1044"></A>
<PRE>
    template &lt;class Item>
    class Iterator {
        // ...
        Item CurrentItem() const;
    };
</PRE>

<A NAME="auto1045"></A>
<P>This implies that all elements the iterator can visit have a common parent
class <CODE>Item</CODE>.</P>

<A NAME="auto1046"></A>
<P>Visitor does not have this restriction.  It can visit objects that
don't have a common parent class. You can add any type of object to a
Visitor interface.  For example, in</P>

<A NAME="auto1047"></A>
<PRE>
    class Visitor {
    public:
        // ...
        void VisitMyType(MyType*);
        void VisitYourType(YourType*);
    };
</PRE>

<A NAME="auto1048"></A>
<P><CODE>MyType</CODE> and <CODE>YourType</CODE> do not have to be related through
inheritance at all.</P>

</LI>

<A NAME="auto1049"></A>
<P></P>

<A NAME="accumulatingstate"></A>
<LI><EM>Accumulating state.</EM>
Visitors can accumulate state as they visit each element in the object
structure.  Without a visitor, this state would be passed as extra
arguments to the operations that perform the traversal, or they
might appear as global variables.</LI>

<A NAME="auto1050"></A>
<P></P>

<A NAME="breakencap"></A>
<LI><EM>Breaking encapsulation.</EM>
Visitor's approach assumes that the ConcreteElement interface is powerful
enough to let visitors do their job.  As a result, the pattern often
forces you to provide public operations that access an element's
internal state, which may compromise its encapsulation.</LI>

</OL>

<A NAME="implementation"></A>
<H2><A HREF="#samplecode"><IMG SRC="down3-1.gif" tppabs="http://ultra/development/DesignPatterns/lowres/gifsb/down3.gif" BORDER=0 ALT="next: 
Sample Code"></A> Implementation</H2> 

<A NAME="auto1051"></A>
<P>Each object structure will have an associated Visitor class.  This
abstract visitor class declares a VisitConcreteElement operation for
each class of ConcreteElement defining the object structure.  Each
Visit operation on the Visitor declares its argument to be a
particular ConcreteElement, allowing the Visitor to access the
interface of the ConcreteElement directly.  ConcreteVisitor classes
override each Visit operation to implement visitor-specific behavior
for the corresponding ConcreteElement class.</P>

<A NAME="auto1052"></A>
<P>The Visitor class would be declared like this in C++:</P>

<A NAME="auto1053"></A>
<PRE>
    class Visitor {
    public:
        virtual void VisitElementA(ElementA*);
        virtual void VisitElementB(ElementB*);
    
        // and so on for other concrete elements
    protected:
        Visitor();
    };
</PRE>

<A NAME="auto1054"></A>
<P>Each class of ConcreteElement implements an <CODE>Accept</CODE> operation
that calls the matching <CODE>Visit...</CODE> operation on the visitor
for that ConcreteElement.  Thus the operation that ends up getting
called depends on both the class of the element and the class of the
visitor.<A NAME="fn10"></A><SUP><A HREF="#footnote10">10</A></SUP></P>

<A NAME="auto1055"></A>
<P>The concrete elements are declared as</P>

<A NAME="auto1056"></A>
<PRE>
    class Element {
    public:
        virtual ~Element();
        virtual void Accept(Visitor&amp;) = 0;
    protected:
        Element();
    };
    
    class ElementA : public Element {
    public:
        ElementA();
        virtual void Accept(Visitor&amp; v) { v.VisitElementA(this); }
    };
    
    class ElementB : public Element {
    public:
        ElementB();
        virtual void Accept(Visitor&amp; v) { v.VisitElementB(this); }
    };
</PRE>

<A NAME="auto1057"></A>
<P>A <CODE>CompositeElement</CODE> class might implement <CODE>Accept</CODE>
like this:</P>

<A NAME="auto1058"></A>
<PRE>
    class CompositeElement : public Element {
    public:
        virtual void Accept(Visitor&amp;);
    private:
        List&lt;Element*>* _children;
    };
    
    void CompositeElement::Accept (Visitor&amp; v) {
        ListIterator&lt;Element*> i(_children);
    
        for (i.First(); !i.IsDone(); i.Next()) {
            i.CurrentItem()->Accept(v);
        }
        v.VisitCompositeElement(this);
    }
</PRE>

<A NAME="auto1059"></A>
<P>Here are two other implementation issues that arise when you apply the
Visitor pattern:</P>

<OL>

<A NAME="doubledispatch"></A>
<A NAME="singledispatch"></A>
<LI><EM>Double dispatch.</EM>
Effectively, the Visitor pattern lets you add operations to classes
without changing them.  Visitor achieves this by using a technique
called <STRONG>double-dispatch</STRONG>.  It's a well-known technique.  In
fact, some programming languages support it directly (CLOS, for
example).  Languages like C++ and Smalltalk support
<STRONG>single-dispatch</STRONG>.

<A NAME="auto1060"></A>
<P>In single-dispatch languages, two criteria determine which operation
will fulfill a request: the name of the request and the type of
receiver. For example, the operation that a GenerateCode request will
call depends on the type of node object you ask. In C++, calling
<CODE>GenerateCode</CODE> on an instance of <CODE>VariableRefNode</CODE> will
call <CODE>VariableRefNode::GenerateCode</CODE> (which generates code for a
variable reference). Calling <CODE>GenerateCode</CODE> on an
<CODE>AssignmentNode</CODE> will call
<CODE>AssignmentNode::GenerateCode</CODE> (which will generate code for an
assignment). The operation that gets executed depends both on the kind
of request and the type of the receiver.</P>

<A NAME="auto1061"></A>
<P>"Double-dispatch" simply means the operation that gets executed
depends on the kind of request and the types of <EM>two</EM> receivers.
<CODE>Accept</CODE> is a double-dispatch operation.  Its meaning depends
on two types: the Visitor's and the Element's.  Double-dispatching
lets visitors request different operations on each class of
element.<A NAME="fn11"></A><SUP><A HREF="#footnote11">11</A></SUP></P>

<A NAME="auto1062"></A>
<P>This is the key to the Visitor pattern: The operation that gets
executed depends on both the type of Visitor and the type of Element
it visits.  Instead of binding operations statically into the Element
interface, you can consolidate the operations in a Visitor and use
<CODE>Accept</CODE> to do the binding at run-time.  Extending the Element
interface amounts to defining one new Visitor subclass rather than many new
Element subclasses.</P>

</LI>

<A NAME="trav-responsibility"></A>
<LI><EM>Who is responsible for traversing the object structure?</EM>
A visitor must visit each element of the object structure. The question
is, how does it get there? We can put responsibility for traversal in
any of three places: in the object structure, in the visitor, or in a
separate iterator object (see <A HREF="pat5dfs-1.htm" tppabs="http://ultra/development/DesignPatterns/lowres/pat5dfs.htm" TARGET="_mainDisplayFrame">Iterator (257)</A>).

<A NAME="auto1063"></A>
<P>Often the object structure is responsible for iteration. A collection
will simply iterate over its elements, calling the Accept operation on
each. A composite will commonly traverse itself by having each Accept
operation traverse the element's children and call Accept on each of
them recursively.</P>

<A NAME="iter-ext-int"></A>
<P>Another solution is to use an iterator to visit the elements. In C++,
you could use either an internal or external iterator, depending on what
is available and what is most efficient. In Smalltalk, you usually use
an internal iterator using <CODE>do:</CODE> and a block. Since internal
iterators are implemented by the object structure, using an internal
iterator is a lot like making the object structure responsible for
iteration. The main difference is that an internal iterator will not
cause double-dispatching&#151;it will call an operation on the <EM>visitor</EM> with an <EM>element</EM> as an argument as opposed to calling an
operation on the <EM>element</EM> with the <EM>visitor</EM> as an argument.
But it's easy to use the Visitor pattern with an internal iterator if
the operation on the visitor simply calls the operation on the element
without recursing.</P>

<A NAME="auto1064"></A>
<P>You could even put the traversal algorithm in the visitor, although you'll
end up duplicating the traversal code in each ConcreteVisitor for each
aggregate ConcreteElement. The main reason to put the traversal strategy
in the visitor is to implement a particularly complex traversal, one
that depends on the results of the operations on the object structure.
We'll give an example of such a case in the Sample Code.</P>

</LI>

</OL>

<A NAME="samplecode"><A>
<H2><A HREF="#knownuses"><IMG SRC="down3-1.gif" tppabs="http://ultra/development/DesignPatterns/lowres/gifsb/down3.gif" BORDER=0 ALT="next: 
Known Uses"></A> Sample Code</H2> 

<A NAME="auto1065"></A>
<P>Because visitors are usually associated with composites, we'll use the
<CODE>Equipment</CODE> classes defined in the Sample Code of
<A HREF="pat4cfs-1.htm" tppabs="http://ultra/development/DesignPatterns/lowres/pat4cfs.htm" TARGET="_mainDisplayFrame">Composite (163)</A> to illustrate the Visitor pattern.  We
will use Visitor to define operations for computing the
inventory of materials and the total cost for a piece of equipment.
The <CODE>Equipment</CODE> classes are so simple that using Visitor
isn't really necessary, but they make it easy to see what's
involved in implementing the pattern.</P>

<A NAME="equipment"></A>
<P>Here again is the <CODE>Equipment</CODE> class from
<A HREF="pat4cfs-1.htm" tppabs="http://ultra/development/DesignPatterns/lowres/pat4cfs.htm" TARGET="_mainDisplayFrame">Composite (163)</A>.  We've augmented it with an
<CODE>Accept</CODE> operation to let it work with a visitor.</P>

<A NAME="auto1066"></A>
<PRE>
    class Equipment {
    public:
        virtual ~Equipment();
    
        const char* Name() { return _name; }
    
        virtual Watt Power();
        virtual Currency NetPrice();
        virtual Currency DiscountPrice();
    
        virtual void Accept(EquipmentVisitor&amp;);
    protected:
        Equipment(const char*);
    private:
        const char* _name;
    };
</PRE>

<A NAME="auto1067"></A>
<P>The <CODE>Equipment</CODE> operations return the attributes of a piece of
equipment, such as its power consumption and cost.  Subclasses redefine
these operations appropriately for specific types of equipment (e.g.,
a chassis, drives, and planar boards).</P>

<A NAME="auto1068"></A>
<P>The abstract class for all visitors of equipment has a virtual
function for each subclass of equipment, as shown next.  All of the
virtual functions do nothing by default.</P>

<A NAME="equip-visit"></A>
<PRE>
    class EquipmentVisitor {
    public:
        virtual ~EquipmentVisitor();
    
        virtual void VisitFloppyDisk(FloppyDisk*);

?? 快捷鍵說明

復(fù)制代碼 Ctrl + C
搜索代碼 Ctrl + F
全屏模式 F11
切換主題 Ctrl + Shift + D
顯示快捷鍵 ?
增大字號(hào) Ctrl + =
減小字號(hào) Ctrl + -
亚洲欧美第一页_禁久久精品乱码_粉嫩av一区二区三区免费野_久草精品视频
五月婷婷久久综合| 午夜久久久久久电影| 亚洲一区视频在线| 狠狠色综合播放一区二区| 一本一本大道香蕉久在线精品| 欧美精品一卡二卡| 亚洲欧美在线视频观看| 久久99国产精品免费| 欧美日韩一区二区在线观看视频 | 色婷婷精品大视频在线蜜桃视频| 制服丝袜在线91| 亚洲另类在线视频| 成人久久视频在线观看| 精品国产露脸精彩对白| 日韩精品一级中文字幕精品视频免费观看 | 在线一区二区观看| 中文字幕免费不卡| 精品在线一区二区三区| 欧美人妇做爰xxxⅹ性高电影| 中文字幕在线不卡国产视频| 国产专区欧美精品| 精品国产乱码久久久久久老虎| 午夜精品久久久久久久久| 色综合天天综合在线视频| 欧美丝袜丝nylons| 中文字幕亚洲综合久久菠萝蜜| 狠狠狠色丁香婷婷综合久久五月| 欧美日韩中文字幕精品| 一区二区三区免费| 91浏览器打开| 一区二区三区在线免费观看| 99久久久久免费精品国产| 国产精品福利一区| 9i看片成人免费高清| 亚洲欧美综合色| 91麻豆免费看| 亚洲国产精品久久不卡毛片| 日本高清不卡一区| 亚洲成av人综合在线观看| 欧美私人免费视频| 日本一道高清亚洲日美韩| 欧美一区二区在线看| 免费在线观看不卡| 久久久久久久久久久电影| 国产福利一区二区三区视频| 日本一区二区三区四区| 不卡免费追剧大全电视剧网站| 亚洲人成精品久久久久久| 色婷婷亚洲精品| 日韩精品免费专区| 精品剧情在线观看| 成人av中文字幕| 一区二区免费在线播放| 91麻豆精品国产91久久久久久久久 | 亚洲综合色成人| 欧美久久一二三四区| 久久精品国产亚洲a| 国产精品三级视频| 91麻豆国产福利精品| 日本aⅴ亚洲精品中文乱码| 精品精品国产高清一毛片一天堂| 国产91精品欧美| 亚洲美女免费视频| 精品日韩99亚洲| 91免费看视频| 秋霞电影一区二区| 国产精品九色蝌蚪自拍| 欧美色图天堂网| 国产精品一区二区免费不卡 | 波多野结衣欧美| 亚洲一区二区3| 久久久久久亚洲综合影院红桃| 成人动漫av在线| 久久精品国产77777蜜臀| 亚洲人成网站在线| 欧美精品一区二区三区很污很色的 | 不卡视频在线观看| 久久国产视频网| 亚洲一区二区三区在线| 久久老女人爱爱| 3d动漫精品啪啪一区二区竹菊| 成人av动漫在线| 精品一区在线看| 亚洲国产美国国产综合一区二区| 国产欧美日韩精品在线| 91麻豆精品国产自产在线| 色综合一区二区| 国产suv精品一区二区883| 蜜臀91精品一区二区三区| 有码一区二区三区| 国产精品毛片高清在线完整版| 国产成人aaa| 欧美一区二区三区视频免费| 91丨九色丨蝌蚪丨老版| 精久久久久久久久久久| 肉色丝袜一区二区| 亚洲一二三专区| 亚洲天堂中文字幕| 国产精品人人做人人爽人人添| 91精品国产乱码| 欧美人与性动xxxx| 欧美无砖专区一中文字| 91丨九色porny丨蝌蚪| 成人黄页在线观看| 国产**成人网毛片九色| 国产麻豆精品在线观看| 免费人成黄页网站在线一区二区 | 99在线视频精品| 丁香一区二区三区| 国产精品123| 国产精品一区专区| 国产黄色91视频| 成人丝袜18视频在线观看| 韩日av一区二区| 激情综合网天天干| 国产精品一二三区| 国产成人自拍高清视频在线免费播放 | 国产一区二区在线视频| 久久99国产精品成人| 九色porny丨国产精品| 免费一级欧美片在线观看| 五月婷婷色综合| 精品影院一区二区久久久| 韩国精品主播一区二区在线观看| 黄色日韩网站视频| 国产精品一区二区三区网站| 成人黄色国产精品网站大全在线免费观看| 国产精品99久久不卡二区| 99久久er热在这里只有精品66| 色综合久久天天综合网| 欧美写真视频网站| 日韩亚洲欧美在线观看| 亚洲精品在线观看网站| 国产精品日韩精品欧美在线| 亚洲精品乱码久久久久久日本蜜臀| 亚洲欧美自拍偷拍色图| 午夜精品福利一区二区三区av| 极品美女销魂一区二区三区免费| 国产精品69久久久久水密桃| 本田岬高潮一区二区三区| 欧美亚洲自拍偷拍| 精品国产制服丝袜高跟| 国产精品成人免费| 天天av天天翘天天综合网色鬼国产| 日本aⅴ亚洲精品中文乱码| 国产精品一二二区| 欧美三电影在线| 久久影音资源网| 亚洲欧美日韩国产中文在线| 日韩中文欧美在线| 国产成都精品91一区二区三| 欧美午夜精品久久久久久孕妇| 精品免费国产二区三区| 亚洲美女电影在线| 久久精品久久精品| 欧美在线观看视频一区二区三区| 精品国产一区二区三区忘忧草| 亚洲少妇30p| 蜜臀av一级做a爰片久久| 成人综合婷婷国产精品久久蜜臀 | 欧美又粗又大又爽| 2021国产精品久久精品| 夜夜爽夜夜爽精品视频| 国模少妇一区二区三区| 欧美三级资源在线| 国产精品三级电影| 韩国一区二区三区| 欧美日韩精品一区二区三区 | 日本美女一区二区三区视频| 国产ts人妖一区二区| 日韩精品资源二区在线| 亚洲午夜视频在线观看| 成人激情开心网| 亚洲精品一区二区精华| 日韩经典中文字幕一区| 91在线国产观看| 久久精品男人天堂av| 免费日本视频一区| 欧美日韩午夜在线视频| 亚洲欧洲日产国码二区| 国产一区二区三区免费看| 欧美一区二区在线看| 亚洲午夜视频在线| 欧美在线观看视频一区二区三区| 国产日韩av一区| 国产一区免费电影| 日韩欧美国产麻豆| 日韩高清在线一区| 欧美偷拍一区二区| 亚洲激情综合网| 日本丰满少妇一区二区三区| 中文字幕第一区二区| 国产精品66部| 国产欧美日韩精品一区| 九九国产精品视频| 精品日韩一区二区| 国产乱子轮精品视频| 久久亚洲一级片| 国产一区二区三区四区五区入口| 精品国产一区二区三区久久久蜜月|