2016-12-01 15 views
-1

を呼び出します、ポリシーはデフォルトの実装を呼び出します(これはシナリオの1つですが、複数の組み合わせがあります)パターンは、私は以下のようにポリシーのクラスを持っている

class CPolicy : public IPolicy 
{ 
public: 
void func1() override { 
if(condition) 
{ 
    // customized logic 
} 
pDefaultUtil->func1(); 
} 
} 

この実装が見えたら、それは循環呼び出しで浪費されます。

この問題を解決するために、私はIPolicy契約に別の機能を導入しました。

interface IPolicy 
{ 
public: 
virtual void func1() = 0; 
virtual bool ShouldUsePolicy() = 0; 
} 


class CPolicy : public IPolicy 
{ 
public: 
void func1() override { 
if(condition) 
{ 
    // customized logic 
} 
usePolicy = false; 
pDefaultUtil->func1(); 
usePolicy = true; 
// other logic continues. 
} 

bool ShouldUsePolicy() override { return usePolicy; } 
private: 
bool usePolicy { true }; 
} 

とUtilのクラスは次のように変更されます。これらの変更により

class Util { 
public: 
void func1() { 
if(policy != nullptr && policy->ShouldUsePolicy()) policy->func1(); // customized behavior 

// default behavior 
} 

} 

、すべてが期待どおりに動作しますが、私はこのデザインに満足していません。ポリシーがusePolicy変数を適切に設定しているかどうかに依存したくありません。 PolicyからDefault実装への呼び出しがあれば、ポリシーを無視できるはずです。

このような問題のパターン/解決策はありますか?

答えて

0

Policyクラスは、それが責任を負っている以上のことを行うべきではありません(単体責任原則)。簡単な変更は、func1をブール値に戻し、Utilityクラスがfalseを返すときに何をするかを決定させることです。

class IPolicy 
{ 
public: 
    virtual bool func1() = 0; 
    virtual ~IPolicy() {}; 
} 


class CPolicy : public IPolicy 
{ 
public: 
    void func1() override { 
    if(condition) 
    { 
     // customized logic 
     return true; 
    } 
    return false; 
}; 

class Util { 
public: 
    void func1() { 
    assert (policy); 
    if (! policy->func1()) { 
     // Call the default action as seen 
     // fit by the Util class 
    } 
    } 
}; 
関連する問題