得到GET得到 - 过度设计?效率与一致性

时间:2014-12-19 09:22:24

标签: c++ performance ogre3d

我知道公共变量的缺点/具有GET和SET函数的私有变量的优势,但目前我正在使用Ogre3D(C ++)开发我自己的第一个'真实'游戏。同时,我有时需要6-7 getFunctions()访问我需要对其执行单个操作的数据。 所以,我想知道这是不是过度/过度设计,以及何时将新的直接指针存储到其他类/函数中的某些对象可能是有用的。但这听起来不像是良好的编排,良好的编程风格和/或可读性。 (我来自德国,实际上并不知道'constancy'是否是正确使用的词,如果没有,请纠正我。我的意思是代码结构的同质性,例如整个代码遵循严格的编程风格)

那么,一个GetFunction(返回指向对象的指针)需要多长时间?是否过度设计大约5-7 Get?

或者:在| R getFunctions()中,对于哪些X in | | | | | | | | | | | | | | | | | | | | | | | | | | | | | |

可能有些人说这是过度优化,但另一个方面是可读性 with getFunctions()..

我的游戏中的一个例子,以获得本地玩家在某个“基地”中拥有的剑客数量。

int numSwordsman =  GameManager::getSingletonPtr()->getMatchInstance()->getPlayerData()->getLocalPlayer()->getGameElementManager()->getBase(EWT_MAINBASE)->getSwordsmann();

更糟糕的是这样的事情

Ogre::Vector2 newVec2 = Ogre::Vector2(GameManager::getSingletonPtr()->getSceneManager()->getCameraNode()->getViewport()->getActualHeight() / GameManager::getSingletonPtr()->getMainGameLoop()->getMouse()->getState()->x.abs,GameManager::getSingletonPtr()->getSceneManager()->getCameraNode()->getViewport()->getActualWidth() GameManager::getSingletonPtr()->getMainGameLoop()->getMouse()->getState()->y.abs);

除了你需要大约20-30秒才能理解那里发生的事情之外,还有一个巨大的痛苦......打字。

就个人而言,我更喜欢编写像

这样的代码
Ogre::Vector2 newVec2 = Ogre::Vector2(GameManager::getSingletonPtr()->
     getSceneManager()->getCameraNode()->getViewport()->getActualHeight()
          / GameManager::getSingletonPtr()->getMainGameLoop()->getMouse()->getState().X.abs,
     GameManager::getSingletonPtr()->
          getSceneManager()->getCameraNode()->getViewport()->getActualWidth() 
          / GameManager::getSingletonPtr()->getMainGameLoop()->getMouse()->getState().Y.abs);

但是对于那些不了解我的编码风格的人来说,它可能会让人感到困惑,因为它超出了所有人类已知的编程风格和实践。

您如何看待这个话题?这整个Get-> Get-> Get-> Get->得到过度设计?还是不可避免的必要?你如何处理'远方'对象指针?不重要的主题或与性能密集型应用相关的主题?关于代码设计的任何窍门和技巧?或者7-8'Get仍然是标准的?

2 个答案:

答案 0 :(得分:2)

我会将您的代码示例重写为:

auto GM = GameManager::getSingletonPtr();
auto VP = GM->getSceneManager()->getCameraNode()->getViewport();
auto mouse = GM->getMainGameLoop()->getMouse()->getState();

Ogre::Vector2 newVec2 = Ogre::Vector2(
     VP->getActualHeight() / mouse.X.abs,
     VP->getActualWidth() / mouse.Y.abs);

只是为了可读性;效率方面我怀疑它可能会更糟,它可能会更好。

(另外,由于不知道表面下方发生了什么,我宁愿抓住鼠标状态一次:我不想在鼠标移动的任何一侧获得X和Y!)

如果关注效率,请在所有优化的基础上进行编译,然后查看生成的汇编代码。为清晰起见,比较代码重构的前/后;也许它会是一样的。 (这里唯一需要注意的是编译器技术总是在不断改进,所以最好的做法现在可能不是两年内的最佳实践。)

还有一个提示:阅读Martin Fowler的重构书,以提高你在添加抽象层时的直觉,并且在折叠抽象层时很好。是的,我知道现在已经15岁了,但恕我直言,这个建议非常好......即使这些例子都在java中; - )

答案 1 :(得分:1)

这就是我改变你迄今给出的内容的方式。关键原因是可读性和最重要的所有调试能力。将函数结果存储到本地中可以在调试器中轻松进行状态检查。我不保证这在语法上是正确的,它是用记事本写的,但你明白了。

实际工作的陈述现在更加清晰,并且没有模糊地购买你寻找国家,这是非常可怕的。你的程序会遇到面向对象过载的问题,但也许这就是你正在使用的引擎。我不能从一个片段中说出来。

// How many are dereferenced is down to the judgement of the programmer
// If you think inspection of the state is useful in the debugger or
// validation against null is required then dereference.
// If it's never null, or simply not useful, then I don't really have 
// an objection to chain dereferencing.
SingletonPtrType singleton_ptr = GameManager::getSingletonPtr();
SceneManagerType scene_manager = singleton_ptr->getSceneManager();
CameraNodeType camera_node = scene_manager->getCameraNode();
MouseStateType mouse_state = singleton_ptr->getMainGameLoop()->getMouse()->getState();

ViewPortHeightType height  = camera_node->getViewport()->getActualHeight();
ViewPortWidthType width = camera_node->getViewport()->getActualWidth();

Ogre::Vector2 newVec2 = Ogre::Vector2(height / mouse_state.X.abs, width / mouse_state.Y.abs);