关于封装和继承实践的问题

问题描述 投票:1回答:3

[我听过有人说拥有protected成员有点破坏封装的观点,而不是最佳实践,应该设计程序,使派生类将不需要访问private基类成员。


示例情况

现在,想象以下场景,一个简单的8位游戏,我们有一堆不同的对象,例如,常规框充当障碍物,尖峰硬币移动平台等。列表可以继续。

它们都具有x和y坐标指定对象大小的矩形和碰撞盒纹理。它们还可以共享设置位置渲染加载纹理检查碰撞等功能

但是其中一些还需要修改基本成员,例如盒子可以被推开,所以它们可能需要移动功能,某些对象可能会自己移动,或者某些块会在游戏中更改纹理。

因此,像object这样的基类确实可以派上用场,但这要么需要大量的[[getters-setters,要么要让private成员成为protected。无论哪种方式,都会损害封装。


考虑到轶事背景,这将是更好的做法:

1。具有共同的基类,该基类具有共享的函数和成员,并声明为受保护的。能够使用通用函数,将基类的引用传递给只需要访问共享属性的非成员函数。但是要破坏封装。

2。

每个都有一个单独的类,将成员变量声明为私有,并且不影响封装。

3

。我想不到的更好的方法。
我不认为封装是至关重要的,可能发生此事的方法可能只是拥有受保护的成员,但是我的目标是编写一个实践良好的标准代码,而不是解决该特定问题。

提前感谢。

c++ inheritance encapsulation
3个回答
1
投票
首先,我要说的是,没有一个适合所有设计的单一尺寸的答案。不同的问题需要不同的解决方案;但是,随着时间的推移,有些设计模式通常可能比其他设计模式更易于维护。

的确,许多设计建议使它们在

团队环境中变得更好-但是好的实践对单独项目也很有用,以便将来更容易理解和更改。

有时候,需要了解您的代码的人将是您,一年后-请记住这一点😊

我听过有人说保护成员会破坏封装的意义

像任何工具一样,它可能会被滥用;但是protected访问并没有本质上破坏封装的内容。

定义对象封装的是预期的投影API表面积。有时,protected成员在逻辑上是表面区域的一部分—完全正确。

如果

misused

protected成员可以使客户端访问可变成员,这可能会破坏类的预期不变式,这很糟糕。例如,您是否能够派生暴露rectangle的类,并且能够将width / height设置为负值。基类中的函数,例如compute_area可能会突然产生错误的值-并导致级联失败,否则应该通过更好地封装来防止这些失败。

关于所讨论示例的设计:

基类不一定是一件坏事,但很容易被过度使用,并可能导致“神”类无意间暴露了太多功能以共享逻辑。随着时间的流逝,这可能会成为维护负担,并且只会带来混乱的局面。

您的示例听起来更适合作曲,但界面较小:

    pointvector之类的东西将是基本类型,以产生像rectangle之类的高阶成分。
  • 然后可以将其组合在一起以创建一个model,该C0处理2D空间中发生碰撞的常规(逻辑)对象。
  • 交叉口/碰撞逻辑可以从外部实用程序类处理
  • 可以从renderable接口处理渲染,其中需要渲染的任何类都从该接口扩展。
  • 交叉口处理逻辑可以由intersectable接口处理,该接口确定对象在交叉口上的行为(这有效地将每个游戏对象抽象为原始行为)

1
投票
封装不是安全的东西,它不是一个整洁的东西(因此不是可支持性,可读性..)。您必须假设派生阶级的人基本上是明智的。毕竟,他们要么使用您的基类(所以谁在乎)编写自己的程序,要么与您一起编写团队]

1
投票
"encapsulation"在面向对象编程中的主要目的是限制对数据的直接访问,以最大程度地减少依赖关系,以及必须存在依赖关系的地方,以用[[functions而不是[[data 。

Design by Contract息息相关,您可以在其中允许“公共”访问某些功能,并保留随时以任何理由任意修改其他功能的权利,甚至可以通过将这些功能表示为“受保护”。

也就是说,您可能有一个游戏对象,例如:class Enemy { public: int getHealth() const; }

getHealth()函数返回表示健康状况的int值。它如何得出这个值?这不是呼叫者知道或关心的。也许是您刚刚收到的二进制数据包的字节9。也许是来自JSON对象的字符串。没关系。

最重要的是,因为没有关系,您可以自由更改getHealth()内部的工作方式,而无需

breaking
任何依赖于[[dependent
的代码。

但是,如果您要公开一个公开的int health属性,则会带来很多问题。如果操作不当怎么办?如果将其设置为无效值怎么办?您如何捕获对被操纵属性的访问?

[拥有setHealth(const int health)时您可以轻松执行以下操作:

将其夹紧到特定范围

超过特定范围时触发事件

更新已保存的游戏状态

    通过网络传输更新
  • 钩住其他“观察者”,他们可能需要知道何时操纵该值
  • 没有封装,这些东西都不容易实现。
  • protected不仅是“滚开草坪”,它还是确保<和
  • 按预期的方式使用
  • 的实现的重要工具。”
    © www.soinside.com 2019 - 2024. All rights reserved.