设计建议:更改 class 行为
Design suggestion: Changing the class behaviour
下面我试着用一个例子来解释这个问题。
我们有一个Caller.java
Caller.java :调用一系列Actor按顺序执行某些步骤。
Actor.java : 摘要 class 包含 action() 方法
ActorOne.java : 实现 action() 方法
ActorTwo.java : 实现 action() 方法
ActorThree.java : 实现 action() 方法
在运行时,根据要完成的任务,在 Caller.java 中准备了 classes 的集合,并使用反射实例化。
Actor.java: callActions(){
Class[] classes = [ActorOne.class, ActorTwo.class]
for(Class clazz : classes){
Actor actor = (Actor) clazz.newInstance();
actor.action();
}
}
在某些情况下,我知道 callActions.java 内的运行时,我需要通知 ActorTwo 以不同的方式执行操作方法。
我的解决方案是使用反射 API 将该标志传递给 ActorTwo 对象,并在 action() 方法中放置 if/else 以执行特定于标志的操作。
是否有更好的方法来设计解决方案,以便我可以避免 ActorTwo.action() 方法中的 if/else?
此致
您的界面上可以有两种方法。 ActorOne 和 ActorThree 会将一种方法的实现委托给另一种方法(也许抽象超级 class 会这样做)。 ActorTwo 会做一些不同的事情。
您可以使用不同的方法创建另一个接口,让 ActorTwo 实现它,并在运行时检查您的对象是否支持它
if(inSpecialCase && actor instanceof Actor2) {
((Actor2)actor).specialMethod()
Eclipse 与第二个建议非常相似,以保持可扩展性和兼容性(随着时间的推移会创建新接口,并且行为会根据代码支持的级别进行调整)。
另一种选择是让 action()
方法接受一个参数数组(就像 main(...)
那样)。这样 ActorTwo 就可以检查参数以查看它是否属于特殊情况,而其他 Actor 可以忽略输入。
public abstract class Actor{
public abstract void action(String[] args);
}
public class Actor2 extends Actor{
public void action(String[] args){
if(args != null && args.length > 0 && args[0].equals("SPECIAL_CASE"){
//Do special case things
} else {
//Do regular case things
}
}
}
这种形式为您提供了最大的灵活性,可以向任何参与者添加额外的案例。
使用多态性。在你的 ActorTwo.java 中再定义一个方法,称为 action(flag),然后在这个方法中实现新的行为。当你不想传递标志时,应该调用正常的 action() 。当你想传递标志时,在运行时,你应该调用 action(flag).
忠告,尽可能避免反射。它减慢了执行速度。如果您的代码无法避免反射,那也没关系。
下面我试着用一个例子来解释这个问题。
我们有一个Caller.java
Caller.java :调用一系列Actor按顺序执行某些步骤。
Actor.java : 摘要 class 包含 action() 方法
ActorOne.java : 实现 action() 方法
ActorTwo.java : 实现 action() 方法
ActorThree.java : 实现 action() 方法
在运行时,根据要完成的任务,在 Caller.java 中准备了 classes 的集合,并使用反射实例化。
Actor.java: callActions(){
Class[] classes = [ActorOne.class, ActorTwo.class]
for(Class clazz : classes){
Actor actor = (Actor) clazz.newInstance();
actor.action();
}
}
在某些情况下,我知道 callActions.java 内的运行时,我需要通知 ActorTwo 以不同的方式执行操作方法。
我的解决方案是使用反射 API 将该标志传递给 ActorTwo 对象,并在 action() 方法中放置 if/else 以执行特定于标志的操作。
是否有更好的方法来设计解决方案,以便我可以避免 ActorTwo.action() 方法中的 if/else?
此致
您的界面上可以有两种方法。 ActorOne 和 ActorThree 会将一种方法的实现委托给另一种方法(也许抽象超级 class 会这样做)。 ActorTwo 会做一些不同的事情。
您可以使用不同的方法创建另一个接口,让 ActorTwo 实现它,并在运行时检查您的对象是否支持它
if(inSpecialCase && actor instanceof Actor2) {
((Actor2)actor).specialMethod()
Eclipse 与第二个建议非常相似,以保持可扩展性和兼容性(随着时间的推移会创建新接口,并且行为会根据代码支持的级别进行调整)。
另一种选择是让 action()
方法接受一个参数数组(就像 main(...)
那样)。这样 ActorTwo 就可以检查参数以查看它是否属于特殊情况,而其他 Actor 可以忽略输入。
public abstract class Actor{
public abstract void action(String[] args);
}
public class Actor2 extends Actor{
public void action(String[] args){
if(args != null && args.length > 0 && args[0].equals("SPECIAL_CASE"){
//Do special case things
} else {
//Do regular case things
}
}
}
这种形式为您提供了最大的灵活性,可以向任何参与者添加额外的案例。
使用多态性。在你的 ActorTwo.java 中再定义一个方法,称为 action(flag),然后在这个方法中实现新的行为。当你不想传递标志时,应该调用正常的 action() 。当你想传递标志时,在运行时,你应该调用 action(flag).
忠告,尽可能避免反射。它减慢了执行速度。如果您的代码无法避免反射,那也没关系。