【问题标题】:Is it a good idea to make fields protected?保护字段是个好主意吗?
【发布时间】:2012-01-17 11:51:48
【问题描述】:

代码示例:

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 访问它吗?

您如何处理此类案件?是否还有任何性能方面的考虑?

【问题讨论】:

  • 这与stackoverflow.com/questions/8281582/…有些相关,但更具体。
  • 无数次如果不是私密的,我已经找到了一些可以减轻我工作负担的东西。我相信许多其他人也这样做了,因为我见过完全忽略 private 并使用 protected 作为最严格范围的开发人员。 +1
  • @Sertac 当您无法控制其他代码时,这通常是一个问题。当您完全控制所有代码时,您可以使用private 甚至strict private,当它变得过于严格时,您可以根据需要放宽限制。
  • 无性能考虑。我个人倾向于使用最严格的visibility specifier 可用以允许您的代码工作。这个建议是当您完全控制使用该类的所有代码时。如果您正在编写组件或库,那么您必须考虑到不是您的用户。那是一个不同的游戏,我不提供任何建议。
  • @David - 我认为在需要逐个访问代码片段之前,能够仔细构建代码非常重要。也有可能有人无法控制它,有时可能不得不使用它。

标签: delphi oop delphi-2007


【解决方案1】:

虽然我同意您可以从最低权限开始,并在需要时提高可见性,但这只是因为它最终产生了正确的面向对象设计,而无需过多考虑类成员是否是真实的应该暴露的业务功能。

您应该在对象中封装和隐藏尽可能多的复杂性,以使外部接口尽可能简约。实现此目的的一种方法是仅在需要时添加或公开属性。

如果您不需要对类的特定成员进行外部访问,它可能只是一个实现工件,不适合该类的实际业务用途。因此,它的复杂性应该被隐藏起来。

在这种情况下,由于 TBar 继承自 TFoo,因此 Protected 是一个有效的可见性级别,因为它是为继承的类保留的。另外,因为 TBar 是从 TFoo 继承的,所以您可能认为它应该对 TFoo 的内部工作具有一些额外的特权,因为它毕竟是它的子类。为什么我们要将 TBar 降级为与其他类一样低级别的访问权限?

答案取决于 FList 是否是 TFoo 的实际类成员,因为我们考虑 TFoo 模型代表什么,或者它是否只是一个实现细节。另外,需要什么级别的访问权限?我们只是在访问它,还是在更改实现?

我猜您不需要访问 FList,并且您没有更改实现,在这种情况下,即使这两个类在同一个单元中,我仍然会将 FList 设为私有而不是受保护。

如果您只是从同一单元内的后代类中访问类成员,我仍然会将其保密。

但是,如果 FList 是您需要在 TBar 中覆盖的东西(可能不是,因为它不是方法),或者被设计为继承类应该或将覆盖的东西,无论它是否在同一个单元中,那么你会想要让它受到保护。

如果您需要从同一单元之外的后代类访问 FList,您还需要提高对 Protected 的可见性。

【讨论】:

  • 此外,无论您将 TFoo 的字段设为私有还是受保护,如果 TBar 在同一单元中声明,它们仍然对 TBar 可见。为了避免这种情况,在最近的 delphi 版本中使用“严格私有”。在没有Strict Private 的 Delphi 2007 中,将 TBar 移动到它自己的单元,以防止 ObjectPascal/Delphi 在其 OOP 设计中内置的“同一单元中的类的隐式朋友状态”。
  • 如果FList 是私有的(并且没有暴露在公共范围内)并且TFoo 和TBar 在不同的文件中,您会使用受保护的属性从TBar 访问它吗?
  • @Jens,是的。使用受保护的,继承的类可以从不同的单元访问它,同时仍然对其他类隐藏它。如果它在同一个单元中,如果我只是访问它,我很可能会将它保持为私有,但如果我要更改实现,我会将其设为公开。
猜你喜欢
  • 1970-01-01
  • 1970-01-01
  • 2010-11-05
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2020-03-29
  • 1970-01-01
  • 1970-01-01
相关资源
最近更新 更多