我正在写一个非常大的库,我发现自己一直在编写几乎相同的访问器.我已经有几十个访问器,如下面的那个.
问题:如何声明/实现访问器以保存键入所有重复代码?(请不要#defines;我正在寻找C++结构.)
更新:是的,我确实需要访问器函数,因为我需要为这些访问器指向一个名为Property Descriptors的东西,它可以大大节省我的GUI代码(非库).
private:
bool _visible;
public:
bool GetVisible() const { return _visible; }
void SetVisible (bool value);
// Repeat for Get/SetFlashing, Get/SetColor, Get/SetLineWidth, etc.
Run Code Online (Sandbox Code Playgroud)
void Element::SetVisible (bool value)
{
_visible = value;
this->InvalidateSelf(); // Call method in base class
// ...
// A bit more code here, identical in 90% of my setters.
// ...
}
// Repeat for Get/SetFlashing, Get/SetColor, Get/SetLineWidth, etc.
Run Code Online (Sandbox Code Playgroud)
Lig*_*ica 33
我发现自己一直在写几乎相同的访问者.我已经有几十个访问器,如下面的那个.
这是一种确定的设计气味,你正在为了它而编写存取器.你真的需要它们吗?你真的需要为每个人进行低级公共"获取"和"设置"操作吗?这不太可能.
毕竟,如果您所做的只是为每个私有数据成员编写一个getter和一个setter,并且每个私有数据成员具有相同的逻辑,那么您可能只是公开了数据成员.
相反,你的班级应该有意义和语义的操作,在他们的职责过程中,可能会或可能不会使用私人数据成员.您会发现每个有意义的操作都与其他操作完全不同,因此重复代码的问题就会被破坏.
正如纳米所说:
简单:避免访问者.编写你的课程来做一些事情,而不是拥有一些东西.
即使对于那些对它们没有任何帮助的操作,比如控制可见性,你应该有a bool isVisible() const,a void show()和a void hide().你会发现,当你开始这样编码的时候,它会促使人们远离模板"为了它"的吸气剂和制定者.
Mat*_*son 26
虽然我认为Lightness Races in Orbit是一个非常好的观点,但也有一些方法可以用来实现"重复代码",这可以应用,假设我们确实有一个类"有许多相似的东西"需要单独控制,所以继续这样,说我们有几个像这样的方法:
void Element::Show()
{
visible = true;
Invalidate();
// More code goes here.
}
void Element::Hide()
{
visible = false;
Invalidate();
// More code goes here.
}
Run Code Online (Sandbox Code Playgroud)
现在,在我看来,这打破了DRY(不要重复自己)原则,所以我们应该做这样的事情:
void Element::UpdateProperty(bool &property, bool newValue)
{
property = value;
Invalidate();
// More code goes here.
}
Run Code Online (Sandbox Code Playgroud)
现在,我们可以实现Show和Hide,Flash,Unflash,Shaded通过这样做,避免了各功能内重复等.
void Element::Show()
{
UpdateProperty(visible, true);
}
Run Code Online (Sandbox Code Playgroud)
如果类型不总是bool,例如有一个position,我们可以这样做:
template<typename T>void Element::UpdateProperty(T &property, T newValue)
{
property = value;
Invalidate();
// More code goes here.
}
Run Code Online (Sandbox Code Playgroud)
并MoveTo成为:
void Element::MoveTo(Point p)
{
UpdateProperty(position, p);
}
Run Code Online (Sandbox Code Playgroud)
根据之前未公开的信息进行编辑,添加到问题中:
显然,上述技术同样可以应用于执行此类工作的任何形式的函数:
void Element::SetVisible(bool value)
{
UpdateProperty(visible, value);
}
Run Code Online (Sandbox Code Playgroud)
将起到与Show上述相同的作用.这并不意味着您可以远离声明函数,但它减少了对函数内部代码的需求.
我同意Lightness.你应该为手头的任务设计你的课程,如果你需要这么多的getter和setter,你可能会做错事.
也就是说,大多数好的IDE都允许你生成简单的getter和setter,有些甚至可以让你自定义它们.您可以将重复代码保存为模板,并在需要时选择代码片段.
您还可以使用emacs和Vim(使用Ultisnips)等可自定义的编辑器,并创建一些自定义帮助功能,使您的工作变得轻松.自动化的任务已经成熟.