我需要一些有关如何重构以下代码的建议。 我有多个配置类,它们都是不同的,但是正如您在下面的示例代码中看到的那样,正在发生重复模式。
我想知道简化View代码的最佳方法是什么?
class IConfiguration1
{
public:
virtual bool Save(const std::string& Output) = 0;
virtual bool OutText(const std::string& BaseFileName) = 0;
virtual bool Open() = 0;
}
class IConfiguration2
{
public:
virtual bool Save(const std::string& Output) = 0;
virtual bool OutText(const std::string& BaseFileName) = 0;
virtual bool Update() = 0;
}
class MockConfiguration
{
MOCK_METHOD1(Save,bool(const std::string& Output));
MOCK_METHOD1(OutText, bool(const std::string& BaseFileName));
}
void View::SaveConfiguration1(std::string path)
{
m_Configuration1->Save(path);
m_Configuration1->OutText(wxFileName::StripExtension(path).ToStdString())
//Enable Reset Menu
wxMenuItem* item2 = GetMenuBar()->FindItem(wxID_RESET);
if (item2 != NULL) item2->Enable(true);
}
void View::SaveConfiguration2(std::string path)
{
m_Configuration2->Save(path);
m_Configuration2->OutText(wxFileName::StripExtension(path).ToStdString());
//Enable Reset Menu
wxMenuItem* item2 = GetMenuBar()->FindItem(wxID_RESET);
if (item2 != NULL) item2->Enable(true);
}
void View::SaveConfiguration3(std::string path)
{
m_Configuration3->Save(path);
m_Configuration3->OutText(wxFileName::StripExtension(path).ToStdString());
//Enable Reset Menu
wxMenuItem* item2 = GetMenuBar()->FindItem(wxID_RESET);
if (item2 != NULL) item2->Enable(true);
}
此函数调用保存
void Controller::SaveCurrentSettings()
{
switch (m_View->GetSelectedConfiguration())
{
case Options::Configuration1:
{
SaveConfiguration1();
}
break;
case Options::Configuration2:
{
SaveConfiguration2();
}
break;
case Options::Configuration3:
{
SaveConfiguration3();
}
break;
}
}
答案 0 :(得分:1)
创建所有配置通用的(抽象)界面。 对于显示的代码,这将包括Save和OutText,但不包括Open或Update。
从该界面导出配置
使用单个函数SaveConfiguration方法替换SaveConfiguration1,SaveConfiguration2,该方法具有一个附加参数,可让您选择要保存的正确配置。正如Jarod42所评论的那样,该参数可以是配置本身(作为对我提到的新通用接口的引用而传递)。否则,该参数可能是用于在SaveConfiguration方法中选择配置的枚举。
无论哪种方式,当您到达重复的Save和OutText行时,您将通过新接口使用调用它们,并依靠虚函数的功能来处理不同的配置不相同的事实,方法是调用特定的Save和OutText版本。
...在评论“我已经有一个枚举1级”之后编辑
所以代替:-
case Options::Configuration1:
{
// your example call doesn't pass a view, but your SaveConfiguration requires one
SaveConfiguration1(/* view? */);
}
你可以
case Options::Configuration1:
{
// your example call doesn't pass a view, but your SaveConfiguration requires one
SaveConfiguration(/* view? */ , m_Configuration1);
}
SaveConfiguration在哪里使用IConfiguration&
void View::SaveConfiguration(std::string path, IConfiguration& config)
{
config.Save(path);
config.OutText(wxFileName::StripExtension(path).ToStdString())
//Enable Reset Menu
wxMenuItem* item2 = GetMenuBar()->FindItem(wxID_RESET);
if (item2 != NULL) item2->Enable(true);
}
class IConfiguration
{
public:
virtual bool Save(const std::string& Output) = 0;
virtual bool OutText(const std::string& BaseFileName) = 0;
// no output or update
}
您还需要在将开关移到拥有配置的视图或使配置对控制器可用的选择之间。