ivaneeo's blog

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

            BlogJava :: 首頁 :: 聯(lián)系 :: 聚合  :: 管理
            669 Posts :: 0 Stories :: 64 Comments :: 0 Trackbacks

          #

          你有一個reference object(引用對象),很小且不可變(immutable),而且不易管理。

          將它變成一個value object(實值對象)。

          Change Reference to Value.png
          posted @ 2005-09-05 09:47 ivaneeo 閱讀(272) | 評論 (0)編輯 收藏

          在debian中使用sudo必須先添加用戶到sudo中,才可以以root身份執(zhí)行.
          修改sudo列表使用visudo命令.

          添加內(nèi)容

          任何程序不要用sudo執(zhí)行不要密碼
          你的用戶名 ALL=NOPASSWD:ALL

          要密碼的
          你的用戶名 ALL=PASSWD:ALL 密碼為你的用戶名密碼非root的

          如果限制程序用sudo把all換成相應的程序
          只有在普通用戶下用gksu 運行程序時才用root密碼
          因為gksu 默任時root用戶

          posted @ 2005-09-02 14:07 ivaneeo 閱讀(444) | 評論 (0)編輯 收藏

          范例(Examples)
          在Replace Data Value with Object(175)一節(jié)中,我留下了一個重構(gòu)后的程序,本節(jié)范例就從它開始。我們有下列的Customer class:
          class Customer {
              public Customer(String name) {
                 _name = name;
              }

              public String getName() {
                 return _name;
              }
              private final String _name;
          }
          它被以下的order class使用:
          class Order...
              public Order(String customer) {
                 _customer = new Customer(customer);
              }

              public String getCustomer() {
                 return _customer.getName();
              }
             
              public void setCustomer(String arg) {
                 _customer = new Customer(arg);
              }
              private Customer _customer;


          此外,還有一些代碼也會使用Customer對象:
          private static int numberOfOrdersFor(Collection orders, String customer) {
              int result = 0;
              Iterator iter = orders.iterator();
              while(iter.hasNext()) {
                 Order each = (Order)iter.next();
                 if(each.getCustomer().equals(customer)) result ++;
              }
              return result;
          }
          到目前為止,Customer對象還是value object。就算多份定單屬于同一客戶,但每個order對象還是擁有各自的Customer對象。我希望改變這一現(xiàn)狀,使得一旦同一客戶擁有多份不同定單,代表這些定單的所有Order對象就可以共享同一個Customer對象。

          首先我使用Replace Constructor with Factory Method(304)。這樣,我就可以控制Customer對象的創(chuàng)建過程,這在以后會是非常重要的。我在Customer class中定義這個factory method
          class Customer {
              public static Customer create(String name) {
                 return new Customer(name);
              }
          }
          然后我把[對構(gòu)造函數(shù)的調(diào)用]替換成[對factory method的調(diào)用]:
          class Order {
              public Order(String customer) {
                 _customer = Customer.create(customer);
              }
          }
          然后我再把構(gòu)造函數(shù)聲明為private:
          class Customer {
              private Customer(String name) {
                 _name = name;
              }
          }
          現(xiàn)在,我必須決定如何訪問Customer對象。我比較喜歡通過另一個對象(例如Order class中的一個值域)來訪問它。但是本例并沒有這樣一個明顯的值域可用于訪問Customer對象。在這種情況下,我通常會創(chuàng)建一個注冊(登錄)對象,作為訪問點。為了簡化我們的例子,我把Customer對象保存在Customer class的一個static值域中,讓Customer class作為訪問點:
          private static Dictionary _instance = new Hashtable();

          然后我得決定:應該在接到請求時創(chuàng)建新的Customer對象,還是應該預先將它們創(chuàng)建好。這里我選擇后者。在應用程序的啟動代碼(start-up code)中,我先把需要使用的Customer對象加載妥當。這些對象可能來自數(shù)據(jù)庫,也可能來自文件。為求簡單起見,我在代碼中明確生成這些對象。反正以后我總是可以使用Substitute Algorithm(139)來改變它們的創(chuàng)建方式。
          class Customer...
              static void loadCustomers() {
                 new Customer("Lemon Car Hire").store();
                  new Customer("Associated Coffee Machines").store();

                  new Customer("Bilston Gasworks").store();
              }
              private void store() {
                 _instance.put(this.getName(), this);
              }
          現(xiàn)在,我要修改factory method,讓它返回預先創(chuàng)建好的Customer對象:
          public static Customer create(String name) {
              return (Customer)_instance.get(name);
          }
          由于create()總是返回既有的Customer對象,所以我應該使用Rename Method(273)修改這個factory method的名稱,以便強調(diào)(說明)這一點。
          class Customer...
          public static Customer getNamed(String name) {
              return (Customer)_instances.get(name);
          }
          posted @ 2005-09-01 14:16 ivaneeo 閱讀(191) | 評論 (0)編輯 收藏

          作法(Mechanics)
            • 使用Replace Constructor with Factor Method(304)。
            • 編譯,測試。
            • 決定由什么對象負責提供訪問新對象的途徑。
                • ==》可能是個靜態(tài)字典(static dictionary)或一個注冊對象(registry object)
                • ==》你也可以使用多個對象作為新對象的訪問點(access point)。
            • 決定這些reference object應該預先創(chuàng)建好,或是應該動態(tài)創(chuàng)建。
                • ==》如果這些reference object是預先創(chuàng)建好的,而你必須從內(nèi)存中被它們讀取出來,那么就得確保它們在被需要的時候能夠被及時加載。
            • 修改factory method,令它返回reference object。
                • ==》如果對象是預先創(chuàng)建好的,你就需要考慮:萬一有人索求一個其實并不存在的對象,要如何處理錯誤?
                • ==》你可能希望對factory method使用Rename Method(273),使其傳達這樣的信息;它返回的是一個既存對象。
            • 編譯,測試。
          posted @ 2005-09-01 11:13 ivaneeo 閱讀(165) | 評論 (0)編輯 收藏

          動機(Motivation)
          在許多系統(tǒng)中,你都可以對對象做一個有用的分類:reference object和value objects。前者就像[客戶]、[帳戶]這樣的東西,每個對象都代表真實世界中的一個實物,你可以直接以相等操作符(==,用來檢驗同一性, identity)檢查兩個對象是否相等。后者則是像[日期]、[錢]這樣的東西,它們完全由其所含的數(shù)據(jù)值來定義,你并不在意副本的存在;系統(tǒng)中或許存 在成百上千個內(nèi)容為“1/1/2000”的[日期]對象。當然,你也需要知道兩個value objects是否相等,所以你需要覆寫equals()(以及hashCode())。


          要在reference object和value object之間做選擇有時并不容易。有時侯,你會從一個簡單的value object開始,在其中保存少量不可修改的數(shù)據(jù)。而后,你可能會希望給這個對象加入一些可修改數(shù)據(jù),并確保對任何一個對象的修改都能影響到所有引用此一對象的地方。這時候你就需要將這個對象變成一個reference object。
          posted @ 2005-09-01 10:37 ivaneeo 閱讀(180) | 評論 (0)編輯 收藏

          你有一個class,衍生出許多相等實體(equal instances),你希望將它們替換為單一對象。

          將這個value object(實值對象)變成一個reference object(引用對象)。

          Change_Value_to_Reference.png
          posted @ 2005-09-01 10:22 ivaneeo 閱讀(179) | 評論 (0)編輯 收藏

          范例(Examples)
          下面有一個代表[定單]的Order class,其中以一個字符串記錄定單客戶。現(xiàn)在,我希望改為以一個對象來表示客戶信息,這樣我就有充裕的彈性保存客戶地址、信用等級等等信息,也得以安置這些信息的操作行為。Order class最初如下:
          class Order...
              public Order(String customer) {
                 _customer = cusomer;
              }

              public String getCustomer() {
                 return _customer;
              }
             
              public void setCustomer(String arg) {
                 _customer = arg;
              }
              private String _customer;

          Order class的客戶代碼可能像下面這樣:
          private static int numberOfOrdersFor(Collection orders, String customer) {
              int result = 0;
              Iterator iter = orders.iterator();
              while(iter.hasNext()) {
                 Order each = (Order)iter.next();
                 if(each.getCustomer().equals(customer)) result ++;
              }
              return result;
          }

          首先,我要新建一個Customer class來表示[客戶]概念。然后在這個class中建立一個final值域,用以保存一個字符串,這是Order class目前所使用的。我將這個新值域命名為_name,因為這個字符串的用途就是記錄客戶名稱。此外我還要為這個字符串加上取值函數(shù)(getter) 和構(gòu)造函數(shù)(constructor)。
          class Customer {
              public Customer(String name) {
                 _name = name;
              }

              public String getName() {
                 return _name;
              }
              private final String _name;
          }

          現(xiàn)在,我要將Order中的_customer值域的型別修改為Customer;并修改所有引用此一值域的函數(shù),讓它們恰當?shù)馗亩肅ustomer實體。其中取值函數(shù)和構(gòu)造函數(shù)的修改都很簡單;至于設值函數(shù)(setter),我讓它創(chuàng)建一份Customer實體。
          class Order...
              public Order(String customer) {
                 _customer = new Customer(customer);
              }

              public String getCustomer() {
                 return _customer.getName();
              }
             
              public void setCustomer(String arg) {
                 _customer = new Customer(arg);
              }
              private Customer _customer;

          設值函數(shù)需要創(chuàng)建一份Customer實體,這是因為以前的字符串是個實值對象(value object),所以現(xiàn)在的Customer對象也應該是個實值對象。這也就意味每個Order對象都包含自己的一個Customer對象。注意這樣一條 規(guī)則:實值對象應該是不可修改內(nèi)容的--這便可以避免一些討厭的[別名](aliasing)錯誤。日后或許我會想讓Customer對象成為引用對象(reference object),但那是另一項重構(gòu)手法的責任。現(xiàn)在我可以編譯并測試了。

          我需要觀察Order class中的_customer值域的操作函數(shù),并作出一些修改,使它更好地反映出修改后的新形勢。對于取值函數(shù),我會用Rename Method(273)改變其名稱,讓它更清晰地表示,它所返回的是消費者名稱,而不是個Customer對象。
          public String getCustomerName() {
              return _customer.getName();
          }

          至于構(gòu)造函數(shù)和設值函數(shù),我就不必修改其簽名(signature)了,但參數(shù)名稱得改:
          public Order(String customerName) {
              _customer = new Customer(customerName);
          }
          public void setCustomer(String customerName) {
              _customer = new Customer(customerName);
          }

          本次 重構(gòu)到此為止。但是,這個案例和其他很多案例一樣,還需要一個后續(xù)步驟。如果想在Customer中加入信用等級、地址之類的其他信息,現(xiàn)在還做不到,因為目前的Customer還是被作為實值對象(value object)來對待,每個Order對象都擁有自己的Customer對象。為了給Customer class加上信用等級、地址之類的屬性,我必須運用Change Value to Reference(179),這么一來屬于同一客戶的所有Order對象就可以共享同一個Customer對象。馬上你就可以看到這個例子。
          posted @ 2005-09-01 09:59 ivaneeo 閱讀(205) | 評論 (0)編輯 收藏

          作法(Mechanics)
            • 為[待替換數(shù)值]新建一個class,在其中聲明一個final值域,其型別和source class中的[待替換數(shù)值]型別一樣。然后在新class中加入這個值域的取值函數(shù)(getter),再加上一個[接受此值域為參數(shù)]的構(gòu)造函數(shù)。
            • 編譯。
            • 將source class中的[待替換數(shù)值值域]的型別改為上述的新建class。
            • 修改source class中此一值域的取值函數(shù)(getter),令它調(diào)用新建class的取值函數(shù)。
            • 如果source class構(gòu)造函數(shù)中提及這個[待替換值域](多半是賦值動作),我們就修改構(gòu)造函數(shù),令它改用新class的構(gòu)造函數(shù)來對值域進行賦值動作。
            • 修改source class中[待替換值域]的設值函數(shù)(setter),令它為新class創(chuàng)建一個實體。
            • 編譯,測試。
            • 現(xiàn)在,你有可能需要對新class使用Change Value to Reference(179)。
          posted @ 2005-09-01 09:28 ivaneeo 閱讀(152) | 評論 (0)編輯 收藏

          動機(Motivation)
          一開始你可能會用一個字符串來表示[電話號碼]概念,但是隨后你就會發(fā)現(xiàn),電話號碼需要[格式化]、[抽取區(qū)號]之類的特殊行為。當這些臭味開始出現(xiàn),你就應該將數(shù)據(jù)值(data value)變成對象(object)。
          posted @ 2005-09-01 09:17 ivaneeo 閱讀(196) | 評論 (0)編輯 收藏

          你有一筆數(shù)據(jù)項(data item),需要額外的數(shù)據(jù)和行為。

          將這筆數(shù)據(jù)項變成一個對象。

          Replace_Data_Value_with_Object.png


          posted @ 2005-08-31 16:32 ivaneeo 閱讀(171) | 評論 (0)編輯 收藏

          僅列出標題
          共67頁: First 上一頁 41 42 43 44 45 46 47 48 49 下一頁 Last 
          主站蜘蛛池模板: 嘉荫县| 雅江县| 德令哈市| 清苑县| 昌乐县| 红桥区| 马山县| 塔河县| 庄浪县| 余干县| 贵港市| 南川市| 滦南县| 成武县| 巨野县| 阳谷县| 宜都市| 奉节县| 武汉市| 石首市| 沅江市| 沈阳市| 和林格尔县| 成安县| 巴中市| 梅河口市| 家居| 济宁市| 睢宁县| 云阳县| 景宁| 湖北省| 红原县| 蛟河市| 梁山县| 松潘县| 扎兰屯市| 平邑县| 随州市| 丹棱县| 北川|