2016-12-01 63 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 
    } 
    } 
};