I am developing a small application and trying my best to make it as professional as possible in regards to design pattern etc.
It is a JavaFX app, and my app works fine but I am uneasy at the fact that I am instantiating the back end in the front end. I tried my best to follow MVC pattern and I think I have so far, but I can't see any other way around this.
Basically, my application has difficulty levels, and based on the difficulty level chosen by user (which is required to create the backend) a game with that difficulty level is created. And I can't think of any other way to start the backend without first knowing the difficulty level, thus it is instantiated in the front end.
However, besides that the front end has no logic. It only draws and sends user input to the back-end, the back end of course then has the logic and tells the front end where to draw the changes.
Is this considered ok? If not how should each side of the pipe be launched?
-
2Maybe a game object should be created but no work should be done (as far as setting up the game) until a difficulty level is set?– FrustratedWithFormsDesignerApr 19, 2017 at 18:34
-
How does the UI know which difficulty levels exist? That is also part of the business logic that should be in the model/backend.– Bart van Ingen SchenauApr 20, 2017 at 16:49
-
@FrustratedWithFormsDesigner such a simple answer, I don't know why I didn't think of this before.– PantsApr 21, 2017 at 15:41
2 Answers
Is this considered ok?
I don't see any problems with your approach.
If not how should each side of the pipe be launched?
If the model side of your application were to be a server with the ability for multiple viewers to connect to it, then you will need to worry about how to launch it independent of the viewer/controller and connect to it.
From your description, it does not sound like the model side will be an independent server. Hence, it makes most sense that your viewer is started first, which then starts the model with the necessary input.
thus it is instantiated in the front end.
This might look like a detail, but the correct phrase should be "It is initiated in the front end".
What I mean by this is that the View
tells the Controller
: "Do action 52". (fictional example, made extreme just to make a point).
The View
doesn't care at all what action 52 is. It could be restarting the game, it could be changing the difficulty, it could be a lot of other things. But none of those matter for the View
. It only cares that the user has pressed a certain button, and clicking that button means telling to the Controller
to "do action 52".
The Controller
on his side doesn't care why the View
is telling him to "do action 52". It might have been because the user has pressed a certain button. It might be an automated command in a testing framework. It just doesn't care. All it cares about is that it now has to "do action 52".
And the Controller
knows what has to happen now. It has to tell the backend "set difficulty level to 3". But again, the Controller
doesn't really need to know one thing about what difficulty levels are. That's something the backend will take care of. All the Controller
cares is that it tells the backend that the difficulty level is now 3, and that the backend should respond with some new level
that should be presented to the user.
Now in practice, ofcourse you're not going to make the View
call some arbitrary string like "do action 52". Because you as a programmer do know what to tell the controller. And that this message from the view to Controller
should be a call to the method prepareLevel(3)
. This makes it a lot more readable for you, but doesn't change the fact that the View
still doesn't care what should happen when that method is called. That's not his responsibility. The View
's only responsibility is calling that specific method if the user has clicked that specific button.
To test yourself you can ask the following questions:
If my business logic changes (for example you change something inside a level) which componens have to change as well? The answer should be: only the Model
If I want to change my app to java swing instead of javafx which components need to change? The answer should be: only the View.
There might be some minor details in the controller depending on how far you went in decoupling the controller from the view implementation, or the similarly the controller from the model. But in general, you should have put all business logic into the model, and all presentation related stuff (like colors, font, buttons, ...) into the View.
Just for completeness sake. If you don't mind sharing your code as is and want other people to review what you've done right and what could have been done better you can always post (snippits of) your code on https://codereview.stackexchange.com
-
Thanks so much for your input. I agree with everything you said, the problem however is that the Model object (lets call it Game) does not exists prior to user input in the front end (View). All those testing questions give me the correct answer, but again, it is unclear to me whether the View should instantiate/create the Game. I haven't found any source stating whether it is ok or not and why.– PantsApr 21, 2017 at 15:44
-
The view itself should not create the game. It should tell the controller to create the game. Then the controller could for example use a factory to have that create the game. There is nothing wrong with that. If the View itself actually calls the constructor of one of your model classes then that's a different story.– ImusApr 21, 2017 at 16:25