Каково лучшее решение ООП моей проблемы? - PullRequest
0 голосов
/ 30 января 2019

В настоящее время я пытаюсь лучше структурировать свой код и все больше и больше фокусироваться на использовании концепций ООП.

У меня простой вопрос о следующем сценарии и о том, как онЛучшая решаемая с точки зрения дизайна модель.

У меня есть игра, в которой игрок может ограбить магазин.Магазин представлен объектом Shop, а ограбление - RobEvent.И у меня есть объект Spawner, который обрабатывает порождение ценных бумаг, когда кто-то пытается ограбить магазин.

Моя главная проблема заключается в том, что у меня есть ощущение, что объект RobEvent имеет слишком много информации и функций, описанных ниже, и что я могу разделить информацию и функции на большее количество объектов, и для этого мне нужна помощьyou!

public class Main 
{

    public static void main(String[] args)
    {

    }

    public class Shop {

        private String name;
        private Location location;
        private boolean isBeingRobbed = false;

        /*
         * Here one of the problems, should the shop have the 
         * data of the npcs, which will appear
         * in the shop when the player attempts to rob it.
         * Should it have methods to place "spawn" positions of 
         * the securities, the type, the amount etc.
         * and store it here? 
         * 
         */

        public Shop(String name, Location location){
            this.name = name;
            this.location = location;
        }

        public boolean isBeingRobbed(){
            return isBeingRobbed;
        }

        protected void setBeingRobbed(boolean bool){
            this.isBeingRobbed = bool;
        }
    }

    public class RobEvent extends Looper {

        private Shop shop;

        RobEvent(Shop shop){
            this.shop = shop;
        }

        public void start(){
            shop.setBeingRobbed(true);
        }

        @Override
        protected void logic(){
        /*
         * Big chunk of game logic
         * Spawning the securities, checking if they 
         * all appeared(they got a delay of few seconds each),
         * check if he ran away before everything 
         * spawned, check if he killed all, check if all appeared
         */
        }

        private void completed(){
            shop.setBeingRobbed(false);
        }
    }

    public class Spawner {


        /* not important things
         * 
         * just has a method to 
         * handle the spawn of a security 
         */     

        public void spawn(NPC npc){
            /*
             * spawn the npc aka security
             */
        }

    }
}

Моя самая большая проблема в том, что метод logic() становится действительно большим.Это метод, который зацикляется каждую секунду суперклассом.

Подробнее:

  • RobEvent должен знать, порождает ли он в настоящее время ценные бумаги, и делать определенные вещи,
  • он должен проверять, все ли появились и делать определенные вещи,
  • он должен проверять, убежал ли игрок до того, как он был завершен, и делать определенные вещи,
  • он должен проверять, убил ли игрок все и делать определенные вещи и т. д.

Больше всего раздражает слежка за порожденными ценными бумагами, потому что, если он убегает, все они должны быть отброшены.У меня такое ощущение, что это слишком много информации в этом объекте, и я мог бы, например, разделить отслеживание порожденных ценных бумаг в отдельном объекте и просто сделать что-то вроде tracker.despawn, когда RaidEvent имеет определенное состояние.

РЕДАКТИРОВАТЬ: код просто упрощение фактического кода.

Ответы [ 3 ]

0 голосов
/ 30 января 2019

RobEvent должен знать, порождает ли он в настоящее время ценные бумаги и делать определенные вещи, - он должен проверять, все ли появилось и делать определенные вещи, - он должен проверять, убежал ли игрок, прежде чем он был завершени делать определенные вещи, - он должен проверять, убил ли игрок все, и делать определенные вещи и т.д.

Это звучит как State-Pattern , который отделяет логику от состояния.

Быстрое внедрение

RobEvent необходимо отслеживать RobState.У вас есть несколько RobState, таких как StartSpanSecuritiesState, AllSecuritiesSpanedState, PlayerRunAwayState и более ..

interface RobState {
    void handle();
}

class RobEvent extends Looper implements RobState {

    // add new member
    private RobState robState;
    private Shop shop;

    RobEvent(Shop shop) {
        this.shop = shop;
        this.robState = new StartSpanSecuritiesState();
    }

    // add new setter - gets normally called only by a `State`
    void setRobState(RobState robState) {
        this.robState = robState;
    }

    // ..

}

Каждый RobState знает следующий RobState и задает его через setRobStateRobEvent.

class StartSpanSecuritiesState implements RobState {

    private RobEvent robEvent;

    public StartSpanSecuritiesState(RobEvent robEvent) {
        this.robEvent = robEvent;
    }

    @Override
    public void handle() {
        // span your securities
        //...

        // go to the next state
        robEvent.setRobState(new AllSecuritiesSpanedState(robEvent));
    }
}

После всех модификаций метод logic может выглядеть следующим образом:

@Override
protected void logic(){
    robState.handle();
}

Надеюсь, он вам поможет!Если не в этот раз, может быть, в будущем!
Удачи в игре:]

0 голосов
/ 30 января 2019

Наряду с другими ответами я бы также рассмотрел моделирование RobEvent как фактическое Event (я не Java-разработчик, я не знаю, как реализовать их в Java).Когда магазин грабят, он отправляет около RobEvent.Объект Spawner может подписаться на эти события и при каждом RobEvent отправлять ценные бумаги.Затем, если грабитель убегает, магазин отправляет RobberRunAwayEvent, на который подписаны все ценные бумаги (или Despawner).

0 голосов
/ 30 января 2019

С точки зрения структуры ОО, у Классов есть состояние (их свойства) и поведение (их методы).Я бы смотрел на RobEvent как на поведение Shop, т. Е. Перемещал его в метод, а не в класс.

Если ваш метод logic () становится слишком длинным, хорошо, что вы признаете, что он слишком длинный, и этообычно указание на то, что он делает слишком много.Самый простой подход - разделить его на более мелкие методы, каждый из которых выполняет одну конкретную вещь и вызывается по очереди.Например, типичный игровой цикл может выглядеть примерно так:

public void gameLoop(){
    while(this.gameRunning){
        this.checkUserInputs();
        this.updateGameState();
        this.updateGameDisplay();
    }
}

Короткие / меньшие методы легче понять и поддерживать, чем чрезмерно длинные методы.

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...