java 调度设计模式?

声明:本页面是StackOverFlow热门问题的中英对照翻译,遵循CC BY-SA 4.0协议,如果您需要使用它,必须同样遵循CC BY-SA许可,注明原文地址和作者信息,同时你必须将它归于原作者(不是我):StackOverFlow 原文地址: http://stackoverflow.com/questions/3672091/
Warning: these are provided under cc-by-sa 4.0 license. You are free to use/share it, But you must attribute it to the original authors (not me): StackOverFlow

提示:将鼠标放在中文语句上可以显示对应的英文。显示中英文
时间:2020-10-30 02:57:12  来源:igfitidea点击:

dispatch design pattern?

javadesign-patternsdispatch

提问by Jason S

Suppose I have a class hierarchy in Java:

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

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

and I have another class in the same package:

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

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

where I want to do something different for each item type, but I don't want to define that action in the different Itemclasses (MusicBox, TypeWriter, SoccerBall).

我想为每个项目类型做一些不同的事情,但我不想在不同的Item类 ( MusicBox, TypeWriter, SoccerBall) 中定义该操作。

One way to handle this is:

处理这种情况的一种方法是:

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 ...
        }
    }
}

This works but it seems really clunky. Is there a better way to do this, when I know of special cases?(obviously if Itemcontains a method doSomethingSpecialthen I can just call that item's method without caring what type it is, but if I don't want that differentiation to occur within the item itself how do I deal with it?)

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

采纳答案by Jason S

I think I'm going to use the idea of inversion of control and the 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);
      }
   }
}

and then do the following, which at least reduces the instanceofto one check per add()call:

然后执行以下操作,这至少将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 */
    }
 }

回答by Affe

In Java you can do multiple dispatch with a visitor(-like) pattern. The Item implementations don't need to contain the processing logic, they just need an accept()type of method.

在 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
}

回答by Cherish

Why not define some callback function to Item interface?

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

public Interface Item {
  void onCallBack();
}

Then in each class that implements Item, such as MusicBox, it should implement the callback function.

那么在每个实现Item的类中,比如MusicBox,都应该实现回调函数。

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

Then you could create a dispatcher, which you name is "SpecialItemProcessor".

然后您可以创建一个调度程序,您将其命名为“SpecialItemProcessor”。

public SpecialItemProcessor {
  private final Item _item;

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

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

And then, in the Client class which contains the SpecialItemProcessor could just call the method, like:

然后,在包含 SpecialItemProcessor 的 Client 类中可以调用该方法,例如:

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

Actually, in C++, this is Dynamic Binding. And this is why pure abstract class exists...

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

回答by Baltasarq

You could create a bridge pattern for Item, in which the other side were the associated processes to do when add() is called. You could also add a factory method to the mix.

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

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

Hope this helps.

希望这可以帮助。