Java инверсия на контрол върху MVC базирано приложение

Създавам MVC базирано java приложение/игра и се опитвам да използвам 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 getter, за да получите View и Model, необходими на борда.

Аз правя нещо подобно:

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

Притесненията ми са за класа "wrapper" 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