私のプロジェクトには、さまざまな形式からロードおよび再ロードできる 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... }
};
ローダーは指定された形式で入力を読み取り、ターゲットの Resource オブジェクト R を初期化します。ローダーはリソース内に格納されるため、リソースが無効になると、格納されたローダーを使用して自身をリロードします。
問題は、ローダーがリソースを初期化する方法です。
- すべての InternalData フィールドをパブリックにします。それらへのクライアントアクセスを許可しますが、これは良くありません。
- Loader を Resource のフレンドにします。特定の形式の新しいローダーはそれぞれリソース ヘッダーに追加されるため、拡張性が失われ、拡張機能を作成するプログラマは基本コードに触れる必要があります。
- InternalData ごとにセッターを提供します。すべてのクライアントがデータを変更する可能性があるため、変更してはならないため、それらをすべて公開することはそれほど遠くありません。
- Resource::Setup(InternalData1, InternalData2, InternalDataN) を提供するか、それらすべてを何らかの構造体でラップして、その構造体を渡します。すべてのフィールドが一度に設定されることを除いて、3. と同じです。
問題は、 Resource クラスのフィールドは、拡張可能な一連のクラスからの書き込みにはアクセスできなければならず、クライアント コードからの書き込みにはアクセスできない必要があることです。良いOOPソリューションはありますか? ありがとう。