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那么我可以调用该项的方法而不关心它是什么类型,但如果我不希望在项目本身内发生这种区分,我该如何处理呢?)
在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)
我想我将使用控制反转和访问者模式的想法:
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)
| 归档时间: |
|
| 查看次数: |
9971 次 |
| 最近记录: |