Java-инверсия управления в приложении на основе MVC

Я создаю Java-приложение/игру на основе MVC и пытаюсь использовать IoC для отделения создания объекта от логики приложения.

Предположим, у меня есть только 2 сущности: Board и Player, каждая из которых имеет класс Model, класс View и класс Controller.

BoardModel нужен PlayerModel (для обработки некоторой логики приложения), а BoardView нужен PlayerView (чтобы отображать его внутри своего пространства).

Чтобы создать новый Player, я использую класс PlayerFactory, который создает PlayerModel, PlayerView и PlayerController и соединяет их вместе.

Проблема в том, что после создания Player мне нужны экземпляры PlayerModel и PlayerView для создания Board.

Мое решение состоит в том, чтобы «обернуть» PlayerModel, PlayerView и PlayerController в класс Player, который имеет только эти 3 поля и 3 getters; передайте Player BoardFactory и внутри фабрики используйте геттер 3, чтобы получить View и Model, необходимые Правлению.

Я делаю что-то вроде этого:

PlayerFactory pFactory = new PlayerFactory();
Player player = pFactory.build("HUMAN");
BoardFactory bFactory = new BoardFactory();
Board board = bFactory.build(player);

Меня беспокоит класс "обертка" Player. Имеет ли смысл иметь класс только для хранения 3 объектов? Есть ли лучший способ передать зависимости Board без использования контейнера IoC?


person user1305336    schedule 17.05.2015    source источник
comment
Как Board использует PlayerView, PlayerController и PlayerModel?   -  person CKing    schedule 17.05.2015
comment
@ChetanKinger Board использует PlayerView для добавления к своему собственному View (для целей рендеринга) и использует PlayerModel для проверки, например, может ли игрок двигаться в определенной позиции. Класс Board сам является оболочкой для BoardView, BoardModel и BoardContoller.   -  person user1305336    schedule 17.05.2015
comment
Я попытался дать ответ, основанный на моем понимании. Взгляните и дайте мне знать, если у вас есть какие-либо вопросы.   -  person CKing    schedule 17.05.2015
comment
@ChetanKinger Спасибо за ответ. Проблема в том, что я использую шаблон MVC, поэтому я не хочу передавать контроллеру и представление, и модель.   -  person user1305336    schedule 17.05.2015
comment
Без проблем. Просто любопытно, почему вы должны использовать определенный шаблон?   -  person CKing    schedule 17.05.2015
comment
@ChetanKinger Это одна из моих просьб. И мне нужно изменить графическое представление с представлением CLI, так что MVC не так уж и плох.   -  person user1305336    schedule 17.05.2015
comment
Вы все еще можете изменить видGraphic на вид CLI с моим подходом. Но если вы настаиваете на использовании MVC, вам, возможно, придется перепроектировать свои классы с нуля, поскольку то, как они у вас есть сейчас, потребует от вас использования пустой оболочки, которая ничего не делает.   -  person CKing    schedule 17.05.2015


Ответы (1)


Ваш общий подход выглядит хорошо. Хотя, есть пара изменений, которые я бы сделал:

PlayerController и Player несут одинаковую ответственность. Я бы полностью избавился от Player и просто использовал вместо него PlayerController

Псевдокод будет выглядеть так:

 public class PlayerController {
    private PlayerView playerView;
    private PlayerModel playerModel;
    //constructor that intializes playerView and playerModel

    public void render() { playerView.render() }

    public void moveForward(int steps) {
       if(playerModel.canMoveForward()) {
            playerView.moveForward(steps);
       }
    }
 }

Точно так же вы можете избавиться от Board и вместо него просто иметь BoardController. Тогда BoardController может зависеть от PlayerController, а не от Player. Псевдокод для этого будет выглядеть примерно так:

 public class BoardController {
     private PlayerController playerController;
     private BoardView boardView;
     private BoardModel boardModel;
     //constructor that intializes the dependencies 

    public void render() { 
        playerController.render();
        boardView.render();
    }

    public void movePlayerForward(int steps) {
       if(!boardModel.isGameOver()) {
        playerController.moveForward(steps);
       }
    }
 }

Таким образом, вы избавитесь от классов Player и Board, которые на самом деле мало что делали. В качестве альтернативы вы можете переименовать вышеуказанные классы в Player и Board. Еще одно преимущество приведенного выше псевдокода заключается в том, что вы также делаете свой код более читабельным, реализуя принцип Tell Dont Ask.

person CKing    schedule 17.05.2015