我应该使用多态而不是条件,但是我可以在下面的情况下使用吗?
下面的代码根据jsonObject的内容返回一个Screen对象。
public static Screen getNextScreen(){
JSONObject jsonObject = RatingsUtils.getCurrentJsonObjectFromServer();
if(isNextProgramScreen(jsonObject)) {
ParentRatingsObject parentRatingsObject = JsonBusinessObjectFactory.createParentRatingsObject(jsonObject);
return new NextProgramScreen(parentRatingsObject);
}
else if(isTimerScreen(jsonObject)) {
ChildWithParentRatingsObject childWithParentRatingsObject = JsonBusinessObjectFactory.createChildWithParentRatingsObject(jsonObject);
return new TimerScreen(childWithParentRatingsObject);
}
else if(isNextContestantPreJudgeScreen(jsonObject)) {
ChildWithParentRatingsObject childWithParentRatingsObject = JsonBusinessObjectFactory.createChildWithParentRatingsObject(jsonObject);
return new NextContestantPreJudgingScreen(childWithParentRatingsObject);
}
else if(isNextContestantJudgeScreen(jsonObject)) {
ChildWithParentRatingsObject childWithParentRatingsObject = JsonBusinessObjectFactory.createChildWithParentRatingsObject(jsonObject);
return new TimerScreen(childWithParentRatingsObject);
}
else {
return null;
}
}
答案 0 :(得分:4)
绝对。我自己一直在更多地采用多态方法,我真的很喜欢它。由于Java语言,这看起来有点臃肿。我们确实需要lambda表达式来正确执行此操作!
private static List<ScreenProvider> screenProviders = screenProviders();
public static Screen getNextScreen(JSONObject jsonObject) {
for (ScreenProvider screenProvider : screenProviders) {
if (screenProvider.supports(jsonObject)) {
return screenProvider.getScreen(jsonObject);
}
}
return null;
}
interface ScreenProvider {
boolean supports(JSONObject jsonObject);
Screen getScreen(JSONObject jsonObject);
}
private static List<ScreenProvider> screenProviders() {
return Arrays.asList(
new ScreenProvider() {
public boolean supports(JSONObject jsonObject) {
return isNextProgramScreen(jsonObject);
}
public Screen getScreen(JSONObject jsonObject) {
ParentRatingsObject parentRatingsObject = JsonBusinessObjectFactory.createParentRatingsObject(jsonObject);
return new NextProgramScreen(parentRatingsObject);
}
},
new ScreenProvider() {
public boolean supports(JSONObject jsonObject) {
return isTimerScreen(jsonObject);
}
public Screen getScreen(JSONObject jsonObject) {
ChildWithParentRatingsObject childWithParentRatingsObject = JsonBusinessObjectFactory.createChildWithParentRatingsObject(jsonObject);
return new TimerScreen(childWithParentRatingsObject);
}
},
new ScreenProvider() {
public boolean supports(JSONObject jsonObject) {
return isNextContestantPreJudgeScreen(jsonObject);
}
public Screen getScreen(JSONObject jsonObject) {
ChildWithParentRatingsObject childWithParentRatingsObject = JsonBusinessObjectFactory.createChildWithParentRatingsObject(jsonObject);
return new NextContestantPreJudgingScreen(childWithParentRatingsObject);
}
},
new ScreenProvider() {
public boolean supports(JSONObject jsonObject) {
return isNextContestantJudgeScreen(jsonObject);
}
public Screen getScreen(JSONObject jsonObject) {
ChildWithParentRatingsObject childWithParentRatingsObject = JsonBusinessObjectFactory.createChildWithParentRatingsObject(jsonObject);
return new TimerScreen(childWithParentRatingsObject);
}
}
);
}
这种方法的一大好处是getNextScreen()方法的简单性。通过一些思考,有可能使screenProviders()方法更紧凑 - 可能通过添加一个实现ScreenProvider的抽象类并拉出一些工作。
答案 1 :(得分:3)
在某个地方,您必须确定您的JSON对象是否代表特定类型的屏幕。因此,您必须在某处进行if
次比较。就多态性而言,我对工厂方法没有太大的改进,但是你可以提供一些实用方法,它将屏幕类型作为枚举返回并用它构建switch
语句。它可能看起来更好一些。但它的总体改进价值将受到限制。
答案 2 :(得分:1)
编辑:我完全改变了@Mike Deck建议的答案。
使用Enum和多态:
public Enum ScreenType {
NEXT_PROGRAM() {
@Override public ScreenType generateScreen() {
ParentRatingsObject parentRatingsObject = JsonBusinessObjectFactory.createChildWithParentRatingsObject(jsonObject);
return new NextProgramScreen(parentRatingsObject);
}
},
TIMER() {@Override...},
NEXT_CONSTESTANT_PREJUDGE() {@Override...},
NEXT_CONSTESTANT_JUDGE() {@Override...};
public static ScreenType getScreenType(JSONObject jsonObject) {
// basically rewrite your methods isXXXXXXX(jsonObject) here
}
public abstract Screen generateScreen();
}
在原始方法中基本上没有什么可做的:
public Screen generateScreen() {
JSONObject jsonObject = RatingsUtils.getCurrentJsonObjectFromServer();
ScreenType screenType = ScreenType.getScreenType(jsonObject));
return screenType.generateScreen();
}