繁体   English   中英

Extern 是否打破封装

[英]Does Extern Break Encapsulation

我是 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可以通过将其GameController私有并决定访问指针的人、方式和GameController来封装其成员变量。 还有其他方法,例如将指针包装在全局单例类中。 这比您的示例要好,因为包装类可以强制执行某些不变量(例如访问游戏时应该发生什么,或者客户端应该如何删除游戏)。 通常,由于本答案范围之外的原因,全局单例不是最佳方法。 另一种方法是使用依赖注入。 因此,每当一个类需要修改Game * ,它都会将指针传递给它。 这些都是用于访问封装数据的面向对象技术。

仅仅拥有一个全局变量就已经开始破坏您的封装,因为它提供了从程序中的任何代码访问对象的权限。 当你有一个这样的全局变量时,任何函数都可以产生改变游戏的副作用,即使是在完全不相关的对象实例中也是如此。 使用 extern 不会进一步破坏封装,因为它大致相当于将更多代码粘贴到声明全局的单个源文件中。

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

每当您要声明某个全局变量时,不妨问问自己:

  • 很难避免吗? (在所示的情况下,只需将game对象传递给需要它的函数就很容易了。)
  • 是否有可能在以后的某个时间点不只有一种这样的物体? (例如,您可能想为游戏的关卡编写一个编辑器,您想在其中重用一些代码,并且该编辑器应该能够在多个选项卡中编辑多个游戏。)
  • 使用全局强化阅读代码吗? (请记住,易读比易写更重要!)

在我看来,在大多数情况下,最好避免使用全局变量; 我认为对于问题中显示的情况最好避免它。 可以轻松传递game参数。

简而言之,是的,这打破了封装。 您一直引用游戏对象这一事实表明您对这个对象有依赖性。

你可能会考虑在你的程序中有一个初始化序列,称为组合根,(对于简单的例子, main 是最明显的地方),在那里你通过构造函数将所有像这样的依赖传递给需要它们的对象,它称为依赖注入。

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

暂无
暂无

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM