Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Is it a good idea to make fields protected?

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 modify the value of FList, but that's not strictly necessary, because it only has to call its methods / use its properties.

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

How do you handle cases like that? Are there any performance considerations as well?

like image 673
Jens Mühlenhoff Avatar asked Jan 17 '12 11:01

Jens Mühlenhoff


1 Answers

While I agree that you could start out with the least privilege, and move things up in visibility when needed, it's only because it ends up producing proper object oriented design without having to think too hard about whether the class member is a real business function that should be exposed.

You should encapsulate and hide as much of the complexity as possible within an object so that the external interface is as minimalist as possible. One way to accomplish this is to only add or expose properties as you need them.

If you don't need external access to a particular member of the class, it's probably simply an implementation artifact, and doesn't fit the actual business use of the class. It's complexity should, therefore, be hidden.

In this case, because TBar inherits from TFoo, Protected is a valid visibility level, since it's reserved for inherited classes. Also, because TBar is inherited from TFoo, maybe you're thinking it should have some extra privileges to the inner workings of TFoo because it is, after all, its child class. Why should we relegate TBar to have the same low level of access as other classes?

The answer depends on whether FList is an actual class member of TFoo, as we consider what the TFoo model represents, or whether it's simply an implementation detail. Also, what is the level of access required? Are we simply accessing it, or are we changing the implementation?

I'm guessing that you don't need access to FList, and you're not changing the implementation, in which case, even if the two classes were in the same unit, I would still make FList Private over Protected.

If you were merely accessing the class member from descendant classes within the same unit, I would still keep it private.

However, if FList were something that you need to override in TBar (probably not, since it's not a method), or were designed as something that inherited classes should or would override, whether it was in the same unit or not, then you would want to make it Protected.

You would also need to raise the visibility to Protected if you needed to access FList from descendant classes outside of the same unit.

like image 191
Marcus Adams Avatar answered Oct 10 '22 09:10

Marcus Adams