ivaneeo's blog

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

            BlogJava :: 首頁 :: 聯(lián)系 :: 聚合  :: 管理
            669 Posts :: 0 Stories :: 64 Comments :: 0 Trackbacks
          范例(Examples)
          下面是一段簡單程序,其中有兩個(gè)classes:表示[定單]的Order和表示[客戶]的CustomerOrder引用了CustomerCustomer則并沒有引用Order
          class Order...
              Customer getCustomer() {
                 return _customer;
              }
              void setCustomer(Customer arg) {
                 _Customer = arg;
              }
              Customer _customer;   //這是一個(gè)“Order”to “Customer”的連接

          首先,我要為Customer添加一個(gè)值域。由于一個(gè)客戶可以擁有多份定單,所以這個(gè)新增值域應(yīng)該是個(gè)群集(collection)。我不希望同一份定單在同一個(gè)群集中出現(xiàn)一次以上,所以這里適合使用set:
          class Customer {
              private Set _orders = new HashSet();
          現(xiàn)在,我需要決定由哪一個(gè)class負(fù)責(zé)控制關(guān)聯(lián)性(association)。我比較喜歡讓單一class來操控,因?yàn)檫@樣我就可以將所有[關(guān)聯(lián)處理邏輯]集中安置于一地。我將按照下列步驟做出這一決定:
          1. 如果兩者都是reference objects,而其間的關(guān)聯(lián)是[一對(duì)多]關(guān)系,那么就由[擁有單一reference]的那一方承擔(dān)[控制者]角色。以本例而言,如果一個(gè)客戶可擁有多份定單,那么就由Order class(定單)來控制關(guān)聯(lián)性。
          2. 如果某個(gè)對(duì)象是另一個(gè)對(duì)象的組成(component),那么由后者負(fù)責(zé)控制關(guān)聯(lián)性。
          3. 如果兩者都是reference objects,而其間的關(guān)聯(lián)是[多對(duì)多]關(guān)系,那么隨便其中哪個(gè)對(duì)象來控制關(guān)聯(lián)性,都無所謂。
          本例之中由于Order負(fù)責(zé)控制關(guān)聯(lián)性,所以我必須為Customer添加一個(gè)賦值函數(shù),讓Order可以直接訪問_orders(訂單)集群。Order的修改函數(shù)(modifier)將使用這個(gè)輔助函數(shù)對(duì)指針兩端對(duì)象進(jìn)行同步控制。我將這個(gè)賦值函數(shù)命名為friendOrders(),表示這個(gè)函數(shù)只能在這種特殊情況下使用。此外,如果OrderCustomer位在同一個(gè)package內(nèi),我還會(huì)將friendOrders()聲明為[package  可見度],使其可見程度降至最低。

          但如果這兩個(gè)classes不在同一個(gè)package內(nèi),我就只好把friendOrders()聲明為public了。
          class Customer...
              Set friendOrders() {
                 return _orders;
              }
          現(xiàn)在。我要改變修改函數(shù)(modifier),令它同時(shí)更新反向指針:

          class Order...
              void setCustomer(Custoemr arg) ...
                 if(_customer != null) _customer.friendOrders().remove(this);
                 _customer = arg;
                 if(_customer != null) _customer.friendOrders().add(this);
              }

          classes之間的關(guān)聯(lián)性是各式各樣的,因此修改函數(shù)(modifier)的代碼也會(huì)隨之有所差異。如果_customer的值不可能是null,我可 以拿掉上述的第一個(gè)null檢查,但仍然需要檢查引數(shù)(argument)是否是null。不過,基本形式總是相同的:先讓對(duì)方刪除[指向你]的指針,再 將你的指針指向一個(gè)新對(duì)象,最后讓那個(gè)新對(duì)象把它的指針指向你。

          如果你希望在Customer中也能修改連接(link),就讓它調(diào)用控制函數(shù):

          class Customer ...
              void addOrder(Order arg) {
                 arg.setCustomer(this);
              }
          如果一份訂單也可以對(duì)應(yīng)多個(gè)客戶,那么你所面臨的就是一個(gè)[多對(duì)多]情況,重構(gòu)后的函數(shù)可能是下面這樣:
          class Order ...   //controlling methods
              void addCustomer(Customer arg) {
                 arg.friendOrders().add(this);
                 _customers.add(arg);
              }
              void removeCustomer(Customer arg) {
                 arg.friendOrders().remove(this);
                 _customers.remove(arg);
              }
          class Customer ...
              void addOrder(Order arg) {
                 arg.addCustomer(this);
              }
              void removeOrder(Order arg) {
                 arg.removeCustomer(this);
              }
          posted on 2005-09-13 15:55 ivaneeo 閱讀(325) 評(píng)論(0)  編輯  收藏 所屬分類: refactoring-從地獄中重生
          主站蜘蛛池模板: 公主岭市| 错那县| 盐源县| 敖汉旗| 凤凰县| 霍山县| 璧山县| 泾阳县| 曲松县| 南平市| 鄢陵县| 涞水县| 满城县| 密云县| 湟源县| 金堂县| 武陟县| 安泽县| 晋州市| 大竹县| 南乐县| 新闻| 汉中市| 巨野县| 班玛县| 泗水县| 皮山县| 上栗县| 沁水县| 九龙县| 石林| 南昌县| 河池市| 花莲县| 明光市| 方城县| 沅江市| 怀化市| 荔波县| 彝良县| 普安县|