我有两个类,Repository和Search。存储库封装了用于存储和管理内容的逻辑,而搜索封装了用于搜索内容的逻辑,还需要访问存储库对象,以便读取内容。
通常,我想将Repository类的功能划分为public,该类的每个用户都可以访问,而private则只能在内部使用。我遇到的问题是Search类应该可以访问Repository的私有功能,但是因为Repository对象将从外部传递给Search对象,所以它只会公开公共功能。
我现在这样做的方式是,Repository使用pimpl习惯用法来隐藏实现细节,并且我将Search声明为朋友,因此它可以在实现代码中使用私有功能。
Repository.h:
// Forward declaration of implementation class
class RepositoryImpl;
// Forward declaration of friend class
class Search;
class Repository
{
public:
// public interface
private:
RepositoryImpl* pImpl;
};
Search.h
class Search
{
public:
void searchRepository(Repository* repo);
};
Search.cpp
void Search::searchRepository(Repository* repo)
{
repo->pImpl->someHiddenMethod();
}
这显然只是给予和想法,所以它在实际功能方面没有任何意义,但我希望它能很好地解释我正在努力解决的问题。 有些人可能会说在这里使用朋友非常好,但对我来说感觉有点“hacky”所以如果有更好的方式(一些设计模式)去做,我想用。
我也不想将这些类合并为一个(尽管它似乎是一个好主意),因为它引入了一些不可接受的限制。基本上我希望能够拥有一个搜索引擎,能够使用多个存储库。如果能够以干净的方式实现目标,我仍然可以完成对课程的重新设计。
非常感谢你。
答案 0 :(得分:2)
您可以创建Searchable
使用的Search
和RepositoryImpl
实施的界面。然后,向Repository
添加一个公共接口,该接口返回pImpl
成员但缩小到Searchable
接口。
执行上述操作的优点是您不必将RepositoryImpl
的所有实现细节公开到Search
,这使您的方法感觉像是黑客。
// in Search.h
class Searchable
{
friend class Search;
virtual void internal_method () = 0;
//...
protected:
virtual ~Searchable () = default;
};
// in Repository.cpp
class RepositoryImpl : public Searchable //...
{
//...
};
Searchable * Repository::searchable () { return pImpl; }
// in Search.cpp
void Search::searchRepository(Repository* repo)
{
repo->searchable()->internal_method();
}
答案 1 :(得分:0)
可能您不需要访问存储库实现细节。
搜索应该能够在Repository上工作而不了解Repository的详细信息,例如,如果您正在使用STL容器和其元素的迭代器。
因此,您可能应该修改Repository接口以授予对底层元素的访问权限(例如将begin()和end()添加到公共接口)并让Search类使用这些“句柄”。 如果Search足够通用以便与其他类型的“迭代器”一起使用,那就更好了。
P.S。我本来希望将其添加为注释,因为这些信息不能准确得出明确的答案。但由于声誉不佳,我不被允许。