调度设计模式?

时间:2010-09-08 21:36:07

标签: java design-patterns dispatch

假设我在Java中有一个类层次结构:

interface Item { ... };
class MusicBox implements Item { ... };
class TypeWriter implements Item { ... };
class SoccerBall implements Item { ... };

我在同一个包中有另一个类:

class SpecialItemProcessor {
    public void add(Item item)
    {
        /* X */
    }
}

我希望为每种项目类型执行不同的操作,但我不想在不同的Item类中定义该操作(MusicBoxTypeWriter,{{1 }})。

处理此问题的一种方法是:

SoccerBall

这有效,但看起来真的很笨重。 当我知道特殊情况时,有没有更好的方法呢?(显然如果class SpecialItemProcessor { public void add(Item item) { if (item instanceof MusicBox) { MusicBox musicbox = (MusicBox)item; ... do something ... } else if (item instanceof MusicBox) { TypeWriter typewriter = (TypeWriter)item; ... do something ... } else if (item instanceof SoccerBall) { SoccerBall soccerball = (SoccerBall)item; ... do something ... } else { ... do something by default ... } } } 包含方法Item那么我可以调用该项的方法而不关心什么输入它,但如果我不希望在项目本身内发生差异化,我该如何处理呢?)

4 个答案:

答案 0 :(得分:7)

在Java中,您可以使用访问者(类似)模式进行多次调度。 Item实现不需要包含处理逻辑,只需要accept()类型的方法。

public interface Item {
/** stuff **/

void processMe(ItemProcessor processor);

}

public interface ItemProcessor {

void process(MusicBox box);

void process(SoccerBall ball);

//etc

}

public class MusicBox implements Item {

  @Override
  public void processMe(ItemProcessor processor) {
    processor.process(this);
  }

}

public class ItemAddingProcessor implements ItemProcessor {

  public void add(Item item) {
    item.processMe(this);
  }

  @Override
  public void process(MusicBox box) {
    //code for handling MusicBoxes
    //what would have been inside if (item instanceof MusicBox) {}
  }

//etc
}

答案 1 :(得分:2)

我想我会使用控制反转和visitor pattern的想法:

interface Item { 
   public void accept(Visitor visitor);
   ... 

   public interface Visitor {
      public void visit(Item item);
   }
}


class MusicBox implements Item { 
   public interface Visitor extends Item.Visitor {
      public void visitMusicBox(MusicBox item);
   }
   ... 
   @Override public accept(Item.Visitor visitor)
   {
      if (visitor instanceof MusicBox.Visitor)
      {
          ((MusicBox.Visitor)visitor).visitMusicBox(this);
      }
   }
}

class TypeWriter implements Item { 
   public interface Visitor extends Item.Visitor {
      public void visitTypeWriter(TypeWriter item);
   }
   ... 
   @Override public accept(Item.Visitor visitor)
   {
      if (visitor instanceof TypeWriter.Visitor)
      {
          ((TypeWriter.Visitor)visitor).visitTypeWriter(this);
      }
   }
}

class SoccerBall implements Item { 
   public interface Visitor extends Item.Visitorr {
      public void visitSoccerBall(SoccerBall item);
   }
   ... 
   @Override public accept(Item.Visitor visitor)
   {
      if (visitor instanceof SoccerBall.Visitor)
      {
          ((SoccerBall.Visitor)visitor).visitSoccerBall(this);
      }
   }
}

然后执行以下操作,至少将instanceof减少到每add()次调用一次检查:

 class SpecialItemProcessor 
    implements 
       MusicBox.Visitor, 
       TypeWriter.Visitor, 
       SoccerBall.Visitor, 
       Item.Visitor
 {
    public void add(Item item)
    {
        item.accept(this);
    }
    @Override public void visitMusicBox(MusicBox item)
    {
        ...
    }
    @Override public void visitTypeWriter(TypeWriter item)
    {
        ...
    }
    @Override public void visitSoccerBall(SoccerBall item)
    {
        ...
    }
    @Override public void visit(Item item)
    {
        /* not sure what if anything I should do here */
    }
 }

答案 2 :(得分:0)

您可以为Item创建桥接模式,其中另一侧是调用add()时要执行的关联过程。您还可以在混合中添加工厂方法。

class SpecialItemProcessor {
  public void add(Item item)
  {
     Process p = Item.createCorrespondingProcessor( p );
     p.doWhenAddin();
  }
}

希望这有帮助。

答案 3 :(得分:0)

为什么不为Item接口定义一些回调函数?

public Interface Item {
  void onCallBack();
}

然后在每个实现Item的类中,比如MusicBox,它应该实现回调函数。

public class MusicBox {
  @override
  public void onCallBack() {
    // business logic
    ...
    ...  
  }
}

然后你可以创建一个调度程序,你命名为" SpecialItemProcessor"。

public SpecialItemProcessor {
  private final Item _item;

  public SpecialItemProcessor(Item item) {
    _item = item;
  }

  public dispatch() {
    _item.onCallBack()
  }
}

然后,在包含SpecialItemProcessor的Client类中,只需调用该方法,如:

public void XXXX() {
  ....
  SpecialItemProcessor specialItemProcessor = new SpecialItemProcessor(new MusicBox());
  specialItemProcessor.dispatch();
  ....
}

实际上,在C ++中,这是动态绑定。这就是纯抽象类存在的原因......