0

许多重复的 switch 语句似乎需要 DRY'd。有什么建议么?(包括什么都不做!)

AnimMapIter _iter;
    _iter = _animations->find(name);
    if(_iter == _animations->end()) return;

    if(_curName != name) {
        _curName = name;

        switch(dir) {
        case DIR_FORWARD_LOOPING: /* Fall through to DIR_FORWARD_NONLOOPING */
        case DIR_FORWARD_NONLOOPING:
            _iter->second->First();
            break;
        case DIR_REVERSE_LOOPING: /* Fall through to DIR_REVERSE_NONLOOPING */
        case DIR_REVERSE_NONLOOPING:
            _iter->second->Last();
            break;
        }
    } else {

        switch(dir) {
        case DIR_FORWARD_LOOPING: /* Fall through to DIR_FORWARD_NONLOOPING */
        case DIR_FORWARD_NONLOOPING:
            _iter->second->Next();
            break;
        case DIR_REVERSE_LOOPING: /* Fall through to DIR_REVERSE_NONLOOPING */
        case DIR_REVERSE_NONLOOPING:
            _iter->second->Previous();
            break;
        }

        switch(dir) {
            case DIR_FORWARD_LOOPING:
                if(_iter->second->IsAtEnd())
                    _iter->second->First();
                break;
            case DIR_FORWARD_NONLOOPING:
                if(_iter->second->IsAtEnd())
                    _iter->second->Last();
                break;
            case DIR_REVERSE_LOOPING:
                if(_iter->second->IsAtFront())
                    _iter->second->Last();
                break;
            case DIR_REVERSE_NONLOOPING:
                if(_iter->second->IsAtFront())
                    _iter->second->First();
                break;
        }
    }
4

2 回答 2

1

沿着这些思路将逻辑推入任何_iter->second内容(假设您已经显示的方法存在):

class WhateverItIs
{
public:
   void Start() { if (m_forward) First(); else Last(); }
   void Stop()  { if (m_forward) Last(); else First(); }
   void Advance()
   {
      if (m_forward)
         Next();
      else
         Previous();
      if (IsLast())
      {
         if (m_loop)
            Start();
         else
            Stop();
      }
   }

private:
   bool IsLast() const
   {
      return m_forward ? IsAtEnd() : IsAtFront();
   }
   // Direction and looping are independent concepts.    
   bool m_forward;
   bool m_loop;
};

然后你可以写:

AnimMapIter _iter;
_iter = _animations->find(name);
if(_iter == _animations->end()) return;

if(_curName != name) {
    _curName = name;
    _iter->second->Start();
} else {
    _iter->second->Advance();
}

编辑:使用自由函数并保持常量的示例。

   void Start(Strip* s, bool forward) 
        { if (forward) s->First(); else s->Last(); }
   void Stop(Strip* s, bool forward) 
        { if (forward) s->Last() else s->First(); }
   void Advance(Strip* s, bool forward, bool loop)
   {
      if (forward)
         s->Next();
      else
         s->Previous();
      if (IsLast(s, forward))
      {
         if (loop)
            Start(s);
         else
            Stop(s);
      }
   }

   bool IsLast(const Strip* s, bool forward) const
   {
      return forward ? s->IsAtEnd() : s->IsAtFront();
   } 

   bool Projector::IsForward() const
   { 
       return dir == DIR_FORWARD_LOOPING || dir == DIR_FORWARD_NONLOOPING; 
   }

   bool Projector::IsLooping() const
   {
       return dir == DIR_REVERSE_LOOPING || dir == DIR_FORWARD_LOOPING;
   }

    if(_curName != name) {
        _curName = name;
        Start(_iter->second, IsForward());
    } else {
        Advance(_iter->second, IsForward(), IsLooping());
    }
于 2012-07-04T22:34:28.863 回答
1

else 下的所有内容都应该折叠成一个开关,以使相关步骤更接近;例如

case DIR_FORWARD_LOOPING:
    _iter->second->Next();
    if (_iter->second->IsAtEnd()) {
        _iter->second->First();
    }
    break;

……都在那种情况下。重复几个函数调用并不是什么大问题,因为它可以使整个动作序列更加清晰。

于 2012-07-11T04:27:54.483 回答