<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國際加速解決方案。 廣告
                ### Separate Domain from Presentation(將領域和表述/顯示分離) (譯注:本節保留domain-,presentation-logic,UI,class,object等英文詞) 某些GUI class 之中包含了domain logic(領域邏輯)。 將domain logic(領域邏輯)分離出來,為它們建立獨立的domain class。 ![](https://box.kancloud.cn/2016-08-15_57b1b5e8a5946.gif) **動機(Motivation)** 提到面向對象,就不能不提model-view-controller (MVC,模型-視圖-控制器) 模式。在Smalltalk-80環境中,人們以此模式維護GUI(圖形用戶界面)和domain object (領域對象)間的關系。 MVC模式的最核心價值在于:它將用戶界面代碼(即所謂view,視圖;亦即現今常說的presentation,表述)和領域邏輯(即所謂model,模型)分離了。presentation class 只含用以處理用戶界面的邏輯;domain class不含任何與程序外觀相關的代碼,只含業務邏輯(business logic)相關代碼。將程序中這兩塊復雜的部分加以分離,程序未來的修改將變得更加容易,同時也使同一業務邏輯(business logic)的多種表述(顯示)方式成為可能。那些熟稔面向對象技術的程序員會毫不猶豫地在他們的程序中進行這種分離,并且這種作法也的確證實了它自身的價值。 但是,大多數人并沒有在設計中采用這種方式來處理GUI。大多數帶有client-server GUIs 的環境都釆用雙層(two-tier)邏輯設計:數據保存在數據庫中,業務邏輯(business logic)放在presentation class 中。這樣的環境往往迫使你也傾向這種風格的設計,使你很難把業務邏輯放在其他地方。 Java 是一個真正意義上的面向對象環境,因此你可以創建內含業務邏輯的非視覺性領域對象(nonvisual domain objects )。但你卻還是會經常遇到上述雙層風格寫就的程序。 **作法(Mechanics)** - 為每個窗口(window)建立一個domain class。 - 如果窗口內有一張表格(grid),新建一個class 來表示其中的行(row),再以窗口所對應之domain class 中的一個群集(collection)來容納所有的row domain objects。 - 檢查窗口中的數據。如果數據只被用于UI,就把它留著;如果數據被domain logic使用,而且不顯示于窗口上,我們就以Mocve Field 將它搬移到domain class 中;如果數據同時被UI 和domain logic 使用,就對它實施Duplicate Observed Data,使它同時存在于兩處,并保持兩處之間的同步。 - 檢査presentation class 中的邏輯。實施 Extract Method 將presentation logic 從domain logic 中分開。一旦隔離了domain logic。再運用 Move Method 將它移到domain class。 - 以上步驟完成后,你就擁有了兩組彼此分離的classes:presentation classes 用以處理GUI,domain logic 內含所有業務邏輯(business logic)。此時的domain classes 組織可能還不夠嚴謹,更進一步的重構將解決這些問題。 **范例:(Example)** 下面是一個商品訂購程序。其GUI 如圖12.7所示,其presentation class 與圖12.8 所示的關系式數據庫(relational database)互動。 ![](https://box.kancloud.cn/2016-08-15_57b1b5e8bab16.gif) 圖12.7 啟動程序的用戶界面 ![](https://box.kancloud.cn/2016-08-15_57b1b5e8cefae.gif) 圖12.8 訂單程序所用的數據庫 - 所有classes 都是《SQL table》,粗體字表示主鍵(primary key),《FK》表示外鍵(foreign keys) 所有行為(包括GUI 和定單處理)都由OrderWindow class 處理。 首先建立一個Order class 表示「定單」。然后把Order 和OrderWindow 聯系起來, 如圖12.9。由于窗口中有一個用以顯示定單的表格(grid),所以我們還得建立一個OrderLine,用以表示表格中的每一行(rows)。 ![](https://box.kancloud.cn/2016-08-15_57b1b5e8e5116.gif) 圖12.9 OrderWindow class 和Order class 我們將從窗口這邊而不是從數據庫那邊開始重構。當然,一開始就把domain model 建立在數據庫基礎上,也是一種合理策略,但我們最大的風險源于presentation logic 和domain logic之間的混淆,因此我們首先基于窗口將這些分離出來,然后再考慮對其他地方進行重構。 面對這一類程序,在窗口中尋找內嵌的SQL (結構化查詢語言)語句,會對你有所幫助,因為SQL 語句獲取的數據一定是domain data 。 最容易處理的domain data 就是那些不直接顯示于GUI 者。本例數據庫的Customer table 中有一個Codes 值域,它并不直接顯示于GUI,而是被轉換為一個更容易被人理解的短語之后再顯示。程序中以簡單型別(而非AWT組件)如String 保存這個值域值。我們可以安全地使用Move Field 將這個值域移到domain class。 對于其他值域,我們就沒有這么幸運了,因為它們內含AWT 組件,既顯示于窗口, 也被domain object 使用。面對這些值域,我們需要使用Duplicate Observed Data,把一個domain field 放進Order class,又把一個相應的AWT field 放進OrderWindow class。 這是一個緩慢的過程,但最終我們還是可以把所有domain logic field 都搬到domain class。進行這一步驟時,你可以試著把所有SQL calls 都移到domain class,這樣你就是同時移動了database logic 和domain data。最后,你可以在OrderWindow 中移除import java.sql 之類的語句,這就表示我們的重構告一段落了。在此階段中 你可能需要大量運用 Extract Method 和 Move Method。 現在,我們擁有的三個classes,如圖12.10所示,它們離「組織良好」還有很大的距離。不過這個模型的確已經很好地分離了presentation logic 和domain logic (business logic)。本項重構的進行過程中,你必須時刻留心你的風險來自何方。 如果「presentation logic 和domain logic 混淆」是最大風險,那么就先把它們完全分開,然后才做其他工作;如果其他方面的事情(例如產品定價策略〉更重要,那么就先把那一部分的logic 從窗口提煉出來,并圍繞著這個高風險部分進行重構,為它建立合適的結構。反正domain logic 早晚都必須從窗口移出,如果你在處理高風險部分的重構時會遺留某些logic 于窗口之中,沒關系,就放手去做吧。 ![](https://box.kancloud.cn/2016-08-15_57b1b5e902e37.gif) 圖12.10 將數據安置(分散)于domain classes 中
                  <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>

                              哎呀哎呀视频在线观看