简体   繁体   English

是什么让这段代码变坏了

[英]What really makes this code bad

At my company I came across the following 2 code snippets, which I found thoroughly unpleasant at first sight, but in the spirit of offering constructive feedback to the engineer who wrote that, I'm trying to come up with technical arguments why this code is bad: 在我的公司,我遇到了以下两个代码片段,我发现这些代码片段一见钟情,但本着向撰写该代码的工程师提供建设性反馈的精神,我试图提出技术论据,为什么这段代码是坏:

FileTableEntry * FilerManager::GetFileTableEntry(uint32_t i) const {
  return &(GetFileTable()[i]);
}

…
for (uint32_t i = 0; i < container_.size(); ++i) {
   *GetFileTableEntry(i) = FileTableEntry();
   // GetFileTableEntry ultimately accesses a std::vector in FileManager
}

My main arguments are : 我的主要论点是:

  1. This code is very indirect and misleading, it should not use a getter to initiliaze (part of the FileManager), but at least a setter: being more direct makes the code easier to understand. 这段代码非常间接和误导,它不应该使用getget来初始化(FileManager的一部分),但至少是一个setter:更直接使代码更容易理解。
  2. The getter completely leaks the internal state of the FileManager, so encapsulation for FileManager means nothing at this point. getter完全泄漏了FileManager的内部状态,因此FileManager的封装在这一点上没有任何意义。 Even worse, the getter promises to be applicable to const objects, but is merrily used to mutate the internal state of FileManager. 更糟糕的是,getter承诺适用于const对象,但是很快就会用来改变FileManager的内部状态。 Breaking encapsultion is a sure path to making refactorings harder. 打破封装是使重构更难的必由之路。

Are there other arguments for not writing code like this that I would be missing?? 还有其他论据不写这样的代码我会遗漏吗?

Another argument against this code is that the signature of GetFileTableEntry returns a pointer in situations when the object is always present. 反对此代码的另一个参数是GetFileTableEntry的签名在对象始终存在的情况下返回指针。 This calls for a reference, not a pointer: 这需要引用,而不是指针:

FileTableEntry& FilerManager::GetFileTableEntry(uint32_t i) const {
    return GetFileTable()[i];
}

This should address your first point. 这应该解决你的第一点。 Your second point can be addressed by making the reference const : 你的第二点可以通过引用const来解决:

const FileTableEntry& FilerManager::GetFileTableEntry(uint32_t i) const {
    return GetFileTable()[i];
}

This prohibits the callers from modifying the internal state returned by GetFileTableEntry . 这禁止调用者修改GetFileTableEntry返回的内部状态。

Note: To make the GetFileTableEntry function useful, one should add a bounds check of the index passed in to catch errors early. 注意:要使GetFileTableEntry函数有用,应该添加传入的索引的边界检查以及早捕获错误。

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

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