之前写代码的时候看到同一个class中用内部接口实现各种业务操作的例子,感到很新奇,就尝试着自己写一下
自编自导了一个吃喝嫖赌的场景:假设做吃喝嫖赌四个操作的时候,都需要先挣钱,然后点单,然后享用,然后结算。除了挣钱这个操作,是独立于吃喝嫖赌本身,有共通性,点、品、结三个动作在不同场景下区别很大,所以需要各自不同的实现
先用最土的方法实现
public class CommonApproach {
public void eat() {
earn();
orderForEat();
enjoyForEat();
checkoutForEat();
}
public void drink() {
earn();
orderForDrink();
enjoyForDrink();
checkoutForDrink();
}
public void prostitute() {
earn();
orderForProstitute();
enjoyForProstitute();
checkoutForProstitute();
}
public void gamble() {
earn();
orderForGamble();
enjoyForGamble();
checkoutForGamble();
}
private void earn() {
}
private void orderForEat() {
}
private void enjoyForEat() {
}
private void checkoutForEat() {
}
private void orderForDrink() {
}
private void enjoyForDrink() {
}
private void checkoutForDrink() {
}
private void orderForProstitute() {
}
private void enjoyForProstitute() {
}
private void checkoutForProstitute() {
}
private void orderForGamble() {
}
private void enjoyForGamble() {
}
private void checkoutForGamble() {
}
}
明显过于繁琐,不会写代码的看了都会觉得很累赘,那么再试着用abstract类继承的方式实现,由于这里要求在一个class里完成,那么就用私有内部类来搞一下:
public class AbstractApproach {
private DoEDPG behaviour;
public void eat() {
behaviour = new DoEDPG() {
@Override
protected void order() {
JoePrint.print("order food");
}
@Override
protected void enjoy() {
JoePrint.print("enjoy the food");
}
@Override
protected void checkout() {
JoePrint.print("pay for the food");
}
};
behaviour.earn();
behaviour.order();
behaviour.enjoy();
behaviour.checkout();
}
public void drink() {
behaviour = new DoEDPG() {
@Override
protected void order() {
JoePrint.print("order drink");
}
@Override
protected void enjoy() {
JoePrint.print("enjoy liquid");
}
@Override
protected void checkout() {
JoePrint.print("pay for the liquid");
}
};
behaviour.earn();
behaviour.order();
behaviour.enjoy();
behaviour.checkout();
}
public void prostitute() {
behaviour = new DoEDPG() {
@Override
protected void order() {
JoePrint.print("order someone or several");
}
@Override
protected void enjoy() {
JoePrint.print("enjoy with him/her/them");
}
@Override
protected void checkout() {
JoePrint.print("pay for him/her/them");
}
};
behaviour.earn();
behaviour.order();
behaviour.enjoy();
behaviour.checkout();
}
public void gamble() {
behaviour = new DoEDPG() {
@Override
protected void order() {
JoePrint.print("order token");
}
@Override
protected void enjoy() {
JoePrint.print("gamble");
}
@Override
protected void checkout() {
JoePrint.print("checkout");
}
};
behaviour.earn();
behaviour.order();
behaviour.enjoy();
behaviour.checkout();
}
private abstract class DoEDPG {
protected void earn() {
JoePrint.print("earn money");
}
abstract protected void order();
abstract protected void enjoy();
abstract protected void checkout();
}
}
然后用接口实现,也是我认为在同一个class内部实现的最简洁方式:
public class InterfaceApproach {
public void eat() {
doEDPG(new IDo() {
@Override
public void order() {
JoePrint.print("order food");
}
@Override
public void enjoy() {
JoePrint.print("enjoy the food");
}
@Override
public void checkout() {
JoePrint.print("pay for the food");
}
});
}
public void drink() {
doEDPG(new IDo() {
@Override
public void order() {
JoePrint.print("order drink");
}
@Override
public void enjoy() {
JoePrint.print("enjoy liquid");
}
@Override
public void checkout() {
JoePrint.print("pay for the liquid");
}
});
}
public void prostitute() {
doEDPG(new IDo() {
@Override
public void order() {
JoePrint.print("order someone or several");
}
@Override
public void enjoy() {
JoePrint.print("enjoy with him/her/them");
}
@Override
public void checkout() {
JoePrint.print("pay for him/her/them");
}
});
}
public void gamble() {
doEDPG(new IDo() {
@Override
public void order() {
JoePrint.print("order token");
}
@Override
public void enjoy() {
JoePrint.print("gamble");
}
@Override
public void checkout() {
JoePrint.print("checkout");
}
});
}
private void doEDPG(IDo iDo) {
earn();
iDo.order();
iDo.enjoy();
iDo.checkout();
}
private void earn() {
JoePrint.print("earn money");
}
private interface IDo {
void order();
void enjoy();
void checkout();
}
}
当然这里讨论的场景很狭隘,至于接口和抽象方法在策略模式下的优劣长短,需要在以后的工作中继续体会