2016-12-01 150 views
-1

我有如下策略類:模式,以避免循環調用

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

class CPolicy : public IPolicy 
{ 
public: 
void func1() override { // do something } 
} 

而且我有工具類如

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

// default behavior 
} 

} 

現在的問題是,考慮政策的執行有一定的條件,如果條件失敗,策略調用默認實現(這是場景之一,可以有多種組合)

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 
} 

} 

有了這些變化,預計一切都將正常工作,但我不滿意這樣的設計。我不想依賴Policy是否正確設置usePolicy變量。如果有任何呼叫來自策略到默認實現,那麼我應該能夠忽略策略。

這樣的問題有什麼好的模式/解決方案嗎?

回答

0

Policy類不應該做任何事情超過它負責(單一職責原則)。一個簡單的改變是讓func1返回一個bool值,並讓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 
    } 
    } 
};