在我的项目中,我有可以从不同格式加载和重新加载的Resource对象。加载算法在不同的ResourceLoader子类中实现。
class Resource
{
private:
// Not for client access
Type1 InternalData1;
Type2 InternalData2;
TypeN InternalDataN;
ResourceLoader Loader;
public:
// Any client interface
void UseResource();
};
class ResourceLoader
{
public:
void Load(Resource& R) = 0;
};
class ResourceLoaderFormat1: public ResourceLoader
{
public:
void Load(Resource& R) { ...loads Resource from Format1... }
};
class ResourceLoaderFormat2: public ResourceLoader
{
public:
void Load(Resource& R) { ...loads Resource from Format2... }
};
Loader以给定格式读取输入并初始化其目标Resource对象R. Loader存储在资源中,因此如果资源变为无效,则使用存储的加载器重新加载自身。
问题是Loader应该如何初始化资源?
问题在于,必须可以访问Resource类字段,以便从可扩展的类集中进行写入,并且必须无法访问客户端代码。有没有好的OOP解决方案?感谢。
答案 0 :(得分:1)
假设我们选择
让Loader成为Resource的朋友。
有缺点
特定格式的每个新加载器都将添加到资源标头中,从而消除了可扩展性,并要求任何编写扩展程序的程序员触摸基本代码。
但是,由于您将加载器拆分为基类+派生类,因此您只能授予对Loader
的访问权限,并通过Loader
成员授予protected
子类访问权限。
class Resource
{
Type1 InternalData1;
...
friend class ResourceLoader;
};
class ResourceLoader
{
...
protected:
static void setResourceInternalData1(Resource &r, const Type1 &val1);
...
};
所有ResourceLoader
子类现在都可以访问这些setter,因为它们是protected
:
class ResourceLoaderFormat1: public ResourceLoader;
class ResourceLoaderFormat2: public ResourceLoader;
只要您不经常更改Resource
的数据成员,这将很有效。
答案 1 :(得分:1)
另一种解决方案是(如我的第一条评论所述):
class ResourceClient
{
public:
virtual void UseResource() = 0;
}
class ResourceLoader
{
public:
virtual void SetResource() = 0;
}
class Resource:
public ResourceClient,
public ResourceLoader
{
private:
// Not for client access
Type1 InternalData1;
Type2 InternalData2;
TypeN InternalDataN;
ResourceLoader Loader;
public:
// Any client interface
virtual void UseResource();
virtual void SetResource();
};
class ResourceLoader
{
public:
void Load(ResourceLoader& R) = 0;
};
class ResourceLoaderFormat1: public ResourceLoader
{
public:
void Load(ResourceLoader& R) { ...loads Resource from Format1... }
};
class ResourceLoaderFormat2: public ResourceLoader
{
public:
void Load(ResourceLoader& R) { ...loads Resource from Format2... }
};
需要编写的函数集资源使用ResourceLoader指针和restrected函数将使用ResourceClient指针访问资源。
此解决方案的优点是您不需要使用写访问权限声明任何类或函数。 Juste根据您的需要或想要的功能使用正确的界面