小酌重構系列 24 封裝集合

2022-01-15 22:35:45 字數 2423 閱讀 2323

當方法返回型別或屬性型別為集合時,有些開發者會千篇一律地使用ilist集合。然而ilist具有集合的所有操作,這意味著呼叫者不僅可以讀取集合資訊,還能夠修改集合。業務需求本來只是為呼叫者提供乙個可讀的集合,例如資料的查詢和展示,但當方法返回ilist時,無疑隱式地開放了集合可寫的許可權。此時,我們無法阻止呼叫者篡改集合元素。

注意:將屬性設定為ilist型別時,即使宣告為唯讀的,我們仍然無法避免集合元素的篡改。

例如public ilistpeople,people屬性是乙個ilist集合,它雖然是唯讀的,但是people集合裡面的元素可以被修改。

這種情況下,我們應該使用ienumerable來代替ilist。

ilist和ienumerable都可以遍歷集合的元素,ilist擁有集合的所有操作方法,包括集合元素的增加、修改和刪除。

而ienumerable則只有乙個getenumerator方法(擴充套件方法除外),它返回乙個可用於迴圈訪問集合的ienumerator物件。

下面這段**定義了兩個類:order和orderline。

當呼叫者在取到order例項時,仍然可以通過ilist的add()或remove()方法修改orderlines集合。

假設呼叫者篡改了orderlines中的元素,並且通過另外的方法回傳了order例項,則可能會產生一些bug。

隱藏**

/// /// 訂單

///

public class order

}public void addorderline(orderline orderline)

public void removeorderline(orderline orderline)

}/// /// 訂單明細

///

public class orderline

}

重構後,不僅orderlines集合是唯讀的,而且也只能通過addorderline()和removeorderline()方法來增加或刪除訂單明細。

隱藏**

/// /// 訂單

///

public class order

/// /// 訂單明細集合是唯讀的,只能通過addorderline()和removeorderline()來增加或刪除訂單明細

///

public ienumerableorderlines

}public double ordertotal

}public void addorderline(orderline orderline)

public void removeorderline(orderline orderline)

}/// /// 訂單明細

///

public class orderline

}

注意:上述**有一些瑕疵,orderline類沒有重寫object類的equals()、gethashcode()方法。

這行**orderline = _orderlines.find(item => item == orderline)會使得orderline每次都是null。

較為完整的orderline如下:

隱藏**

public class orderline

public int orderid

public double total

/// /// 重寫equals方法

///

public override bool equals(object obj)

return id.equals(other.id);

}/// /// 重寫gethashcode方法

///

///

public override int gethashcode()

/// /// 是否為瞬時物件

///

///

public virtual bool istransient()

/// /// 提供==操作符,可用於物件比較

///

public static bool operator ==(orderline left, orderline right)

return left.equals(right);

}/// /// 提供!=操作用,可用於物件比較

///

public static bool operator !=(orderline left, orderline right)

}

當集合作為返回引數時,應使用適合業務需求的集合型別,不宜提供過多的集合操作給呼叫者。

小酌重構系列目錄彙總

關注keepfool

3 11 封裝集合

封裝集合 範例 1 include 2 define max student count 2034 class student512 13int getid const 1417 void setid int nid 1821 qstring getname const 2225 void setn...

31 天重構學習筆記1 封裝集合

摘要 由於最近在做重構的專案,所以對重構又重新進行了一遍學習和整理,對31天重構最早接觸是在2009年10月份,由於當時沒有訂閱 sean chambers的blog,所以是在國外的社群上閒逛的時候鏈結過去的。記得當時一口氣看完了整個系列並沒有多少感覺,因為這些基本上專案都 在使用,只是我們沒有專門...

物件導向系列二(封裝)

僅僅須要最簡單的操作就能實現一系列複雜的功能。是做乙個個技術攻克的目的。一台精密儀器,一架家用電器,乙個小公尺手機,這些可能我們都在用,或者用過。它們的內部都無比的複雜。使用了各種各樣的配件,運用了極多的原理和知識。我們在使用的時候都具有同樣的感受 簡單 方便 太好了!面對原本複雜的東西,我們卻能通...