Java中的条件分支
我想知道你认为哪一个设计更好。如果我们有Java中的条件分支,java,if-statement,switch-statement,Java,If Statement,Switch Statement,我想知道你认为哪一个设计更好。如果我们有 /* * Created 21 Feb 2014 */ import java.util.Properties; import java.util.Random; /** * * @author me */ enum EventType{ TRADE, RISK, SHIPPING, MARGIN, STOP_LOSS, TAKE_PROFIT } interface Event{ EventType getType();
/*
* Created 21 Feb 2014
*/
import java.util.Properties;
import java.util.Random;
/**
*
* @author me
*/
enum EventType{
TRADE, RISK, SHIPPING, MARGIN, STOP_LOSS, TAKE_PROFIT
}
interface Event{
EventType getType();
Properties getProperties();
}
class ShippingEvent implements Event{
public final static String PROPERTY_KEY1 = "property_ke1";
public final static String PROPERTY_KEY2 = "property_ke2";
public final static String PROPERTY_KEY3 = "property_ke3";
@Override
public EventType getType() {
return EventType.SHIPPING;
}
@Override
public Properties getProperties() {
throw new UnsupportedOperationException("Not supported yet.");
}
}
class TradeEvent implements Event{
public final static String PROPERTY_KEY1 = "property_ke1";
public final static String PROPERTY_KEY2 = "property_ke2";
public final static String PROPERTY_KEY3 = "property_ke3";
@Override
public EventType getType() {
return EventType.TRADE;
}
@Override
public Properties getProperties() {
throw new UnsupportedOperationException("Not supported yet.");
}
}
class RiskEvent implements Event{
public final static String PROPERTY_KEY1 = "property_ke1";
public final static String PROPERTY_KEY2 = "property_ke2";
public final static String PROPERTY_KEY3 = "property_ke3";
@Override
public EventType getType() {
return EventType.RISK;
}
@Override
public Properties getProperties() {
throw new UnsupportedOperationException("Not supported yet.");
}
}
class MarginEvent implements Event{
public final static String PROPERTY_KEY1 = "property_ke1";
public final static String PROPERTY_KEY2 = "property_ke2";
public final static String PROPERTY_KEY3 = "property_ke3";
@Override
public EventType getType() {
return EventType.MARGIN;
}
@Override
public Properties getProperties() {
throw new UnsupportedOperationException("Not supported yet.");
}
}
class StopLossEvent implements Event{
public final static String PROPERTY_KEY1 = "property_ke1";
public final static String PROPERTY_KEY2 = "property_ke2";
public final static String PROPERTY_KEY3 = "property_ke3";
@Override
public EventType getType() {
return EventType.STOP_LOSS;
}
@Override
public Properties getProperties() {
throw new UnsupportedOperationException("Not supported yet.");
}
}
class TakeProfiEvent implements Event{
public final static String PROPERTY_KEY1 = "property_ke1";
public final static String PROPERTY_KEY2 = "property_ke2";
public final static String PROPERTY_KEY3 = "property_ke3";
@Override
public EventType getType() {
return EventType.TAKE_PROFIT;
}
@Override
public Properties getProperties() {
throw new UnsupportedOperationException("Not supported yet.");
}
}
public class InstanceOfTest {
private static void testIfBranch(final Event event){
if (event instanceof TakeProfiEvent){
System.out.println("TakeProfiEvent");
}else if (event instanceof StopLossEvent){
System.out.println("StopLossEvent");
}else if (event instanceof MarginEvent){
System.out.println("MarginEvent");
}else if (event instanceof RiskEvent){
System.out.println("RiskEvent");
}else if (event instanceof TradeEvent){
System.out.println("TradeEvent");
}else if (event instanceof ShippingEvent){
System.out.println("ShippingEvent");
}
}
private static void testSwitchBranch(final Event event){
switch(event.getType()){
case TRADE:
System.out.println("TradeEvent");
break;
case RISK:
System.out.println("RiskEvent");
break;
case SHIPPING:
System.out.println("ShippingEvent");
break;
case MARGIN:
System.out.println("MarginEvent");
break;
case STOP_LOSS:
System.out.println("StopLossEvent");
break;
case TAKE_PROFIT:
System.out.println("TakeProfiEvent");
break;
default:
break;
}
}
public static void main(String[] args){
Event[] events = new Event[] {
new TakeProfiEvent(),
new StopLossEvent(),
new MarginEvent(),
new RiskEvent(),
new TradeEvent(),
new ShippingEvent()
};
Random random = new Random(System.currentTimeMillis());
long start = System.currentTimeMillis();
for(int idx=0; idx<10000000; ++idx){
int jdx = random.nextInt(events.length-1);
//testIfBranch(events[jdx]);
testSwitchBranch(events[jdx]);
}
long end = System.currentTimeMillis();
System.out.println("Time taken: " + (end - start));
}
}
就我从剥离的示例中所见,这两种方法在软件工程方面都不是真正的可扩展和易于维护的 重要的问题是:您在实际应用程序中如何处理这些事件(及其类型)?即:是否确实需要查询类型
在这种情况下,至少应该考虑的一般模式是用某种多态性隐藏类型查询。要以过于暗示的形式指出这一点:
interface Event{
void performAction();
Properties getProperties();
}
class ShippingEvent implements Event{
@Override
public void performAction() {
// Whatever you would otherwise do based on the event type:
System.out.println("ShippingEvent");
}
....
}
private static void testPolymorphism(final Event event){
event.performAction(); // That's it. No type queries here.
}
但是从发布的代码中很难判断这是否(以及如何)适用于您的情况……就我从剥离的示例中所看到的情况而言,从软件工程的角度来看,这两种方法都不是真正可扩展且易于维护的 重要的问题是:您在实际应用程序中如何处理这些事件(及其类型)?即:是否确实需要查询类型
在这种情况下,至少应该考虑的一般模式是用某种多态性隐藏类型查询。要以过于暗示的形式指出这一点:
interface Event{
void performAction();
Properties getProperties();
}
class ShippingEvent implements Event{
@Override
public void performAction() {
// Whatever you would otherwise do based on the event type:
System.out.println("ShippingEvent");
}
....
}
private static void testPolymorphism(final Event event){
event.performAction(); // That's it. No type queries here.
}
但是这是否(以及如何)适用于您的情况,很难从发布的代码中判断…最好的设计无疑是开关式的。有关最佳实践,请参阅
最好的设计无疑是开关式的。有关最佳实践,请参阅
本例中的性能参数与if vs switch没有多大关系,因为您在它们中做的事情不同。您的if正在测试类是否属于特定类型,而您的交换机正在检查枚举相等性 此外,在设计方面,你提供的信息很少,所以很难对什么更好做出任何判断。如果您提供了一些信息,说明为什么要做这些条件语句,以及您希望在每个分支上做些什么,这将是使讨论变得更好的良好的第一步
就最佳实践而言,您希望避免如此长的if/else构造或switch语句,并根据您的情况采用多态性之类的解决方案。本例中的性能参数与if vs switch没有太多关系,因为您在它们中做的事情不同。您的if正在测试类是否属于特定类型,而您的交换机正在检查枚举相等性 此外,在设计方面,你提供的信息很少,所以很难对什么更好做出任何判断。如果您提供了一些信息,说明为什么要做这些条件语句,以及您希望在每个分支上做些什么,这将是使讨论变得更好的良好的第一步
就最佳实践而言,您希望避免如此长的if/else构造或switch语句,并根据您的情况采用多态性等解决方案。两者之间的性能差异可以忽略不计;选择一个更容易理解和管理的开关(无论如何看起来像
开关
变体)。枚举开关通常编译为一个O(1)表开关
,除非您只有一个带有稀疏序数的枚举值子集的案例,在这种情况下,您可能会得到一个O(logn)查找开关
(但大多数编译器将保证使用表开关
)。无论哪种方式,它都比O(n)直链的if/else if
语句要好。两者之间的性能差异可以忽略不计;选择一个更易于理解和管理的开关(不管怎样,它看起来像开关
变体).enum开关通常编译为O(1)表开关
,除非只有带有稀疏序数的enum值子集的case,在这种情况下,您可能会得到一个O(logn)查找开关
(但大多数编译器将保证表开关
)。无论哪种方式,它都比O(n)好if/else if
语句的直链。本文没有提出开关
解决方案(而是提出多态性,如我在中所述)诚然,我没有解释代码的目的,只是比较了两种方法。为了更彻底一点,如果事件部分以Swing为中心,我建议阅读优秀的java事件。我还建议检查。希望我能提供一些帮助!本文没有提出开关
解决方案(相反,它提出了多态性,正如我在中提到的)是的,我没有解释代码的目的,只是比较了两种方法。为了更彻底一点,如果事件部分以Swing为中心,我建议阅读优秀java事件。我还建议检查。希望我能提供一些帮助!不能更同意你。不能更同意你。