2012-01-17 58 views
7

代碼示例:將字段保護起來是不是一個好主意?

unit Foo; 

    TFoo = class 
    protected 
    FList: TList; // Lifetime is managed by constructor and destructor 
    public 
    property List: TList read FList; 
    constructor Create; 
    destructor Destroy; override; 
    end; 

unit Bar; 

    TBar = class(TFoo) 
    procedure MyMethod; 
    end; 

procedure TBar.MyMethod; 
begin 
    // Access of FList goes here 
end; 

的TBAR類是能夠直接修改FLIST的價值,但是這不是絕對必要的,因爲它只有調用它的方法/使用其屬性。

我應該讓FList私密並使用該屬性從TBar訪問它嗎?

你如何處理這種情況?是否有任何性能方面的考慮?

+0

這有點與http://stackoverflow.com/questions/8281582/using-properties-instead-of-fields-in-class-methods-of-the-same-unit-is-a-bad-公關,但更具體。 – 2012-01-17 11:56:10

+1

*無數次*如果東西不是私人的,我會碰到一些能夠緩解我工作的東西。我相信很多其他人也是這樣做的,因爲我已經看到開發人員完全忽略* private *並且使用* protected *作爲最嚴格的範圍。 +1 – 2012-01-17 12:10:59

+2

@Sertac當你無法控制其他代碼時,這通常是一個問題。當你完全控制所有的代碼時,你可以使用'private'甚至'strict private',當它變得太嚴格時,你可以根據需要放寬限制。 – 2012-01-17 12:18:23

回答

3

雖然我同意你可以從最小特權開始,並在需要時將事物向上移動,但這只是因爲它最終會產生適當的面向對象的設計,而不必過多地考慮類成員是否是應該暴露的真正的商業功能。

您應該在對象中封裝並儘可能多地隱藏複雜性,以便外部接口儘可能簡化。完成此操作的一種方法是隻根據需要添加或顯示屬性。

如果您不需要外部訪問某個類的特定成員,那可能只是一個實現工件,並且不符合該類的實際業務用途。因此,應該隱藏它的複雜性。

在這種情況下,由於TBar繼承自TFoo,因此Protected是有效的可見性級別,因爲它是爲繼承類保留的。另外,因爲TBar是從TFoo繼承的,也許你認爲它應該對TFoo的內部工作有一些額外的特權,因爲它畢竟是它的子類。爲什麼我們應該將TBar與其他類一樣具有相同的低訪問級別?

答案取決於FList是否是TFoo的實際類成員,因爲我們考慮TFoo模型代表的是什麼,或者它只是一個實現細節。另外,需要的訪問級別是多少?我們是簡單地訪問它,還是我們正在改變實現?

我猜你不需要訪問FList,並且你沒有改變實現,在這種情況下,即使兩個類在同一個單元中,我仍然會使FList專用於受保護的。

如果你只是從同一單元內的後代類訪問類成員,我仍然保持私有。但是,如果FList是你需要在TBar中重寫的東西(可能不是,因爲它不是方法),或者被設計爲繼承類應該或將會覆蓋的東西,不管它是否在同一個單元中,那麼你會想讓它受到保護。

如果您需要從同一單元之外的後代類訪問FList,還需要將可見性提高到Protected。

+1

同樣,無論您是否將TFoo的字段設置爲私有或受保護,如果TBar被聲明在同一個單元中,它們仍然可以從TBar中看到。爲了避免這種情況,在最近的delphi版本中使用「strict private」。在沒有「嚴格專用」的Delphi 2007中,將TBar移到它自己的單元中,以防止ObjectPascal/Delphi在其OOP設計中內置的「同一單元中類的隱式朋友狀態」。 – 2012-01-17 14:24:45

+0

如果'FList'是私人的(並且不暴露於公共範圍)並且'TFoo'和'TBar'在不同的文件中,您是否會使用受保護的屬性從'TBar'訪問它? – 2012-01-17 14:26:10

+0

@Jens,是的。使用受保護的繼承類可以從其他單元訪問它,但仍然從其他類隱藏它。如果它在同一個單元中,如果我只是簡單地訪問它,我很可能會將其保留爲私有的,但如果我正在更改實現,則會將其公開。 – 2012-01-17 14:36:03

相關問題