ivaneeo's blog

          自由的力量,自由的生活。

            BlogJava :: 首頁 :: 聯系 :: 聚合  :: 管理
            669 Posts :: 0 Stories :: 64 Comments :: 0 Trackbacks
          讓我們從一個簡單的Person class開始:
          class Person...
              public String getName() {
                 return _name;
              }
              public String getTelephoneNumber() {
                 return ("(" + _officeAreaCode + ")" + _officeNumber);
              }
              String getOfficeAreaCode() {
                 return _officeAreaCode;
              }
              void setOfficeAreaCode(String arg) {
                 _officeAreaCode = arg;
              }
              String getOfficeNumber() {
                 return _officeNumber;
              }
              void setOfficeNumber(String arg) {
                 _officeNumber = arg;
              }

              private String _name;
              private String _officeAreaCode;
              private String _officeNumber;

          在這個例子,我可以將[與電話號碼相關]的行為分離到一個獨立class中。首先我要定義一個TelephoneNumber class來表示[電話號碼]這個概念:
          class TelephoneNumber {
          }
          易如反掌!然后,我要建立從Person到TelephoneNumber的連接:
          class Person...
              private TelephoneNumber _officeTelephone = new TelephoneNumber();
          現在,我運用Move Field(146)移動一個值域:
          class TelephoneNumber {
              String getAreaCode() {
                 return _areaCode;
              }
              void setAreaCode(String arg) {
                 _areaCode = arg;
              }
              private String _areaCode;
          }

          class Person...
              public String getTelephoneNumber() {
                 return ("(" + getOfficeAreaCode() + ")" + _officeNumber);
              }
              String getOfficeAreaCode() {
                 return _officeTelephone.getAreaCode();
              }
              void setOfficeAreaCode(String arg) {
                 _officeTelephone.setAreaCode(arg);
              }

          然后我可以移動其他值域,并運用Move Method(142)將相關函數移動到TelephoneNumber class中:
          class Person...
              public String getName() {
                 return _name;
              }
              public String getTelephoneNumber() {
                 return _officeTelephone.getTelephoneNumber();
              }
              TelephoneNumber getOfficeTelephone() {
                 return _officeTelephone;
              }

              private String _name;
              private TelephoneNumber _officeTelephone = new TelephoneNumber();


          class TelephoneNumber...
              public String getTelephoneNumber() {
                 return ("(" + _areaCode + ")" + _number);
              String getAreaCode() {
                 return _areaCode;
              }
              void setAreaCode(String arg) {
                 _areaCode = arg;
              }
              String getNumber() {
                 return _number;
              }
              void setNumber(String arg) {
                 _number = arg;
              }
              private String _number;
              private String _areaCode;


          下一步要做的決定是:要不要對客戶揭示這個新class?我可以將Person中[與電話號碼相關]的函數委托(delegating)至 TelephoneNumber,從而完全隱藏這個新class;也可以直接將對用戶曝光。我還可以將它暴露給部分用戶(位于同一個package中的用 戶),而不暴露給其他用戶。

          如果我選擇暴露新class嗎,我就需要考慮別名(aliasing)帶來的危險。如果我暴露了TelephoneNumber,而有個用戶修改了對象中的_areaCode值域值,我又怎么能知道呢?而且,做出修改的可能不是直接用戶,而是用戶的用戶的用戶。


          面對這個問題,我有下列數種選擇:
          1.允許任何對象修改TelephoneNumber對象的任何部分。這就使得TelephoneNumber對象成為引用對象(reference object),對于我應該考慮使用Change Value to Reference(179)。這種情況下,Person應該是TelephoneNumber的訪問點。
          2.不許任何人[不通過Person對象就修改TelephoneNumber對象]。為了達到目的,我可以將TelephoneNumber設為不可修改的(immutable),或為它提供一個不可修改的接口(immutable interface)。
          3.另一個辦法是:先復制一個TelephoneNumber對象,然后將復制得到的新對象傳遞給用戶。但這可能會造成一定程度的迷惑,因為人們會認為他們可以修改TelephoneNumber對象值。此外,如果同一個TelephoneNumber對象被傳遞給多個用戶,也可能在用戶之間造成別名(aliasing)問題。

          Extract Class(149)是改善并發(concurrent)程序的一種常用技術,因為它使你可以提煉后的兩個classes分別加鎖(locks)。
          posted on 2005-08-30 16:33 ivaneeo 閱讀(213) 評論(0)  編輯  收藏 所屬分類: refactoring-從地獄中重生
          主站蜘蛛池模板: 滁州市| 芷江| 射阳县| 新津县| 塔河县| 阿拉尔市| 五华县| 鸡西市| 南乐县| 滦南县| 镇江市| 乐至县| 二连浩特市| 外汇| 伊春市| 玉环县| 宁化县| 义乌市| 余干县| 营口市| 石楼县| 台湾省| 山丹县| 泸州市| 进贤县| 石嘴山市| 西充县| 靖宇县| 离岛区| 垦利县| 古浪县| 克山县| 平安县| 扎兰屯市| 襄汾县| 木兰县| 郸城县| 犍为县| 金秀| 鞍山市| 太仓市|