2010-08-26 72 views
2

什么是最好的(最紧凑)的方式来处理这种情况: 方法调用的一个或多个参数取决于某些条件,而其余参数是相同的?条件参数的紧凑Java语法?

对于example--要

DeathRay mynewWpn = new DeathRay(particle.proton, chassisColor.BLACK, oem.ACME) 

如果

enemy_composition == nature.ANTIMATTER 

DeathRay mynewWpn = new DeathRay(particle.anti-proton, chassisColor.BLACK, oem.ACME) 

如果

enemy_composition == nature.MATTER 

显然你可以if-else,但是当有很多参数或多个条件参数时,它看起来不必要的长。我也已经做了这个事先创建了一个参数if-else,然后调用该方法。再次,这似乎有点笨重。是否有某种类似于Excel if语句的内联语法?

+0

'Excel if-statement'是什么? – 2010-08-26 04:31:25

回答

4

你可以做

new DeathRay(enemy_composition == nature.ANTIMATTER ? particle.proton : particle.anti-proton, chassisColor.BLACK, oem.ACME) 

…但我认为我们都可以认同这很可怕。它也假定只有两种粒子。

这里有一些更好的选择。

switch

particle type; 
switch (enemy_composition) { /* Assuming "nature" is an enum. */ 
    case ANTIMATTER : 
    type = particle.proton; 
    break; 
    case MATTER : 
    type = particle.antiproton; 
    break; 
} 
DeathRay mynewWpn = new DeathRay(type, chassisColor.BLACK, oem.ACME); 

enum方法:

添加一个方法你enumNature

public enum Nature 
{ 

    MATTER 
    { 
    public Particle getCounterWeapon() 
    { 
     return Particle.ANTIPROTON; 
    } 
    }, 
    ANTIMATTER 
    { 
    public Particle getCounterWeapon() 
    { 
     return Particle.PROTON; 
    } 
    }; 

    public abstract Particle getCounterWeapon(); 

} 

然后使用它。

DeathRay mynewWpn = new DeathRay(enemy_composition.getCounterWeapon(), chassisColor.BLACK, oem.ACME); 

Map

particle type = counterWeapons.get(enemy_composition); 
DeathRay mynewWpn = new DeathRay(type, chassisColor.BLACK, oem.ACME); 
+1

将参数传递给枚举构造函数可能会更简单,而不是定义3次相同的方法。但无论如何goog答案,+1 – 2010-08-26 04:56:16

+0

是的,在这种情况下,它会。只是想展示如何为每个枚举实例编写完全不同的方法。 – erickson 2010-08-26 16:08:45

1

您可以使用MAP 和命令模式 来避免if-else

对于eexample

Map<EnemyCompositionEnum,DeathRay> weapons = new HashMap<EnemyCompositionEnum,DeathRay>(); 

weapons.put(EnemyCompositionEnum.ANTIMATTER, new DeathRay(particle.proton,BLACK,oem.ACME)); 
weapons.put(EnemyCompositionEnum.MATTER, new DeathRay(particle.anti-proton,BLACK,oem.ACME)); 

,然后用它

DeathRay weapon = weapons.get(enemy.composition); 

更新

好吧,我才意识到什么通过阅读其他的答案的Excel三元运算符。

+0

我喜欢它,虽然这可能是一个过度杀伤比较:?对于这个简单的例子,我可以看到很多情况下,这将派上用场。我不知道你可以把这些东西放在地图的值域中。谢谢 – Pete 2010-08-26 04:45:03

+0

@Pete小心,?:是“Elvis”操作符,可在Groovy和Spring EL中使用。你可能在谈论三元运算符a? b:c。 http://groovy.codehaus.org/Operators – 2010-08-26 05:02:01

+0

在Java环境中,?:是一种完全合理的方式来引用三元运算符。 – 2010-08-26 05:34:40

2

是的,这就是所谓的三元运算符?:

DeathRay mynewWpn = new DeathRay(
    enemy_composition == nature.ANTIMATTER ? particle.proton : particle.anti_proton, 
    chassisColor.BLACK, oem.ACME); 

的语法是condition ? value_if_true : value_if_false,它具有最低的运算符优先级,但括号往往添加,以避免混淆。

+0

我发现通常会添加括号来表示混淆,而不是避免它。 – 2010-08-26 05:32:52

2

如果enemy_composition只能是nature.MATTERnature.ANTIMATTER那么你可以使用一个ternery operator

DeathRay mynewWpn = new DeathRay(enemy_composition == nature.MATTER ? particle.anti-proton : particle.proton, chassisColor.BLACK, oem.ACME) 
2

如何重新设计一些类?

在自然类中,编写一些像getDestroyer()这样的方法。

abstract class Enemy{ 
    abstract Weapon getDestroyer(); 
} 

然后在像水泥类:

class MatterEnemy extends Enemy{ 
    Weapon getDestroyer(){return new DeathRay(antiproton, blabla);} 
} 

你实现这样的方法。所以你的主要类将是:

public static void main(String... args){ 
    Enemy enemy = new MatterEnemy(); 
    Weapon weapon = enemy.getDestroyer(); 
} 

这样你可以避免条件'ifs'。相反,敌人本身'告诉'你应该用什么武器来摧毁它们。