假设我在Java中有一个类层次结构:
interface Item { ... };
class MusicBox implements Item { ... };
class TypeWriter implements Item { ... };
class SoccerBall implements Item { ... };
我在同一个包中有另一个类:
class SpecialItemProcessor {
public void add(Item item)
{
/* X */
}
}
我希望为每种项目类型执行不同的操作,但我不想在不同的Item
类中定义该操作(MusicBox
,TypeWriter
,{{1 }})。
处理此问题的一种方法是:
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
那么我可以调用该项的方法而不关心什么输入它,但如果我不希望在项目本身内发生差异化,我该如何处理呢?)
答案 0 :(得分: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
}
答案 1 :(得分:2)
我想我会使用控制反转和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);
}
}
}
然后执行以下操作,至少将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 */
}
}
答案 2 :(得分:0)
您可以为Item创建桥接模式,其中另一侧是调用add()时要执行的关联过程。您还可以在混合中添加工厂方法。
class SpecialItemProcessor {
public void add(Item item)
{
Process p = Item.createCorrespondingProcessor( p );
p.doWhenAddin();
}
}
希望这有帮助。
答案 3 :(得分:0)
为什么不为Item接口定义一些回调函数?
public Interface Item {
void onCallBack();
}
然后在每个实现Item的类中,比如MusicBox,它应该实现回调函数。
public class MusicBox {
@override
public void onCallBack() {
// business logic
...
...
}
}
然后你可以创建一个调度程序,你命名为" SpecialItemProcessor"。
public SpecialItemProcessor {
private final Item _item;
public SpecialItemProcessor(Item item) {
_item = item;
}
public dispatch() {
_item.onCallBack()
}
}
然后,在包含SpecialItemProcessor的Client类中,只需调用该方法,如:
public void XXXX() {
....
SpecialItemProcessor specialItemProcessor = new SpecialItemProcessor(new MusicBox());
specialItemProcessor.dispatch();
....
}
实际上,在C ++中,这是动态绑定。这就是纯抽象类存在的原因......