<ruby id="bdb3f"></ruby>

    <p id="bdb3f"><cite id="bdb3f"></cite></p>

      <p id="bdb3f"><cite id="bdb3f"><th id="bdb3f"></th></cite></p><p id="bdb3f"></p>
        <p id="bdb3f"><cite id="bdb3f"></cite></p>

          <pre id="bdb3f"></pre>
          <pre id="bdb3f"><del id="bdb3f"><thead id="bdb3f"></thead></del></pre>

          <ruby id="bdb3f"><mark id="bdb3f"></mark></ruby><ruby id="bdb3f"></ruby>
          <pre id="bdb3f"><pre id="bdb3f"><mark id="bdb3f"></mark></pre></pre><output id="bdb3f"></output><p id="bdb3f"></p><p id="bdb3f"></p>

          <pre id="bdb3f"><del id="bdb3f"><progress id="bdb3f"></progress></del></pre>

                <ruby id="bdb3f"></ruby>

                合規國際互聯網加速 OSASE為企業客戶提供高速穩定SD-WAN國際加速解決方案。 廣告
                # 訪問者設計模式示例 > 原文: [https://howtodoinjava.com/design-patterns/behavioral/visitor-design-pattern-example-tutorial/](https://howtodoinjava.com/design-patterns/behavioral/visitor-design-pattern-example-tutorial/) [**設計模式**](//howtodoinjava.com/category/design-patterns/ "design patterns")用于解決模式中出現的問題,我們都知道,對吧? 我們也知道[**行為型設計模式**](//howtodoinjava.com/category/design-patterns/behavioral/ "behavioral patterns")是識別對象之間常見通信模式的設計模式。 這種行為型模式之一是訪問者模式,我們將在本文中學習。 如果您一直在處理管理大量產品的應用,那么您可以輕松地解決此問題: “您需要在類的層次結構中添加一個新方法,但是添加該方法可能會給設計帶來痛苦或破壞。” 顯然,您**希望對象的層次結構可以修改其行為,而不需要修改其源代碼**。 怎么做? 為了解決這個問題,訪問者模式成為現實。 ```java Sections in this post: Visitor pattern introduction Design participants/components Sample problem to solve Proposed solution using Visitor pattern Implementation code How to use visitors in application code 源碼下載 ``` ## 訪問者模式介紹 根據維基百科所述, [**訪問者設計模式**](https://en.wikipedia.org/wiki/Visitor_pattern "visitor pattern")是一種將算法與操作對象的結構分離的方法。 這種分離的實際結果是能夠在不修改那些對象結構的情況下向現有對象結構添加新操作。 這是遵循**開閉原則**([**SOLID 設計原則**](//howtodoinjava.com/best-practices/5-class-design-principles-solid-in-java/ "5 class design principles [S.O.L.I.D.] in java") 之一)的一種方法。 上面的設計靈活性允許將方法添加到任何對象層次結構,而無需修改為層次結構編寫的代碼。 而是使用[**雙調度**](https://en.wikipedia.org/wiki/Double_dispatch "double dispatch")機制來實現此功能。 雙調度是一種特殊的機制,可以根據調用中涉及的兩個對象的運行時類型,將函數調用分派給不同的具體函數。 ## 設計參與者/組件 此模式中的參與者類是: **`Visitor`** – 這是用于聲明所有可訪問類類型的訪問操作的接口或抽象類。 **`ConcreteVisitor`** – 對于每種類型的訪問者,必須實現在抽象訪問者中聲明的所有訪問方法。 每個訪問者將負責不同的操作。 **`Visitable`** – 是一個聲明接受操作的接口。 這是使訪問者對象可以“訪問”對象的入口點。 **`ConcreteVisitable`** – 這些類實現了 Visitable 接口或類并定義了接受操作。 使用 accept 操作將訪問者對象傳遞給該對象。 ## 要解決的示例問題 一個例子總是比冗長的理論更好。 因此,讓我們在這里也有一個訪問者設計模式。 假設我們有一個在不同環境中管理路由的應用。 路由應該能夠從其他節點發送和接收字符數據,應用應該能夠在不同的環境中配置路由。 本質上,設計應該足夠靈活,以支持**路由將來可以在其他環境中進行配置的方式,而無需對源代碼**進行大量修改。 ![Existing routers in application](https://img.kancloud.cn/73/8c/738cc57060b72ca551160ae5aa77dd1e_870x353.png "Existing routers in application") 應用中的現有路由 我們有以上 3 種類型的路由,我們需要為它們編寫代碼。 **解決此問題的一種方法**是在`Router.java`接口中定義諸如`configureForWinodws()`和`configureForLinux()`之類的方法,并在不同的產品中實現它們,因為每種方法都有自己的配置設置和過程。 但是上述方法的問題在于,每次引入新環境時,都必須重新編譯整個路由的層次結構。 不可接受的解決方案。 那么什么可以預防這種情況呢? ## 使用訪問者模式的建議解決方案 訪問者模式非常適合這些類型的問題,在這些類型的問題中,您希望對對象的層次結構引入新的操作,而無需更改其結構或對其進行修改。 在此解決方案中,我們將通過引入兩種方法(即`accept()`和`visit()`方法)來實現**雙調度技術**。 方法`accept()`,將在路由的層次結構中定義,訪問方法將在訪問者級別。 每當需要添加新環境時,都會將新的訪問者添加到訪問者層次結構中,這需要為所有可用的路由實現`visit()`方法,僅此而已。 ![Solution using visitor pattern](https://img.kancloud.cn/85/15/8515d1bc588c50c63ba67eebeb91e578_956x626.png "Solution using visitor pattern") 使用訪問者模式的解決方案 在上面的類圖中,我們為 Mac 和 Linux 操作系統配置了路由。 如果我們還需要添加 Windows 功能,那么我不需要更改任何類,只需定義一個新的訪問者`WindowsConfigurator`并實現`RouterVisitor`接口中定義的`visit()`方法。 它將提供所需的功能,而無需任何進一步的修改。 ## 實現代碼 讓我們看一下上面討論的問題和解決方案所涉及的不同文件的源代碼。 **`Router.java`** ```java public interface Router { public void sendData(char[] data); public void acceptData(char[] data); public void accept(RouterVisitor v); } ``` **`DLinkRouter.java`** ```java public class DLinkRouter implements Router{ @Override public void sendData(char[] data) { } @Override public void acceptData(char[] data) { } @Override public void accept(RouterVisitor v) { v.visit(this); } } ``` **`LinkSysRouter.java`** ```java public class LinkSysRouter implements Router{ @Override public void sendData(char[] data) { } @Override public void acceptData(char[] data) { } @Override public void accept(RouterVisitor v) { v.visit(this); } } ``` **`TPLinkRouter.java`** ```java public class TPLinkRouter implements Router{ @Override public void sendData(char[] data) { } @Override public void acceptData(char[] data) { } @Override public void accept(RouterVisitor v) { v.visit(this); } } ``` **`RouterVisitor.java`** ```java public interface RouterVisitor { public void visit(DLinkRouter router); public void visit(TPLinkRouter router); public void visit(LinkSysRouter router); } ``` **`LinuxConfigurator.java`** ```java public class LinuxConfigurator implements RouterVisitor{ @Override public void visit(DLinkRouter router) { System.out.println("DLinkRouter Configuration for Linux complete !!"); } @Override public void visit(TPLinkRouter router) { System.out.println("TPLinkRouter Configuration for Linux complete !!"); } @Override public void visit(LinkSysRouter router) { System.out.println("LinkSysRouter Configuration for Linux complete !!"); } } ``` **`MacConfigurator.java`** ```java public class MacConfigurator implements RouterVisitor{ @Override public void visit(DLinkRouter router) { System.out.println("DLinkRouter Configuration for Mac complete !!"); } @Override public void visit(TPLinkRouter router) { System.out.println("TPLinkRouter Configuration for Mac complete !!"); } @Override public void visit(LinkSysRouter router) { System.out.println("LinkSysRouter Configuration for Mac complete !!"); } } ``` ## 如何在應用代碼中使用訪問者 要使用上述設計,請按以下給定方式使用訪問者。 我已經以 JUNIT 測試用例的形式使用了代碼,您可以以適合您的情況的方式更改代碼。 **`TestVisitorPattern.java`** ```java public class TestVisitorPattern extends TestCase { private MacConfigurator macConfigurator; private LinuxConfigurator linuxConfigurator; private DLinkRouter dlink; private TPLinkRouter tplink; private LinkSysRouter linksys; public void setUp() { macConfigurator = new MacConfigurator(); linuxConfigurator = new LinuxConfigurator(); dlink = new DLinkRouter(); tplink = new TPLinkRouter(); linksys = new LinkSysRouter(); } public void testDlink() { dlink.accept(macConfigurator); dlink.accept(linuxConfigurator); } public void testTPLink() { tplink.accept(macConfigurator); tplink.accept(linuxConfigurator); } public void testLinkSys() { linksys.accept(macConfigurator); linksys.accept(linuxConfigurator); } } Output: DLinkRouter Configuration for Mac complete !! DLinkRouter Configuration for Linux complete !! LinkSysRouter Configuration for Mac complete !! LinkSysRouter Configuration for Linux complete !! TPLinkRouter Configuration for Mac complete !! TPLinkRouter Configuration for Linux complete !! ``` #### 源代碼下載 要下載上述應用的源代碼,請遵循給定的鏈接。 [**下載源碼**](https://docs.google.com/file/d/0B7yo2HclmjI4YlJ2RkYxU3hNWDQ/edit?usp=sharing "visitor design pattern source code") **祝您學習愉快!**
                  <ruby id="bdb3f"></ruby>

                  <p id="bdb3f"><cite id="bdb3f"></cite></p>

                    <p id="bdb3f"><cite id="bdb3f"><th id="bdb3f"></th></cite></p><p id="bdb3f"></p>
                      <p id="bdb3f"><cite id="bdb3f"></cite></p>

                        <pre id="bdb3f"></pre>
                        <pre id="bdb3f"><del id="bdb3f"><thead id="bdb3f"></thead></del></pre>

                        <ruby id="bdb3f"><mark id="bdb3f"></mark></ruby><ruby id="bdb3f"></ruby>
                        <pre id="bdb3f"><pre id="bdb3f"><mark id="bdb3f"></mark></pre></pre><output id="bdb3f"></output><p id="bdb3f"></p><p id="bdb3f"></p>

                        <pre id="bdb3f"><del id="bdb3f"><progress id="bdb3f"></progress></del></pre>

                              <ruby id="bdb3f"></ruby>

                              哎呀哎呀视频在线观看