使用 switch 语句在 Java 中出现问题解耦
Trouble decoupling in Java using switch statements
目前我正在制作一款小型游戏,在我的播放器中 class 我有很多重要的和依赖项。
所以我决定将 switch 语句单独分开 [=42=] 以便在方法中调用。
对于上下文播放器代码
import Accessories.BasicSight;
import Accessories.BasicSilencer;
import Accessories.BasicStock;
import Accessories.GoodSight;
import Accessories.GoodSilencer;
import Accessories.GoodStock;
import Accessories.GreatSight;
import Accessories.GreatSilencer;
import Accessories.GreatStock;
import PlayerState.AliveState;
import PlayerState.PlayerState;
import Guns.Weapon;
import Guns.*;
import java.util.Scanner;
public class PlayerSingleton {
private static PlayerSingleton player;
Scanner scanner = new Scanner(System.in);
private String playerName;
private int lives;
private Integer health;
public static Integer MAX_PLAYER_HEALTH = 500;
public static Integer DEFAULT_PLAYER_LIVES = 2;
private PlayerState playerState;
private Weapon weapon;
private PlayerSingleton(Weapon weapon, String pName) {
this.weapon = weapon;
this.playerName = pName;
this.lives = DEFAULT_PLAYER_LIVES;
setState(new AliveState(this));
}
public static PlayerSingleton getInstance(String choice, String name) {
System.out.println("Choose Weapon to play the with: ");
Weapon weapon = PlayerSingleton.chooseWeapon(choice);
weapon.getDescription();
if (player == null) {
player = new PlayerSingleton(weapon, name);
}
return player;
}
public void sufferDamage(int damage) {
playerState.takeDamage(damage);
}
public void respawn() {
playerState.respawn();
}
public int getLives() {
return lives;
}
public void setLives(int lives) {
this.lives = DEFAULT_PLAYER_LIVES;
}
public int getHealth() {
return health;
}
public void setHealth(Integer health) {
this.health = health;
}
public void setState(PlayerState playerState) {
this.playerState = playerState;
}
public void chosenWeapon() {
System.out.println("Player Info: " + playerName + " " + "Has: " + health + " health and " + lives + " lives");
System.out.println(weapon.getDescription() + ":" + " base damage: " + weapon.damage());
}
public static Weapon chooseWeapon(String choice) {
switch (choice) {
case "MP5":
System.out.println("You have chosen MP5!");
return new MP5Weapon();
case "SNIPER":
System.out.println("You have chosen Sniper!");
return new SniperRifleWeapon();
case "SHOTGUN":
System.out.println("You have chosen Shotgun!");
return new ShotgunWeapon();
default:
System.out.println("No gun by that name found!");
return null;
}
}
public void addBasicAttachment(String attachment) {
switch (attachment) {
case "SIGHT":
weapon = new BasicSight(weapon);
break;
case "SILENCER":
weapon = new BasicSilencer(weapon);
break;
case "STOCK":
weapon = new BasicStock(weapon);
break;
default:
System.out.println("No Attachment found!");
}
}
public void getBasicAttachment(String attachment) {
}
public void addGoodAttachment(String attachment) {
switch (attachment) {
case "SIGHT":
weapon = new GoodSight(weapon);
break;
case "SILENCER":
weapon = new GoodSilencer(weapon);
break;
case "STOCK":
weapon = new GoodStock(weapon);
break;
default:
System.out.println("No Attachment found!");
}
}
public void addGreatAttachment(String attachment) {
switch (attachment) {
case "SIGHT":
weapon = new GreatSight(weapon);
break;
case "SILENCER":
weapon = new GreatSilencer(weapon);
break;
case "STOCK":
weapon = new GreatStock(weapon);
break;
default:
System.out.println("No Attachment found!");
}
}
}
所以上面的代码是我的玩家 class,我想把 addBasic/Good/Great 武器附件放在另一个单独的 class 文件中,以便更好地解耦代码。我不确定如何使用 switch 语句执行此操作。
关于如何处理这个问题有什么想法吗?
编辑:
正在从主函数调用开关方法:
import Accessories.*;
import Player.PlayerSingleton;
import Guns.Weapon;
import Guns.MP5Weapon;
import java.util.Scanner;
public class FireingRange {
Weapon weapon;
public static void main(String[] args) {
Scanner scanner = new Scanner(System.in);
String name = scanner.nextLine();
System.out.println(name + " to begin the game, first type a weapon you would like to play with:");
System.out.println();
System.out.println("Choose Weapon to play the with: ");
System.out.println("'Shotgun' for Shotgun");
System.out.println("'Sniper' for Sniper");
System.out.println("'MP5' for MP5");
String chooseWeapon = scanner.next().toUpperCase();
PlayerSingleton player = PlayerSingleton.getInstance(chooseWeapon, name);
System.out.println(player.getHealth());
System.out.println(player.getLives());
System.out.println();
player.chosenWeapon();
System.out.println("Are you ready to play the game?");
}
抽象配件class:
import Guns.Weapon;
public abstract class AccessoryDecorator extends Weapon{
public abstract String getDescription();
}
扩展 AccessoryDecorator 的附件:
public class BasicSight extends AccessoryDecorator {
Weapon weapon;
public BasicSight(Weapon weapon) {
this.weapon = weapon;
}
@Override
public String getDescription() {
return weapon.getDescription() + ", Basic Sight";
}
@Override
public double weight() {
return 7 + weapon.weight();
}
@Override
public double damage() {
return 7 + weapon.damage();
}
所以 objective 是:
public void addBasicAttachment(String attachment) {
switch (attachment) {
case "SIGHT":
weapon = new BasicSight(weapon);
break;
case "SILENCER":
weapon = new BasicSilencer(weapon);
break;
case "STOCK":
weapon = new BasicStock(weapon);
break;
default:
System.out.println("No Attachment found!");
}
}
public void addGoodAttachment(String attachment) {
switch (attachment) {
case "SIGHT":
weapon = new GoodSight(weapon);
break;
case "SILENCER":
weapon = new GoodSilencer(weapon);
break;
case "STOCK":
weapon = new GoodStock(weapon);
break;
default:
System.out.println("No Attachment found!");
}
}
public void addGreatAttachment(String attachment) {
switch (attachment) {
case "SIGHT":
weapon = new GreatSight(weapon);
break;
case "SILENCER":
weapon = new GreatSilencer(weapon);
break;
case "STOCK":
weapon = new GreatStock(weapon);
break;
default:
System.out.println("No Attachment found!");
}
}
在它自己的 class 中,然后能够用结果调用开关,然后将其添加到所选枪支的值中。
我似乎想不出如何 return 配件取决于创建的配件。
您可以制作一个具有某些功能的基础class,然后通过扩展的方式添加代码。另一种选择是制作一个实用程序 class,仅包含静态函数,您可以调用这些函数来操作传递的对象,如下所示:
public class PlayerUtil {
public static void addGreatAttachment(PlayerSingleton player, String attachment) {
Weapon weapon;
switch (attachment) {
case "SIGHT":
weapon = new GreatSight(weapon);
break;
case "SILENCER":
weapon = new GreatSilencer(weapon);
break;
case "STOCK":
weapon = new GreatStock(weapon);
break;
default:
System.out.println("No Attachment found!");
}
player.setWeapon(weapon);
}
}
但对于您的情况,我建议您创建另一个 class:“EquipedWeapon”。这个 class 将有自己的 Weapon 字段,可能还有多个 Attachment 字段。您可以将更改附件的代码放在那里,甚至添加一些方法来获取带有附件的武器的统计信息,例如伤害或子弹扩散或 wtv,然后为武器内部创建一个 getter PlayerSingleton.
我还建议在您的游戏中创建一个 AttachmentManager class 来保存所有附件并允许您使用各种方法 select 它们。或者您可以使所有附件都扩展一个附件 class,该附件包含所有附件的静态列表。如果您将名称作为字段添加到附件 class 中,则可以创建一个静态方法来遍历所有附件并找到名称正确的附件 returns。或者使用静态 Hashmap.
您通常可以消除具有 class 继承的语言中的 switch 语句,例如 Java。特别是 Java 的灵活枚举。我碰巧有一个例子可以做到这一点:
import java.util.Arrays;
import java.util.Map;
import java.util.stream.Collectors;
public enum CommandEnum
{
AUTHENTICATE("authenticate") {
public Command newCommand(final String newMessageName) {
return new Authenticate(newMessageName);
}
},
ADD("add") {
public Command newCommand(final String newMessageName) {
return new Add(newMessageName);
}
},
// ...bunch deleted for brevity
public final String messageName;
// Collect all enumerations into a map you
// can look up by name.
private static final Map<String, CommandEnum> messageNameMap =
Arrays.stream(CommandEnum.values())
.collect(
Collectors.toMap(
commandEnum -> commandEnum.messageName,
commandEnum -> commandEnum
)
);
CommandEnum(final String newMessageName) {
messageName = newMessageName;
}
public abstract Command newCommand(final String newMessageName);
public Command newCommand() {
return newCommand(messageName);
}
public static CommandEnum getEnum(String messageName) {
return messageNameMap.get(messageName);
}
}
在这种情况下,您可以通过以下方式从字符串中获取枚举:
CommandEnum ce = CommandEnum.getEnum(...string...);
然后你把它转换成这样的命令:
if (null != ce) {
Command c = ce.newCommand();
...
}
目前我正在制作一款小型游戏,在我的播放器中 class 我有很多重要的和依赖项。
所以我决定将 switch 语句单独分开 [=42=] 以便在方法中调用。
对于上下文播放器代码
import Accessories.BasicSight;
import Accessories.BasicSilencer;
import Accessories.BasicStock;
import Accessories.GoodSight;
import Accessories.GoodSilencer;
import Accessories.GoodStock;
import Accessories.GreatSight;
import Accessories.GreatSilencer;
import Accessories.GreatStock;
import PlayerState.AliveState;
import PlayerState.PlayerState;
import Guns.Weapon;
import Guns.*;
import java.util.Scanner;
public class PlayerSingleton {
private static PlayerSingleton player;
Scanner scanner = new Scanner(System.in);
private String playerName;
private int lives;
private Integer health;
public static Integer MAX_PLAYER_HEALTH = 500;
public static Integer DEFAULT_PLAYER_LIVES = 2;
private PlayerState playerState;
private Weapon weapon;
private PlayerSingleton(Weapon weapon, String pName) {
this.weapon = weapon;
this.playerName = pName;
this.lives = DEFAULT_PLAYER_LIVES;
setState(new AliveState(this));
}
public static PlayerSingleton getInstance(String choice, String name) {
System.out.println("Choose Weapon to play the with: ");
Weapon weapon = PlayerSingleton.chooseWeapon(choice);
weapon.getDescription();
if (player == null) {
player = new PlayerSingleton(weapon, name);
}
return player;
}
public void sufferDamage(int damage) {
playerState.takeDamage(damage);
}
public void respawn() {
playerState.respawn();
}
public int getLives() {
return lives;
}
public void setLives(int lives) {
this.lives = DEFAULT_PLAYER_LIVES;
}
public int getHealth() {
return health;
}
public void setHealth(Integer health) {
this.health = health;
}
public void setState(PlayerState playerState) {
this.playerState = playerState;
}
public void chosenWeapon() {
System.out.println("Player Info: " + playerName + " " + "Has: " + health + " health and " + lives + " lives");
System.out.println(weapon.getDescription() + ":" + " base damage: " + weapon.damage());
}
public static Weapon chooseWeapon(String choice) {
switch (choice) {
case "MP5":
System.out.println("You have chosen MP5!");
return new MP5Weapon();
case "SNIPER":
System.out.println("You have chosen Sniper!");
return new SniperRifleWeapon();
case "SHOTGUN":
System.out.println("You have chosen Shotgun!");
return new ShotgunWeapon();
default:
System.out.println("No gun by that name found!");
return null;
}
}
public void addBasicAttachment(String attachment) {
switch (attachment) {
case "SIGHT":
weapon = new BasicSight(weapon);
break;
case "SILENCER":
weapon = new BasicSilencer(weapon);
break;
case "STOCK":
weapon = new BasicStock(weapon);
break;
default:
System.out.println("No Attachment found!");
}
}
public void getBasicAttachment(String attachment) {
}
public void addGoodAttachment(String attachment) {
switch (attachment) {
case "SIGHT":
weapon = new GoodSight(weapon);
break;
case "SILENCER":
weapon = new GoodSilencer(weapon);
break;
case "STOCK":
weapon = new GoodStock(weapon);
break;
default:
System.out.println("No Attachment found!");
}
}
public void addGreatAttachment(String attachment) {
switch (attachment) {
case "SIGHT":
weapon = new GreatSight(weapon);
break;
case "SILENCER":
weapon = new GreatSilencer(weapon);
break;
case "STOCK":
weapon = new GreatStock(weapon);
break;
default:
System.out.println("No Attachment found!");
}
}
}
所以上面的代码是我的玩家 class,我想把 addBasic/Good/Great 武器附件放在另一个单独的 class 文件中,以便更好地解耦代码。我不确定如何使用 switch 语句执行此操作。
关于如何处理这个问题有什么想法吗?
编辑:
正在从主函数调用开关方法:
import Accessories.*;
import Player.PlayerSingleton;
import Guns.Weapon;
import Guns.MP5Weapon;
import java.util.Scanner;
public class FireingRange {
Weapon weapon;
public static void main(String[] args) {
Scanner scanner = new Scanner(System.in);
String name = scanner.nextLine();
System.out.println(name + " to begin the game, first type a weapon you would like to play with:");
System.out.println();
System.out.println("Choose Weapon to play the with: ");
System.out.println("'Shotgun' for Shotgun");
System.out.println("'Sniper' for Sniper");
System.out.println("'MP5' for MP5");
String chooseWeapon = scanner.next().toUpperCase();
PlayerSingleton player = PlayerSingleton.getInstance(chooseWeapon, name);
System.out.println(player.getHealth());
System.out.println(player.getLives());
System.out.println();
player.chosenWeapon();
System.out.println("Are you ready to play the game?");
}
抽象配件class:
import Guns.Weapon;
public abstract class AccessoryDecorator extends Weapon{
public abstract String getDescription();
}
扩展 AccessoryDecorator 的附件:
public class BasicSight extends AccessoryDecorator {
Weapon weapon;
public BasicSight(Weapon weapon) {
this.weapon = weapon;
}
@Override
public String getDescription() {
return weapon.getDescription() + ", Basic Sight";
}
@Override
public double weight() {
return 7 + weapon.weight();
}
@Override
public double damage() {
return 7 + weapon.damage();
}
所以 objective 是:
public void addBasicAttachment(String attachment) {
switch (attachment) {
case "SIGHT":
weapon = new BasicSight(weapon);
break;
case "SILENCER":
weapon = new BasicSilencer(weapon);
break;
case "STOCK":
weapon = new BasicStock(weapon);
break;
default:
System.out.println("No Attachment found!");
}
}
public void addGoodAttachment(String attachment) {
switch (attachment) {
case "SIGHT":
weapon = new GoodSight(weapon);
break;
case "SILENCER":
weapon = new GoodSilencer(weapon);
break;
case "STOCK":
weapon = new GoodStock(weapon);
break;
default:
System.out.println("No Attachment found!");
}
}
public void addGreatAttachment(String attachment) {
switch (attachment) {
case "SIGHT":
weapon = new GreatSight(weapon);
break;
case "SILENCER":
weapon = new GreatSilencer(weapon);
break;
case "STOCK":
weapon = new GreatStock(weapon);
break;
default:
System.out.println("No Attachment found!");
}
}
在它自己的 class 中,然后能够用结果调用开关,然后将其添加到所选枪支的值中。
我似乎想不出如何 return 配件取决于创建的配件。
您可以制作一个具有某些功能的基础class,然后通过扩展的方式添加代码。另一种选择是制作一个实用程序 class,仅包含静态函数,您可以调用这些函数来操作传递的对象,如下所示:
public class PlayerUtil {
public static void addGreatAttachment(PlayerSingleton player, String attachment) {
Weapon weapon;
switch (attachment) {
case "SIGHT":
weapon = new GreatSight(weapon);
break;
case "SILENCER":
weapon = new GreatSilencer(weapon);
break;
case "STOCK":
weapon = new GreatStock(weapon);
break;
default:
System.out.println("No Attachment found!");
}
player.setWeapon(weapon);
}
}
但对于您的情况,我建议您创建另一个 class:“EquipedWeapon”。这个 class 将有自己的 Weapon 字段,可能还有多个 Attachment 字段。您可以将更改附件的代码放在那里,甚至添加一些方法来获取带有附件的武器的统计信息,例如伤害或子弹扩散或 wtv,然后为武器内部创建一个 getter PlayerSingleton.
我还建议在您的游戏中创建一个 AttachmentManager class 来保存所有附件并允许您使用各种方法 select 它们。或者您可以使所有附件都扩展一个附件 class,该附件包含所有附件的静态列表。如果您将名称作为字段添加到附件 class 中,则可以创建一个静态方法来遍历所有附件并找到名称正确的附件 returns。或者使用静态 Hashmap
您通常可以消除具有 class 继承的语言中的 switch 语句,例如 Java。特别是 Java 的灵活枚举。我碰巧有一个例子可以做到这一点:
import java.util.Arrays;
import java.util.Map;
import java.util.stream.Collectors;
public enum CommandEnum
{
AUTHENTICATE("authenticate") {
public Command newCommand(final String newMessageName) {
return new Authenticate(newMessageName);
}
},
ADD("add") {
public Command newCommand(final String newMessageName) {
return new Add(newMessageName);
}
},
// ...bunch deleted for brevity
public final String messageName;
// Collect all enumerations into a map you
// can look up by name.
private static final Map<String, CommandEnum> messageNameMap =
Arrays.stream(CommandEnum.values())
.collect(
Collectors.toMap(
commandEnum -> commandEnum.messageName,
commandEnum -> commandEnum
)
);
CommandEnum(final String newMessageName) {
messageName = newMessageName;
}
public abstract Command newCommand(final String newMessageName);
public Command newCommand() {
return newCommand(messageName);
}
public static CommandEnum getEnum(String messageName) {
return messageNameMap.get(messageName);
}
}
在这种情况下,您可以通过以下方式从字符串中获取枚举:
CommandEnum ce = CommandEnum.getEnum(...string...);
然后你把它转换成这样的命令:
if (null != ce) {
Command c = ce.newCommand();
...
}