如何避免類之間的循環相依性

來源:互聯網
上載者:User

標籤:

      最近在看《Java應用架構設計 模組化模式與OSGi》,深有感觸,在此做些總結。(電子版可以在Java1234.com上下載到)

      在使用Java開發中,各種依賴不可避免。比如類之間的繼承,jar包之間的相互依賴。依賴在某種程度上不可避免,但是過多的依賴勢必會增加系統的複雜性,使代碼難以閱讀,從而成為團隊開發的阻礙。循環相依性尤其糟糕。

     循環相依性存在與多種實體之間,尤其是類、包、模組之間。當兩個類相互引用時,就會出現循環相依性。下面摘抄書中的一個例子。

     1.1所示,有Customer和Bill兩個類。在本例中,Customer有一個Bill的執行個體列表,而Bill執行個體也引用Customer來計算折扣總額。這也成為雙向關聯(bidirectional association)。對於維護和測試,這將是一個將是一個問題,因為在不引用另一個類的情況下,你不能單獨的對其中一個類做任何事情。

 

圖1.1 類之間的循環相依性

      代碼清單1.1展示了Customer類,代碼清單1.2展示了Bill類。(為了簡化,每個類的特定部分進行了省略。)在這裡清楚展示了循環相依性。  

package com.scott.cust;import java.util.*;import java.math.BigDecimal;import com.scott.bill.*;public class Customer {   private List<Bill> bills;   //特定Customer的折扣根據訂單數目計算   public BigDecimal getDiscountAmount() {       if (bills.size() > 5) {           return new BigDecimal(0.1);       } else {           return new BigDecimal(0.03);       }   }      public void createBill() {       Bill bill = new Bill(this);       if (bills == null) {           bills = new ArrayList<Bill>();       }       bills.add(bill);   }}
代碼清單1.1 Customer
package com.scott.bill;import com.scott.cust.*;import java.math.BigDecimal;public class Bill {   private Customer customer;      public Bill(Customer customer) {        this.customer = customer;      }      public BigDecimal pay() {       BigDecimal discount =  new BigDecimal(1),subtract(            this.customer.getDiscountAmount()).setScale(2,            BigDecimal.ROUND_HALF_UP);       //確認折扣和應付款代碼省略       return paidAmount;  }}
代碼清單1.2 Bill

      可以有多種方式打破循環相依性(筆者目前所知就是引入抽象),其中之一就是引入抽象,1.2所示。現在,藉助mock的DiscountCaculator,Bill就可以容易的進行(單元)測試了。當然,測試Customer依舊需要Bill的參與。單著不是迴圈的問題了,這裡暫時不做討論。很顯然,引入DiscountCalculator打破了Customer和Bill類之間依賴。但是,它能打破所有的循環相依性嗎,包括可能存在與模組之間的?

圖1.2 打破迴圈   

代碼清單1.3展示了修改後的Customer類,它實現了DiscountCalculator介面,改介面如程式清單4.4所示。

package com.scott.cust;import java.util.*;import java.math.BigDecimal;import com.scott.bill.*;public class Customer implements DiscountCalculator {   private List<Bill> bills;   //特定Customer的折扣根據訂單數目計算   public BigDecimal getDiscountAmount() {       if (bills.size() > 5) {           return new BigDecimal(0.1);       } else {           return new BigDecimal(0.03);       }   }      public List<Bill> getBills() {       return this.bills;   }   public void createBill() {       Bill bill = new Bill(this);       if (bills == null) {           bills = new ArrayList<Bill>();       }       bills.add(bill);   }}
代碼清單1.3 修改後的Customer
package com.scott.bill;import java.math.BigDecimal;public interface DiscountCalculator {    public BigDecimal getDisCountAmount();}
代碼清單1.4 DiscountCalculator

 

如何避免類之間的循環相依性

聯繫我們

該頁面正文內容均來源於網絡整理,並不代表阿里雲官方的觀點,該頁面所提到的產品和服務也與阿里云無關,如果該頁面內容對您造成了困擾,歡迎寫郵件給我們,收到郵件我們將在5個工作日內處理。

如果您發現本社區中有涉嫌抄襲的內容,歡迎發送郵件至: info-contact@alibabacloud.com 進行舉報並提供相關證據,工作人員會在 5 個工作天內聯絡您,一經查實,本站將立刻刪除涉嫌侵權內容。

A Free Trial That Lets You Build Big!

Start building with 50+ products and up to 12 months usage for Elastic Compute Service

  • Sales Support

    1 on 1 presale consultation

  • After-Sales Support

    24/7 Technical Support 6 Free Tickets per Quarter Faster Response

  • Alibaba Cloud offers highly flexible support services tailored to meet your exact needs.