<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>

                ??碼云GVP開源項目 12k star Uniapp+ElementUI 功能強大 支持多語言、二開方便! 廣告
                ### Replace Type Code with Subclasses(以子類取代型別碼) 你有一個不可變的(immutable)type code ,它會影響class 的行為。 以一個subclass 取代這個type code。 ![](https://box.kancloud.cn/2016-08-15_57b1b5a9ac48d.gif) **動機(Motivation)** 如果你面對的type code 不會影響宿主類的行為,你可以使用Replace Type Code with Class 來處理它們。但如果type code 會影響宿主類的行為,那么最好的辦法就是借助多態(polymorphism )來處理變化行為。 一般來說,這種情況的標志就是像switch 這樣的條件式。這種條件式可能有兩種表現形式:switch 語句或者if-then-else 結構。不論哪種形式,它們都是檢查type code 值,并根據不同的值執行不同的動作。這種情況下你應該以Replace Conditional with Polymorphism 進行重構。但為了能夠順利進行那樣的重構,首先應該將type code 替換為可擁有多態行為的繼承體系。這樣的一個繼承體系應該以type code 的宿主類為base class,并針對每一種type code 各建立一個subclass 。 為建立這樣的繼承體系,最簡單的辦法就是Replace Type Code with Subclasses:以type code 的宿主類為base class,針對每種type code 建立相應的subclass 。 但是以下兩種情況你不能那么做:(1) type code 值在對象創建之后發生了改變;(2) 由于某些原因,type code 宿主類已經有了subclass 。如果你恰好面臨這兩種情況之一,就需要使用Replace Type Code with State/Strategy 。 Replace Type Code with Subclasses 的主要作用其實是搭建一個舞臺,讓Replace Conditional with Polymorphism 得以一展身手。如果宿主類中并沒有出現條件式,那么 Replace Type Code with Class 更合適,風險也比較低。使用Replace Type Code with Subclasses 的另一個原因就是,宿主類中出現 了「只與具備特定type code 之對象相關」的特性。完成本項重構之后,你可以使用 Push Down Method 和 Push Down Field 將這些特性推到合適的subclass去,以彰顯它們「只與特定情況相關」這一事實。 Replace Type Code with Subclasses 的好處在于:它把「對不同行為的了解」從class 用戶那兒轉移到了class 自身。如果需要再加入新的行為變化,我只需添加subclass 一個就行了。如果沒有多態機制,我就必須找到所有條件式,并逐一修改它們。因此,如果未來還有可能加入新行為,這項重構將特別有價值。 **作法(Mechanics)** - 使用Self-encapsulate Field 將type code 自我封裝起來。 - 如果type code 被傳遞給構造函數,你就需要將構造函數換成factory method。 - 為type code 的每一個數值建立一個相應的subclass 。在每個subclass 中覆寫(override)type code的取值函數(getter),使其返回相應的type code 值。 - 這個值被硬編碼于return 中(例如:return 1)。這看起來很骯臟, 但只是權宜之計。當所有case 子句都被替換后,問題就解決了。 - 每建立一個新的subclass ,編譯并測試。 - 從superclass 中刪掉保存type code 的值域。將type code 訪問函數(accessors)聲明為抽象函數(abstract method)。 - 編譯,測試。 **范例(Example)** 為簡單起見,我還是使用那個惱人又不切實際的「雇員/薪資」例。我們以Employee 表示「雇員」: ~~~ class Employee... private int _type; static final int ENGINEER = 0; static final int SALESMAN = 1; static final int MANAGER = 2; Employee (int type) { _type = type; } ~~~ 第一步是以Self-encapsulate Field 將type code 自我封裝起來: ~~~ int getType() { return _type; } ~~~ 由于Employee 構造函數接受type code 作為一個參數,所以我必須將它替換為一個factory method: ~~~ static Employee create(int type) { return new Employee(type); } private Employee (int type) { _type = type; } ~~~ 現在,我可以先建立一個subclassEngineer「表示「工程師」。首先我建立這個subclass,并在其中覆寫type code 取值函數: ~~~ class Engineer extends Employee { int getType() { return Employee.ENGINEER; } } ~~~ 同時我該修改factory method ,令它返回一個合適的對象: ~~~ class Employee static Employee create(int type) { if (type == ENGINEER) return new Engineer(); else return new Employee(type); } ~~~ 然后,我繼續逐一地處理其他type code ,直到所有type code 都被替換成subclass 為止。此時我就可以移除Employee 中保存type code 的值域,并將getType() 聲明為一個抽象函數。現在,factory method 看起來像這樣: ~~~ abstract int getType(); static Employee create(int type) { switch (type) { case ENGINEER: return new Engineer(); case SALESMAN: return new Salesman(); case MANAGER: return new Manager(); default: throw new IllegalArgumentException("Incorrect type code value"); } } ~~~ 當然,我總是避免使用switch 語句。但這里只有一處用到switch 語句,并且只用于決定創建何種對象,這樣的switch 語句是可以接受的。 很自然地,在建立了這些subclass 之后,你就應該使用 Push Down Method 和 Push Down Field,將「只與特定種類的雇員相關」的函數和值域推到相關的subclass 去。
                  <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>

                              哎呀哎呀视频在线观看