c ++找到兄弟姐妹的状态

时间:2011-05-05 08:07:14

标签: c++

在我的代码中,有一个基类A,它有三个子类A1,A2,A3。这些对象具有指定它们是否处于活动状态的状态。

现在在另一个B类中,创建了A1,A2和A3的对象。现在在B内的一个函数中,

int B::SetState( A& aObj)
{
  //if aObj is an instance of A1, do nothing and return.
  //if aObj is an instance of A2, do something if A3 is active 
  //if aObj is an instance of A3, do something if A2 is active 

  //the code below i would like to change to something more maintainable
  if ( aObj.GetNumber() == 0 )
      return;

  A& otherAObj = aObj.GetNumber()==1? GetAObj(2) : GetAObj(3);

  if ( otherAObj.IsActive() )
  {
    //do something with aObj
  }

}

我想将代码更改为aObj.DoSomething(),但兄弟之间的依赖关系使其变得艰难。重构还有其他好的想法吗?类结构必须保持不变。

2 个答案:

答案 0 :(得分:0)

你可以重构这个:

if ( otherAObj.IsActive() )
{
  //do something with aObj
}

进入doSomething()函数

public class A{
    virtual bool isActive(){ return false; }
    virtual bool isPending(){ return false; }
    virtual void doSomething()
    {
        if(true == isActive())
        {
            ...
            if(false == isPending())
            { ... }
            ...
        }
    };
}

public class A_State_Active : A
{
    bool isActive(){ return true; }
}

public class A_State_Pending : A
{
    bool isPending(){ return true; }
    void doSomething()
    {
        throw new InvalidOperationException("Don't be messing");
    }
}

甚至可以将doSomething的基本版本设为pure virtual,以强制用户实现特定于州的版本。

但是,您不应在子类中实现基于不同对象状态的任何内容。 IMO你应该在这种情况下使用管理器类型对象。如果真的想这样做,你应该只将对其他对象的引用传递给doSomething()函数,并根据传递对象状态的返回值修改运行时行为(使用“isActive”/“查询isPending“API)。

其他选择是取消继承并支持组合。 A是一个包含对A_State类的引用的类。然后,您继承A_State

class A
{
    //public functions
    ...
    const A_State* getState(){ return m_poMyState; }
    void setState(const A_State const * aStateObj ){ m_poMyState = aStateObj; }
}

答案 1 :(得分:0)

您可以使用

等功能增强A界面
virtual bool hasSibling() const = 0;
virual int siblingNumber() const = 0;

然后,给定子类中的合适实现,B代码可以:

if (!aObj.hasSibling()) return;
A & otherObj = GetAObj(aObj.siblingNumber());
if (otherObj.isActive()) { ... }

如果你能将更多的逻辑推入A(在告诉不要求原则上)会更好,但是当GetAObj驻留在B上时,这可能会很棘手。