调度设计模式?

Jas*_*n S 5 java design-patterns dispatch

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

interface Item { ... };
class MusicBox implements Item { ... };
class TypeWriter implements Item { ... };
class SoccerBall implements Item { ... };
Run Code Online (Sandbox Code Playgroud)

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

class SpecialItemProcessor {
    public void add(Item item)
    {
        /* X */
    }
}
Run Code Online (Sandbox Code Playgroud)

在这里我想做点什么各个项目类型的不同,但我不想定义动作在不同的Item类(MusicBox,TypeWriter,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 ...
        }
    }
}
Run Code Online (Sandbox Code Playgroud)

这有效,但看起来真的很笨重.当我知道特殊情况时,有更好的方法吗?(显然如果Item包含一个方法,doSomethingSpecial那么我可以调用该项的方法而不关心它是什么类型,但如果我不希望在项目本身内发生这种区分,我该如何处理呢?)

Aff*_*ffe 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
}
Run Code Online (Sandbox Code Playgroud)


Jas*_*n S 4

我想我将使用控制反转和访问者模式的想法:

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);
      }
   }
}
Run Code Online (Sandbox Code Playgroud)

然后执行以下操作,这至少将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 */
    }
 }
Run Code Online (Sandbox Code Playgroud)