Warning: file_get_contents(/data/phpspider/zhask/data//catemap/8/design-patterns/2.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
Java 调度设计模式?_Java_Design Patterns_Dispatch - Fatal编程技术网

Java 调度设计模式?

Java 调度设计模式?,java,design-patterns,dispatch,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) {

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

interface Item { ... };
class MusicBox implements Item { ... };
class TypeWriter implements Item { ... };
class SoccerBall implements Item { ... };
我在同一个包中还有另一个类:

class SpecialItemProcessor {
    public void add(Item item)
    {
        /* X */
    }
}
其中,我想为每种项目类型执行不同的操作,但不想在不同的
项目
类中定义该操作(
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 ...
        }
    }
}

这很管用,但看起来真的很笨重当我知道特殊情况时,有没有更好的方法来实现这一点?(显然,如果
Item
包含一个方法
doSomethingSpecial
,那么我可以调用该项的方法,而不管它是什么类型,但是如果我不希望在该项本身中出现这种差异,我该如何处理它?)

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

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

希望这能有所帮助。

在Java中,您可以使用访问者(-like)模式进行多次分派。项实现不需要包含处理逻辑,它们只需要
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
}

我想我将使用控制反转的思想,以及:

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

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

public Interface Item {
  void onCallBack();
}
然后在实现项的每个类中,例如MusicBox,它都应该实现回调函数

public class MusicBox {
  @override
  public void onCallBack() {
    // business logic
    ...
    ...  
  }
}
然后您可以创建一个调度程序,您将其命名为“SpecialItemProcessor”

然后,在包含SpecialItemProcessor的客户端类中,可以调用该方法,如:

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

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

我不知道答案,但在ActionScript3中,显然可以从字符串实例化一个类(即,'com.djw.MusicBox'可以实例化一个MusicBox),这种事情在Java中可能吗?只是一个建议@丹:
Class#forName()
。然而,我对这里的值表示怀疑。这是什么语法?在最初分配给它之前,您如何使用
p
?这不是PHP。。。正确版本:<代码> P.DohanyAddiin()/<代码>对不起,我终于抛出了一些C++语法。此源代码是Java。创建对应的处理器方法是一个工厂方法,它创建与处理器的类层次结构对应的适当类,链接到Items.Hmm的类层次结构。给了我一些想法,但是在您的代码中,接口项现在依赖于ItemProcessor,它依赖于MusicBox和SoccerBall类(因此不确定这是否会编译),它将编译,您可以在Java中的类之间具有交叉依赖性。但是,您不能在.jar之间有corss依赖关系,因此如果Item和ItemProcessor在不同的.jar中,它将不起作用。@Jason:是的,它编译:)这只是一种翻转事物的方式,而不是使用一个方法来尝试如何处理特定类型的项,您可以让不同类型的项将它们自己传递给具有它们的处理的方法。编译时耦合的好处在于,如果在应用程序中的很多地方都有if else instanceof block,那么在创建新的项类型时,要比在它们都实现更改的接口时更容易错过更新。请阅读以下问题:“我想对每种项目类型执行不同的操作,但不想在不同的项目类(MusicBox、TypeWriter、SoccerBall)中定义该操作。”
public SpecialItemProcessor {
  private final Item _item;

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

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