ivaneeo's blog

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

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

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

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

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

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

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

          class Customer ...
              void addOrder(Order arg) {
                 arg.setCustomer(this);
              }
          如果一份訂單也可以對應多個客戶,那么你所面臨的就是一個[多對多]情況,重構后的函數可能是下面這樣:
          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) 評論(0)  編輯  收藏 所屬分類: refactoring-從地獄中重生
          主站蜘蛛池模板: 保定市| 蓬溪县| 新营市| 南靖县| 唐海县| 新龙县| 黄浦区| 田阳县| 顺平县| 东丰县| 南召县| 台江县| 深水埗区| 滕州市| 洛宁县| 博湖县| 庆阳市| 棋牌| 连山| 德令哈市| 黄山市| 和林格尔县| 中卫市| 仪陇县| 金寨县| 东宁县| 河间市| 筠连县| 连城县| 军事| 合山市| 嘉定区| 紫阳县| 内黄县| 塘沽区| 临邑县| 天水市| 耒阳市| 丰宁| 集安市| 章丘市|