如何在初始化前更改单例模式

How to change Singleton Pattern before initialisation

public class PlayerSingleton {

private static PlayerSingleton player;   
private String playerName;

private Weapon weapon;

Weapon stockMP5 = new MP5Weapon();        //Making a new weapon called stockMP5 from MP5weapon Class
Weapon sniper = new SniperRifleWeapon();  //Making a new weapon called sniper from SniperRifleWeapon Class
Weapon shotgun = new ShotgunWeapon();  //Making a new weapon called shotgun from Shotgun Class

private PlayerSingleton(Weapon weapon, String pN) {
    this.weapon = weapon;
    playerName = pN;
}

public void chooseWeapon(String choice) {
    switch (choice) {
        case "MP5":
            weapon = new MP5Weapon();
            break;
        case "Sniper":
            weapon = new SniperRifleWeapon();
            break;
        case "Shotgun":
            weapon = new ShotgunWeapon();
            break;
        default:
            System.out.println("No Attachment found!");
    }
}

public static PlayerSingleton getInstance(Weapon choice, String n) {
    System.out.println("Choose Weapon to play the with: ");

// HERE 我希望允许玩家在单体 class 初始化之前选择武器。让玩家玩他们的枪,而不是在整个游戏过程中改变它。

    if (player == null) {
        player = new PlayerSingleton(choice, n);
    }
    return player;
}

public void chosenWeapon() {
    System.out.println(weapon.getDescription()
            + " Weight of Player: " + playerName + " gun: " + weapon.weight() + " base damage: " + weapon.damage());
}

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!");
    }
}

如何让玩家在初始化 playerSingleton getInstance 方法之前选择武器?

如有任何帮助,我们将不胜感激。

已编辑:

public static Weapon chooseWeapon(String choice) {
        switch (choice) {
            case "MP5":
                return new MP5Weapon();
            case "Sniper":
                return new SniperRifleWeapon();
            case "Shotgun":
                return new ShotgunWeapon();
            default:
                return null;
        }
    }
public static PlayerSingleton getInstance(String choice, String n) {
        System.out.println("Choose Weapon to play the with: ");

        Weapon weapon = PlayerSingleton.chooseWeapon(choice);
        if (player == null) {
            player = new PlayerSingleton(weapon, n);
        }
        return player;
    }

主要:

Scanner scanner = new Scanner(System.in);
        System.out.println(" ------------------------------------ ");
        System.out.println("       Text based Shooting Game       ");
        System.out.println(" ------------------------------------ ");
        System.out.println("Please Enter your name before Beginning*");
        String name = scanner.next();
        System.out.println("Thank you for joining this Adventure " +name);
   
        
        Weapon weapon = PlayerSingleton.chooseWeapon(name);   
        PlayerSingleton player = PlayerSingleton.getInstance("MP5",name);
        player.chosenWeapon();

补充编辑: 武器 class

public abstract class Weapon {
    String description = "Unknown Weapon: ";
    
    
    public String getDescription(){
        return description;
    }
    //public abstract int bulletCount();
    public abstract double weight();
    public abstract double damage();
}

更简洁的方法是将 chooseWeapon 方法设为静态,并将 return 武器设为:

public static Weapon chooseWeapon(String choice) {
    switch (choice) {
        case "MP5":
            return new MP5Weapon();
        case "Sniper":
            return new SniperRifleWeapon();
        case "Shotgun":
            return new ShotgunWeapon();
        default:
            System.out.println("No Attachment found!");
            return null;
    }
}

然后在 getInstance 上做:

public static PlayerSingleton getInstance(String choice, String n) {
    Weapon weapon = PlayerSingleton.chooseWeapon(choice);        
    if (player == null) {
        player = new PlayerSingleton(weapon, n);
    }
    return player;
}

对 getInstance 的调用:

 System.out.println("Choose Weapon to play the with: ");
 String choice = scanner.next();
 PlayerSingleton player = PlayerSingleton.getInstance(choice, name);
 player.chosenWeapon();

那么一个问题是为什么你希望你的玩家是单身?玩家对象应该用游戏对象初始化,这样你就永远不需要说“新”玩家。

现在,如果您要重新生成玩家并创建一个新实例,您应该考虑在玩家中添加一个“重置”方法class

如果一定要做“单例”: 就选择武器的常规而言,将其委托给另一个 class“WeaponFactory”会更清晰。静态方法可能是一种短期方法,如果您有自动化测试(猜猜这些通常不会在编写游戏时编写?),那么测试和存根会很痛苦:P

现在,当您拥有 WeaponFactory 时,您可以拥有一个武器选择器 class,它会提示用户并调用所需的工厂(或方法)来创建“武器”,然后再尝试获取玩家.

实际: 如果你不在Player中写一个“setWeapon”方法class你就达到了不允许改变Player武器的目的除非再次创建 Player 对象并与 Game 相关联。