[英]How to implement clean architecture component boundaries in c++?
我正在阅读 Robert C. Martin 的 Clean Architecture,我想将书中的知识应用到我的 C++ 程序中。 然而,我不明白的一件事是接口边界应该如何工作。
“内层”(业务规则)不应该知道任何关于外层的信息。 意思是红线上方的东西不应该知道下图中红线下方的东西。
但是,如果业务规则使用 C++ 接口(纯抽象类)与数据库(下图中的数据库接口)通信,它们是否不必在“数据库访问/数据库”中包含对实现标头的引用模块,因为抽象基类不能被实例化? 这难道不会违反业务规则不应了解外层的原则吗?
在 C++ 中正确的方法是什么?
图片:图 17.2 来自 Clean Architecture
C++ 中的纯虚拟接口大致类似于 C# 或 Java 等托管语言中的接口:
struct DatabaseInterface {
virtual ~DatabaseInterface();
virtual std::string get(std::string key) = 0;
virtual void put(const std::string& key, const std::string& value) = 0;
};
依赖于数据库的类可以依赖于指向抽象基类的拥有指针。 它不需要了解有关实现的任何信息:
struct BusinessRules {
std::unique_ptr<DatabaseInterface> db; // reference
BusinessRules(std::unique_ptr<DatabaseInterface>);
/* stuff using the database interface */
};
虽然您不能直接实例化它,但您可以让另一个类继承接口,并且您可以将具体类的实例传递给需要指向抽象类接口的指针的使用者:
struct SpecificDatabaseAccess: public DatabaseInterface {
SpecificDatabaseAccess(const std::string& connectionString);
std::string get(std::string key) override;
void put(const std::string& key, const std::string& value) override;
};
/* ... */
// dependency injection through the constructor
auto db = std::make_unique<SpecificDatabaseAccess>("...");
auto rules = BusinessRules(std::move(db));
标准库对istream
做了类似的事情。 istream
有一堆方法,它们作用于较低级别的streambuf
成员之上。 streambuf
是一个抽象接口,其实现执行 I/O 访问(对 stdin、文件、字符串等)。
虽然这些都与 Clean Architecture 没有直接关系,但您可以通过这种方式使组件的实现独立于它们的依赖项。
声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.