Как изменить шаблон Singleton перед инициализацией

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: ");

// ЗДЕСЬ я хочу, чтобы игрок мог выбрать оружие до того, как класс singleton инициализируется ниже. Чтобы игрок мог играть со своим оружием и не менять его на протяжении всей игры.

    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();

Дополнительное редактирование: Класс оружия

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();
}
Пользовательский скаляр GraphQL
Пользовательский скаляр GraphQL
Листовые узлы системы типов GraphQL называются скалярами. Достигнув скалярного типа, невозможно спуститься дальше по иерархии типов. Скалярный тип...
Как вычислять биты и понимать побитовые операторы в Java - объяснение с примерами
Как вычислять биты и понимать побитовые операторы в Java - объяснение с примерами
В компьютерном программировании биты играют важнейшую роль в представлении и манипулировании данными на двоичном уровне. Побитовые операции...
Поднятие тревоги для долго выполняющихся методов в Spring Boot
Поднятие тревоги для долго выполняющихся методов в Spring Boot
Приходилось ли вам сталкиваться с требованиями, в которых вас могли попросить поднять тревогу или выдать ошибку, когда метод Java занимает больше...
Полный курс Java для разработчиков веб-сайтов и приложений
Полный курс Java для разработчиков веб-сайтов и приложений
Получите сертификат Java Web и Application Developer, используя наш курс.
1
0
62
2
Перейти к ответу Данный вопрос помечен как решенный

Ответы 2

Ответ принят как подходящий

Более чистым подходом было бы сделать метод chooseWeapon статическим и вернуть оружие:

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();

Итак, один вопрос: почему вы хотите, чтобы ваш плеер был синглтоном? Объект игрока должен быть инициализирован с помощью объекта Game, и таким образом вам никогда не понадобится говорить «новый» Player.

Теперь, если вы повторно создаете игрока и создаете новый экземпляр, вам следует подумать о добавлении метода «сброса» в класс игрока.

Если вы должны сделать "Singleton": Что касается процедуры выбора оружия, было бы чище делегировать ее другому классу "WeaponFactory". Статический метод может быть краткосрочным подходом, и его трудно тестировать и заглушать, если у вас есть автоматизированные тесты (угадайте, что они обычно не пишутся при написании игры?): P

Теперь, когда у вас есть WeaponFactory, вы можете иметь класс выбора оружия, который предлагает пользователю и вызывает желаемую фабрику (или метод) для создания «оружия», прежде чем пытаться получить экземпляр Player.

Практически: если вы не напишете метод setWeapon в классе Player, вы достигнете цели запретить изменение оружия игрока, если только объект Player не будет создан и снова связан с игрой.

Другие вопросы по теме