#MVVM + UniRx + Zenject + NUnit + ZeroMock (maybe)

1 messages · Page 1 of 1 (latest)

bitter sandal
#

MVVM for code architecture.
UniRx to experiment with reactive programming (it seems to be in fashion right now).
Zenject for IoC/DI.
NUnit for unit testing.
ZeroMock (optionally) to mock concrete classes for unit testing (instead of perhaps having to create factories and interfaces for everything).


Purely for the sake of learning, I'd like to implement everything above in a small project. I've made other threads here before, but I'd like to consolidate my final round of questions here before proceeding. Feel free to answer all or only some of the questions below.

Apologies in advance if I'm "asking the wrong questions" or "asking something in a way that shows I lack requisite knowledge on the topic". I've been working as a professional in the industry for only 3.5 years now, but at a small startup that's mostly been working in a game-jam/prototyping sort of way. I'm looking to take the initiative and break that mold. Thanks for your understanding.


#

(1) MVVM and reactive programming (UniRx) are said to go hand-in-hand. Is this necessarily true? Are there other layering schemes that work better in the context of Unity? I'm aware of MVC and MVP as well. Admittedly, I have a miserable time differentiating the difference between Controller, Presenter, and ViewModel.

(2) In MVVM (MVP and MVC), am I correct in understanding that there is no referential bidirectionality/circularity between the layers? That is, ViewModel only knows Model and View. Model and View don't know about ViewModel. Communication from Model and View towards ViewModel is done by ViewModel observing those two layers by subscribing to events defined in Model and View. i.e. Model (+events) <--- ViewModel ---> View (+events).

(3) Are unit tests going to be uniquely in the intermediary layer (ViewModel/Presenter/Controller)? Or should all the layers be testable?

(4) What about using ZeroMock to be able to mock concrete classes? Is it a substitute for factories and interfaces uniquely for the purpose of making something mockable?

#

(5) Broadly speaking, and in regards to the architectures I've been discussing, when is it best to rely on plain-old-class-objects (POCOs), MonoBehaviours, and ScriptableObjects? Do SciprtableObjects in the Model layer make sense?

(6) I'm getting some mixed messages in my research as to how much logic (if at all) I put into the Model layer. Maybe it depends on the architecture in question, but some say the Model uniquely contains domain objects and their related data. That's it. Others say that domain logic can be found in the Model layer, and application logic goes in the intermediary layer (ViewModel/Presenter/Controller).

(7) Using Zenject to automate layering such as MVVM, MVP, or MVC. I found this code snippet (https://stackoverflow.com/questions/74997265/universal-unity-mvp-solution). Is this worth considering? Am I understanding correctly that each class in each respective layer will implement one of these "universal" interfaces: IModel, IView, or IPresenter/IController/IViewModel? And that each "class slice" would need its own Installer for binding the corresponding View, Model, and ViewModel/Presenter/Controller? In the code snippet, the concrete classes would otherwise be real concrete classes that each implement the respective interface, e.g. PlayerModel : IModel, WeaponModel : IModel, etc, correct? I also noticed that the code snippet demonstrates what seems to be a circular dependency, which is generally considered an anti-pattern — or am I missing something here?

green plume
#

1 - Controller and presenter are mostly differentiated by semantics (and gets even more muddled when you look into active and passive view) - the core idea is: the controller and presenter take the active role of changing state. the Presenter 'presents' the view to the user and also to the model, glueing them together. (often it also gets a show() function for navigation). Controller is much the same, main difference is usually, can the view directly listen to the model (mvp) or does everything get piped through controller (mvc)

Viewmodel is an abstraction of the view. Every (potential) state and action the view can invoke is mirrored in the viewmodel.

2 - bidirectionality depends on usecase. If you have a button and a displaytext on the view, the connection will be bidrectional to propagate the buttonclicks up and the string for the text down

#

7 - for implementation this depends. In my personal implementation of MVP (after I walked it back from MVPVM) [technically AMVP, as I have the application as a layer on top] I solved it using generics, not interfaces. Presenters are usually written against a specific model and view, so making code as reusable as possible there is a bit of a wasted effort imo

#

mvvm usually takes advantage of other framework parts to do viewbinding, I don't know how much UIToolkit helps here, but the gameobject based approach doesn't lend itself really to that architecture

bitter sandal
#

@green plume Regarding point (2), View wouldn't necessarily need to know about the intermediary layer to propagate the onClick event. Since ViewModel has a reference to the View, that includes its exposed events and for example, a setter function that takes a string to set the field text. It can be done without the View ever knowing about the ViewModel, so there would be no circular dependency between the layers. Unless I'm missing something?