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

                企業??AI智能體構建引擎,智能編排和調試,一鍵部署,支持知識庫和私有化部署方案 廣告
                ### Replace Type Code with State/Strategy(以State/strategy 取代型別碼) 你有一個type code ,它會影響class 的行為,但你無法使用subclassing。 以state object (專門用來描述狀態的對象)取代type code 。 ![](https://box.kancloud.cn/2016-08-15_57b1b5a9c6380.gif) **動機(Motivation)** 本項重構和Replace Type Code with Subclasses 很相似,但如果「type code 的值在對象生命期中發生變化」或「其他原因使得宿主類不能被subclassing 」,你也可以使用本重構。本重構使用State 模式或Stategy 模式[Gang of Four]。 State 模式和Stategy 模式非常相似,因此無論你選擇其中哪一個,重構過程都是相同的。「選擇哪一個模式」并非問題關鍵所在,你只需要選擇更適合特定情境的模式就行了。如果你打算在完成本項重構之后再以 Replace Conditional with Polymorphism 簡化一個算法,那么選擇Stategy 模式比較合適;如果你打算搬移與狀態相關(state-specific)的數據,而且你把新建對象視為一種變遷狀態 (changing state),就應該選擇使用State 模式。 **作法(Mechanics)** - 使用Self-encapsulate Field 將type code 自我封裝起來。 - 新建一個class ,根據type code 的用途為它命名。這就是一個state object。 - 為這個新建的class 添加subclass ,每個subclass 對應一種type code 。 - 比起逐一添加,一次性加入所有必要的subclass 可能更簡單些。 - 在superclass 中建立一個抽象的查詢函數(abstract query ),用以返回type code 。 在每個subclass 中覆寫該函數,返回確切的type code 。 - 編譯。 - 在source class 中建立一個值域,用以保存新建的state object。 - 調整source class 中負責查詢type code 的函數,將查詢動作轉發給state object 。 - 調整source class 中「為type code 設值」的函數,將一個恰當的state object subclass 賦值給「保存state object」的那個值域。 - 編譯,測試。 **范例(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; } ~~~ 下面的代碼展示使用這些type code 的條件式: ~~~ int payAmount() { switch (_type) { case ENGINEER: return _monthlySalary; case SALESMAN: return _monthlySalary + _commission; case MANAGER: return _monthlySalary + _bonus; default: throw new RuntimeException("Incorrect Employee"); } } ~~~ 假設這是一家激情四溢、積極進取的公司,他們可以將表現出色的工程師擢升為經理。因此,對象的type code 是可變的,所以我不能使用subclassing 方式來處理type code 。和以前一樣,我的第一步還是使用Self Encapsulate Field 將表示type code 的值域自我封裝起來: ~~~ Employee (int type) { setType (type); } int getType() { return _type; } void setType(int arg) { _type = arg; } int payAmount() { switch (getType()) { case ENGINEER: return _monthlySalary; case SALESMAN: return _monthlySalary + _commission; case MANAGER: return _monthlySalary + _bonus; default: throw new RuntimeException("Incorrect Employee"); } } ~~~ 現在,我需要聲明一個state class 。我把它聲明為一個抽象類(abstract class),并提供一個抽象函數(abstract method)。用以返回type code : ~~~ abstract class EmployeeType { abstract int getTypeCode(); } ~~~ 現在,我可以開始創造subclass 了: ~~~ class Engineer extends EmployeeType { int getTypeCode () { return Employee.ENGINEER; } } class Manager extends EmployeeType { int getTypeCode () { return Employee.MANAGER; } } class Salesman extends EmployeeType { int getTypeCode () { return Employee.SALESMAN; } } ~~~ 現在進行一次編譯。前面所做的修改實在太平淡了,即使對我來說也太簡單。現在,我要修改type code 訪問函數(accessors),實實在在地把這些subclasses 和Employee class 聯系起來: ~~~ Employee (int type) { setType (type); } int getType() { return _type; } void setType(int arg) { _type = arg; } int payAmount() { switch (getType()) { case ENGINEER: return _monthlySalary; case SALESMAN: return _monthlySalary + _commission; case MANAGER: return _monthlySalary + _bonus; default: throw new RuntimeException("Incorrect Employee"); } } ~~~ 這意味我將在這里擁有一個switch 語句。完成重構之后,這將是代碼中惟一的switch 語句,并且只在對象型別發生改變時才會被執行。我也可以運用Replace Constructor with Factory Method 針對不同的case 子句建立相應的factory method 。我還可以立刻再使用Replace Conditional with Polymorphism,從而將其他的case 子句完全消除。 最后,我喜歡將所有關于type code 和subclass 的知識都移到新的class ,并以此結束Replace Type Code with State/Strategy 首先我把type code 的定義拷貝到EmployeeType class 去,在其中建立一個factory method 以生成適當的 EmployeeType 對象,并調整Employee class 中為type code 賦值的函數: ~~~ class Employee... void setType(int arg) { _type = EmployeeType.newType(arg); } class EmployeeType... static EmployeeType newType(int code) { switch (code) { case ENGINEER: return new Engineer(); case SALESMAN: return new Salesman(); case MANAGER: return new Manager(); default: throw new IllegalArgumentException("Incorrect Employee Code"); } } static final int ENGINEER = 0; static final int SALESMAN = 1; static final int MANAGER = 2; ~~~ 然后,我刪掉Employee 中的type code 定義,代之以一個「指向(代表、指涉)Employee 對象」的reference: ~~~ class Employee... int payAmount() { switch (getType()) { case EmployeeType.ENGINEER: return _monthlySalary; case EmployeeType.SALESMAN: return _monthlySalary + _commission; case EmployeeType.MANAGER: return _monthlySalary + _bonus; default: throw new RuntimeException("Incorrect Employee"); } } ~~~ 現在,萬事俱備,我可以運用Replace Conditional with Polymorphism 來處理payAmount 函數了。
                  <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>

                              哎呀哎呀视频在线观看