我正在用C ++编写一个长期运行的多线程服务器。它接收套接字上的请求,进行数据库查找并返回套接字上的响应。
服务器从配置文件中读取各种运行信息,包括数据库连接参数。我必须使用公司代码库中的数据库抽象类。我不想等到尝试进行数据库搜索以延迟实例化数据库连接(由于未显示复杂性,并且如果无法建立数据库连接,则需要在启动时退出错误)。
我的问题是如何将数据库连接信息下载到搜索类中,而不会做任何技术上可行的“丑陋”或糟糕的OOP事情。我想学习如何正确地做到这一点。
这样做有一个好的设计模式吗?我应该使用“从上面参数化”模式吗?我错过了一些更简单的构图模式吗?
// Read config file.
// Open DB connection using config values.
Server::process_request(string request, string response) {
try {
Process process(request);
if (process.do_parse(response)) {
return REQ_OK;
} else {
// handle error
}
} catch (..,) {
// handle exceptions
}
}
class Process : public GenericRequest {
public:
Process(string *input) : generic_process(input) {};
bool do_parse(string &output);
}
bool Process::do_parse(string &output) {
// Parse the input request.
Search search; // database search object
search.init( search parameters from parsing above );
output = format_response(search.get_results());
}
class Search {
// must use the Database library connection handle.
}
如何从顶层的Server类获取数据库连接到上面伪代码底部的Search类实例?
答案 0 :(得分:1)
您尝试解决的问题似乎是对象依赖项之一,并且可以使用dependency injection很好地解决。
您的班级Process
需要Search
的实例,必须以某种方式对其进行配置。不是让Process
实例分配他们自己的Search
实例,而是让他们在施工时接收现成的实例更容易。 Process
类不必了解Search
配置详细信息,因此避免了不必要的依赖关系。
但是问题然后级联到任何必须创建Process
的对象,因为现在这个问题必须知道配置细节!在您的情况下,这不是一个真正的问题,因为Server
类是创建Process
实例的类,并且它恰好知道Search
的配置详细信息。
但是,更好的解决方案是实现一个专门的类 - 例如DBService
,它将封装从配置步骤中获取的数据库详细信息,并提供一种方法来准备好Search
个实例。使用此设置,其他对象的构造和配置将不依赖于Search
类。作为一个额外的好处,您可以轻松实现并注入一个DBService
模型对象,它将帮助您构建测试用例。
class DBSearch {
/* implement/extends the Search interface/class wrt DB */
};
class DBService {
/* constructor reads up configuration details somehow: command line, file */
Search *newSearch(){
return new DBSearch(config); // search object specialized on db
}
};
上面的代码有点说明了解决方案。请注意,newSearch
方法不限于仅构建Search
实例,而是可以构建专门用于该类的任何对象(例如上面的类DBSearch
)。几乎从Process
中移除了依赖关系,现在只需知道它实际操作的Search
的接口。
这里强调的优秀OOP设计的核心要素是减少对象之间的耦合,以减少修改或增强应用程序部分时所需的工作量,
请查看dependency injection on SO以获取有关该OOP设计模式的更多信息。