外部是否破坏封装



我是C++的新手,我正在创建一个游戏。我有一个叫main的类,我在其中声明

Game * game; //globally
int main() {
    game = new Game();
    game->show();
}

我的职业游戏启动了我的游戏等。现在在其他职业(玩家、敌人等)中,我使用访问游戏中的变量,如玩家健康状况

#include<game.h>
extern Game * game;
func::func() {
    game->health->resetHealth();
}

这是打破封装/ood范式吗?这是不好的做法吗?问题是,我可以在比赛中看到任何其他方式。

是的,extern破坏了封装。封装的主要概念是数据隐藏和绑定单个实体中对象的属性和行为。使变量extern会违反法律
在一些更先进的OOP语言中,如java,没有extern。在Java中,它总是建议将属性/字段设置为私有,以限制其访问。

我的意思是,是的,它没有封装。game是一个全局指针,可以从任何地方访问和更改。封装就是数据隐藏,game是完全公开的。它也不是典型的面向对象设计。为了进行适当的封装和OOD,您应该限制谁使用和"了解"Game * game。例如,可以有一个由Game *组成的GameController对象。Game *的作用域和生存期可以存在于GameController中,然后GameController可以通过将其设为私有变量并决定谁、如何以及何时访问指针来封装其成员变量。还有其他方法,比如将指针封装在全局单例类中。这比您的示例要好,因为包装类可以强制执行某些不变量(比如访问游戏时应该发生什么,或者客户端应该如何删除游戏)。通常,全局单态不是最好的方法,原因不在这个答案的范围内。另一种方法是使用依赖注入。因此,每当一个类需要修改Game *时,它都会将指针传递给它。这些都是访问封装数据的面向对象技术。

只要有一个全局变量就开始破坏封装,因为它可以从程序中的任何代码访问对象。当你有一个类似的全局时,任何函数都会产生改变游戏的副作用,甚至是在完全不相关的对象实例中。使用extern不会进一步破坏封装,因为它大致相当于将更多代码粘贴到声明全局的单个源文件中。

使用全局变量本身不会破坏封装——如果对象不是全局的,它可以尽可能多地隐藏其实现细节。然而,在大多数情况下,它确实与另一个设计原则相冲突:灵活性。比方说,你希望你的程序一次处理多个游戏(如果以后的更改根本没有意义,你可能会决定保持全局性)。

每当你准备声明某个全局变量时,问问自己:也许是件好事

  • 会很难避免吗?(在所示的例子中,只需将game对象传递给需要它的函数就可以了。)
  • 有没有可能在以后的某个时间点上不只有一种这样的物体?(例如,你可能想为游戏的级别编写一个编辑器,在那里你想重用一些代码,这个编辑器应该能够在多个选项卡中编辑多个游戏。)
  • 使用全局硬化读取代码吗?(记住,读起来容易比写起来容易重要得多!)

在我看来,在大多数情况下,最好避免全局变量;我认为对于问题中所示的情况,最好避免这种情况。game参数可以很容易地传递。

简而言之,是的,这会破坏封装。你不断引用游戏对象的事实表明你对这个对象有依赖性。

你可以考虑在你的程序中有一个初始化序列,称为composition root(对于简单的例子来说,main是最明显的地方),你可以通过构造函数将所有这样的依赖项传递给需要它们的对象,这被称为依赖项注入。

如果你想更进一步,你可以创建基类并传递抽象基类,而不是实现对象。通过这种方式,您可以更多地针对接口而不是对象进行编程。

最新更新