我一直在为我的项目遇到一些设计问题,我希望得到一些帮助.我想出了一个例子,我想概述了我遇到的问题.我是软件设计的新手,如果我完全错过了什么,请原谅我.
在这个例子中说我有:
struct Book {
std::string author_first_name;
std::string author_last_name;
int year_published;
double price_in_dollars;
};
class BookCase {
std::vector<Book> all_books;
// Rest of class implementation
}
我从一个文件或多个文件中读取所有书籍并将它们存储在BookCase中.然后我想在BookCase上做一堆操作,在运行时定义,这是我被卡住的地方.
假设用户想要按作者对书籍进行排序然后导出,下次按名字排序或按价格排序,或者想要添加新操作可能会删除在X年之前发布的书籍.
我的问题是:
>这些操作的最佳位置在哪里.我可以轻松地将这些操作添加到BookCase:
class BookCase {
void SortByLastNameAscending();
void SortByLastNameDescending();
void SortByPriceAscending();
// etc...};
我知道这是错的,这将使类膨胀,并且每次添加新操作时都必须更改类.我可以拥有像类甚至名称空间“BookCaseProcessor”的东西,它具有所有操作并在那里添加新的操作.是否有一种更优雅的方式来处理这样的事情,也许是我缺少的设计原则.
>我如何以一种很好的方式将操作串在一起.假设用户想要RemoveBooksBeforeYear(),RemoveBooksThatCostLessThan(),SortByLastNameDescending().下次他们跑步时,他们只想做一件事,或者10件事.现在,我能想到的唯一解决方案就是一堆if语句.
最佳答案 我认为最简单的方法是使用std :: function.
鉴于你实现了各种各样的操作:
void SortByLastNameAscending(BookCase&) {...}
void SortByLastNameDescending(BookCase&) {...}
void SortByPriceAscending(BookCase&) {...}
您可以填充要执行的简单操作列表:
std::vector<std::function<void(BookCase&)>> pipeline;
//populate the pipeline
if(user_choice == "sort") {
pipeline.emplace_back(SortByLastNameAscending);
}
并按顺序执行它们:
BookCase data;
for(auto& op : pipeline) {
op(data);
}