Is it a good idea to protect the fields?

Code example:

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; 

The TBar class is able to directly change the value of FList, but this is not strictly necessary, since it only needs to call its methods / use its properties.

Should I make FList private and use the property to access it from TBar?

How do you deal with such cases? Are there any performance considerations?

+7
source share
1 answer

Although I agree that you can start with the least privileges and, if necessary, move things in visibility, it is only because it ends up creating a proper object-oriented design, without making you think too hard about whether the class member is real to be disclosed.

You must encapsulate and hide as much complexity as possible inside the object so that the external interface is as minimal as possible. One way to achieve this is to only add or expand properties as needed.

If you do not need external access to a specific member of the class, it is probably just an implementation artifact and is not suitable for actual use in the class’s business. Therefore, complexity must be hidden.

In this case, since TBar is inherited from TFoo, Protected is a valid level of visibility since it is reserved for inherited classes. Also, since TBar inherits from TFoo, you might think that it should have some additional privileges for TFoo's internal work, because it is, after all, its child class. Why should we attribute TBar to the same low access level as other classes?

The answer depends on whether FList is an actual member of the TFoo class, since we are considering what the TFoo model is, or is it just an implementation detail. Also, what is the required access level? Are we just accessing it or changing the implementation?

I assume that you do not need access to FList, and you do not change the implementation, and in this case, even if both classes were in the same block, I will still do FList Private over Protected.

If you just accessed a class member from descendant classes within the same unit, I would still leave it private.

However, if the FList was something that you need to override in TBar (maybe not, because it is not a method), or were designed as something that the inherited classes should or will be overridden, regardless of whether it was in the same unit or not, you will want to make it protected.

You will also need to increase visibility to protected if you need to access the FList from child classes outside the same block.

+3
source

All Articles