Java 调度设计模式?
假设我在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) {
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();
....
}