I watch some tutorial projects on YouTube and some of them make viewmodel file and write some bunch of code, just to use viewmodel!
We have remember and rememberSavable and state and recomposition
and ... in jetpack compose. so why still some people use viewmodel?!
it's some more code and makes the project more difficult to understand for we beginners.
I guess they learned viewmodel for XML hardly and they can't just forget about it!
isn't it possible in jetpack compose to write the code in a way that we don't need to use viewmodel anyway?
ViewModels are still useful for passing data between screens or changing a Composable from another like in xml.
Let's say you have a Cart composable you wish to change TopAppBar from or other Composables that are not related to each other but changes TopAppbar color or text. You can use a shared ViewModel to set from various places and listen for mutableState inside TopAppBar composable.
Also, remember is for storing Data through recomposition, rememberSaveable adds configuration changes on top of remember. When you move to next screen and come back if your Composable is not in composition these will be reinstantiated but you can keep data in ViewModel as long as your apps alive. You can use ViewModel in various ways.
Last but not least, remember makes your Composables stateful, instead of this using state-hositing makes your Composable easier to maintain.
If you build layers top of stateful Composables you increase permutation of states your Composable go into when any MutableState in child or parent changes.
It might be difficult to track state changes from parent to child. I sometimes have this issue when i have Modifier.pointerInput(keys) with state not changing as expected.
In my opinion state management is one of the most difficult aspects of Compose. Because of this the less stateful Composables you have easier it's to manage your Composable's internal changes
The recommendation to use ViewModel is still there, because we should have calculations in ViewModel as much as possible, except for those that require calculations in pixel space.
On the other hand, we have to use ViewModel to call Domain layer specefic interfaces method.
It is recommended that our presentation layer logic and code not depend on Compose or XML.
It is also logical to use ViewModel for testing purpose
Related
I started playing around with Android JetPack (ViewModel, Architecture Components, LIfeCycle and so on).
Untill now, I was working with Model View Presenter architecture, and actually I found it a quite easy to test and maintain architecture.
On the other hand, The big advantage I can see by using ViewModels instead, is their native coupling with Activities and Fragments lifecycle, which always was one of the biggest pains for Android developer, so I think this is a very big step forward.
Said that, I think there is a big disavantage though: with this new approach, it seems much more tricky to call Activity's or Fragment's methods, because, as stated in the official docs
A ViewModel must never reference a view, Lifecycle, or any class that
may hold a reference to the activity context.
In MVP approach, the Presenter had a contract with the view and could call all of its methods. I made some research on how to address this scenario with Architecture components, but it seem there is no easy and painless way to do that: at the end you always have to handle states in ViewModel and react to these changes in Activities and Fragments. Someone suggest to use SingleLiveEvent class, which makes it a little bit easier, but still much more painfull than before.
So my question is:
The docs say you cannot reference anything holding a reference to an Activity Context (to avoid memory leaks I guess), but what if I do that and then I clear all references in ViewModel's onCleared()?
You wouldn't avoid memory leaks, because for example if you rotate your device your activity will be destroyed, then recreated, but the VM would remain the same, and it's onCleared would not be called (hence your old activity still remains in memory, since your VM still references it).
Generally the MVVM conceptually says, that the ViewModels should not know about the View and this is the beauty of architecture: there is not a better pattern, just a more suitable one, and you should choose the one, that works better for you.
I can think of couple of ways to "notify a user" of the ViewModel:
A LiveData object that changes and an Observer to this data
Send a Broadcast to a BroadcastReceiver using the Application's Context, if you don't mind accessing it statically from the ViewModel
Edit: I know this is not exactly an answer to the question, but I think it removed the need for it
but what if I do that and then I clear all references in ViewModel's onCleared()?
That is far too late. onCleared() is only called if the Activity is finished / the Fragment is removed, it is not called on configuration changes.
But you could potentially use some form of command queue to emit events only when a subscriber is available, for example DispatchWorkSubject in RxJava2-Extensions.
Just make sure you make your subscriptions in onStart and then dispose your disposable in onStop.
How to implement the mvvm architecture in objective-c ? I need sample project to learn the mvvm architecture and also i need to know that what is needed to give in model, view, viewModel and how to separate in objective-c ? what is the difference between the normal project and mvvm project ?
Jesto I can give you details about what you ask briefly.Even if it is explanation you can easily understand what I post here because it has sources with examples and you can directly try the source.
First the Model
The model layer is not as self-explanatory as it may seem.
As you would expect, it will have your model objects, potentially
covering most of the layer surface. In the tickets example, you would
have a Ticket struct that would live in your model.
I find the following components to also be part of the model layer:
Network Code. The shape should be something like this. Ideally, you’d only use a single class for network communication across your
entire app.
Persistence Code. You would implement this with Core Data or simply by saving an NSData blob directly to disk.
Parsing Code. Any objects that parse network responses and the like should be included in the Model layer as well.
While the model objects and the parser are domain-specific, the
network code will be highly reusable.
The controller will then use all the elements in your model layer to
define the flow of information in your app.
Second the View
When a user interacts with your app, they are interacting with the
view layer. The view is considered the “dumb” part of your app, since
it shouldn’t contain any business logic. In code terms, you’ll
normally see:
UIView subclasses. These range from a basic UIView to complex custom UI controls.
A UIViewController (arguably). Since a UIViewController is strongly coupled with its own root UIView and its different cycles
(loadView, viewDidLoad), I personally consider it to be part of this
layer, but not everyone agrees.
Animations and UIViewController transitions.
Classes that are part of UIKit/AppKit, Core Animation and Core Graphics.
Typical code smells found in this layer manifest in different ways,
but boil down to including anything unrelated to UI in your view
layer. A classic code smell is making a network call from a
UIViewController.
It’s tempting to put a bunch of code in your UIViewController and be
done with it, so you can meet that deadline. Don’t do it! In the short
term, you might save a couple of minutes, but in the long term, you
could lose hours looking for a bug, or have trouble when you want to
reuse code inside one view controller in another.
Third MVVM
Model-View-ViewModel, or MVVM, is an MVC derivation. Conceptually,
it’s similar. The biggest difference is in the communication between
layers, and instead of a controller, you use a view model.
In practice, MVVM shines when it has an FRP framework to support it.
Since the model is now observed by the view model and the view model
by the view, the FRP paradigm becomes a natural choice to manage the
information flow. This leads to a better separation between layers,
which translates in decoupled components that are easy to test.
Bottom line: architecture is important, but in my opinion the right
programming paradigm will influence more the overall quality of your
code. It’s also important to note, that most often that not, you will
have in the same app different approaches. This includes both
architecture and paradigm. You might think this will disrupt
consistency inside the codebase, but you should always use the right
tool for the job.
Finally MVC
The Model-View-Controller (MVC) design pattern assigns objects in an
application one of three roles: model, view, or controller. The
pattern defines not only the roles objects play in the application, it
defines the way objects communicate with each other. Each of the three
types of objects is separated from the others by abstract boundaries
and communicates with objects of the other types across those
boundaries. The collection of objects of a certain MVC type in an
application is sometimes referred to as a layer—for example, model
layer.
MVC is central to a good design for a Cocoa application. The benefits
of adopting this pattern are numerous. Many objects in these
applications tend to be more reusable, and their interfaces tend to be
better defined. Applications having an MVC design are also more easily
extensible than other applications. Moreover, many Cocoa technologies
and architectures are based on MVC and require that your custom
objects play one of the MVC roles.
Difference between Normal and MVVM
Models — responsible for the domain data or a data access layer
which manipulates the data, think of ‘Person’ or ‘PersonDataProvider’
classes.
Views — responsible for the presentation layer (GUI), for iOS environment think of everything starting with ‘UI’ prefix.
Controller/Presenter/ViewModel — the glue or the mediator between the Model and the View, in general responsible for altering the Model
by reacting to the user’s actions performed on the View and updating
the View with changes from the Model.
MVVM Says
The latest and the greatest of the MV(X) kind The MVVM is the newest
of MV(X) kind thus, let’s hope it emerged taking into account problems
MV(X) was facing previously. In theory the Model-View-ViewModel looks
very good. The View and the Model are already familiar to us, but also
the Mediator, represented as the View Model. MVVM It is pretty similar
to the MVP:
the MVVM treats the view controller as the View
There is no tight coupling between the View and the Model In addition, it does binding like the Supervising version of the MVP;
however, this time not between the View and the Model, but between the
View and the View Model. So what is the View Model in the iOS reality?
It is basically UIKit independent representation of your View and its
state. The View Model invokes changes in the Model and updates itself
with the updated Model, and since we have a binding between the View
and the View Model, the first is updated accordingly.
Also the MVVM Design Pattern and How does MVVM work?
Check it out this topic -> What is the difference between MVC and MVVM?
Model-View-ViewModel basic example is here -> https://github.com/futurice/mvvm-example-objc and maybe next step, you can use reactive cocoa because it can be more effective with mvvm -> https://github.com/ReactiveCocoa/ReactiveViewModel
reactive cocoa -> https://github.com/ReactiveCocoa/ReactiveCocoa
goodluck :)
I have for one customer entity multiple viewmodels depending on the existing views like Create,Update,Get,Delete. These viewmodels share the same properties up to 75% with the entity.
Should I better merge all the customer viewmodels to one big viewmodel?
So I have to map only and always from one entity to one viewmodel and the way back?
Do you see any disadvantage in flexibility for certain scenarios I have not in my mind now?
In the long run, keeping them separate will be better because while the data contained in each ViewModel may be similar or even identical, the intention is different. For example, the Create and Update ViewModels are certainly similar, but have a few important differences. First, the Create view model usually doesn't have the identity of the entity and having it there may be confusing since it doesn't make sense. Second, if the application supports partial updates, the update ViewModel may be a collection of changes to an existing entity, not the entity as a whole.
If you are striving for DRY you can achieve re-usability by means other than sharing the entire ViewModel class. Instead, you can create smaller re-usable components and re-use by composition instead of inheritance. Attempting to coerce a single ViewModel class to fulfill all requirements will be buggy beacause the code is more difficult to reason about. Many times, simple copy & paste gets the job done better than what OOP offers.
On one hand, splitting up the ViewModels as you describe makes your code base really clear, as you can make sure each ViewModel is exactly fit for purpose and has no unnecessary properties. On the other hand, it means that you have more code to maintain - a change to your entity may well mean changes to several ViewModels.
On the other hand, the one big ViewModel approach has basically exactly the opposite pros and cons - less code to maintain, but the ViewModels are less fit for purpose.
There isn't really a right or wrong answer here, you've got too weigh up the pros and cons of each approach and decide what will work best for you.
One sort of halfway approach is to have a single ViewModel for Create/Update, one for Retrieve and one for Delete, as the Create/Update are likely to be very similar.
Another, most OO option for you lies in good old inheritance: define common functionality between actions in one class MyVM and extend it (inherit from it) as you see fit for different actions: MyVMEdit, MyVMDelete, MyVMCreate, `MyVMList'.
This is the best of both worlds: you only maintain things once, and you extend them to fit precisely to every view.
There is no right approach here, since its not a math, any approach you take that gets job done will get the job done :) But ... sometimes we carried away from our roots too far :) its pure good old Object Oriented approach.
If inheritance (or extension) poses any issues (for any reason), you can embed MyVM portion inside every MyVM<Action> model and achieve the same level of abstraction / functionality balance.
As usual - right tool for the right job.
Hope this will help you.
Just curious why ManagedObjectContexts should be passed to UIViewControllers when they are created, rather than just grabbing them from a UIApplicationDelegate?
The docs say that this makes your applications more rigid, but I am failing to see the nuances of when to use which pattern.
Thanks!
Imagine that I ask you to do some task, like painting a room. If I just tell you "go paint a room," you'll need to ask me a lot of questions, like:
Which room?
Where's the paint?
Where are the brushes?
Should I use a dropcloth?
In short, you won't be able to complete the task without help from me. If you have to depend on me every time, you won't be a very flexible painter. One way to deal with that problem is for me to give you all the stuff you need at the outset. Instead of "go paint a room," I'll say "please paint room number 348 using this bucket of paint and this brush, and don't bother with a dropcloth." Now, you've got everything you need, and you can get right to work with no further help from me. You're a much more flexible worker because you no longer depend on me.
The same thing applies to view controllers (and objects generally); it's better to give them everything they need than to have them depend on a particular object like the app delegate. It's true not just for managed object contexts, but for any information they need to do their job.
This is mainly because you want to use dependency injection with your UIViewControllers instead of just grabbing everything from UIApplication, this keeps your delegate clean instead of full of reference hacks.
This is also to keep with the MVC pattern:
Model
View Controller (Only for view logic)
Controller (For coordinating between the view and the model)
I tend not to agree with this pattern.
First of all I try to treat Core Data as an implementation detail, and as any implementation detail it should be hidden behind a good facade. The facade is the interfaces I expose for my model objects. For example if I have two model objects; Cource and Student, any cource can have a number of students. I do not want to let the controller take upon the duty to setup predicates and sort descriptors, and jump through all Core Data hoops just to get a list of students for a particular class. There is a perfectly valid way to expose this in the model:
#interface Cource (StudentAccess)
-(NSArray*)studentsStortedByName;
#end
Then implement the ugly stuff once and for all in the Model class. Hiding all the complex details of Core Data, and no need to pass around managed object contexts. But how would I find the sources, it has to start somewhere right? Yes, it does but you need not expose it to the controller. Adding methods such as these are perfectly reasonable as well:
#interface Cource (CourceAccess)
+(Cource*)caurceByID:(NSString*)courceID;
+(NSArray*)allCources;
+(NSArray*)courcesHeldByTeacher:(Teacher*)teacher;
#end
This also helps in minimizing dependencies between controllers. And reducing he dependencies between the model and controller. Assuming I have a CourceViewController and a StudenViewController is I did not hide the Core Data details behind a facade and wanted to pass around the managed object context as well, then I would end up with a designated initializer like this:
-(id)initWithManagedObjectContext:(NSManagedObjectContext*)moc
student:(Student*)student;
Whereas with good a good facade I end up with this:
-(id)initWithStudent:(Student*)student;
Minimizing dependencies behind facades, in favor of dependency injection also makes it much easier to change the internal implementations. Passing around the managed object context encourages each controller to implement their own logic for basic stuff. Take for example studentsSortedByName method. At first it might be sorter by last/first name, if later changed to last/first name sort you would have to go to each and every controller that has sorted students and make the change. Where a good facade method requires you to change in one method, and all controller automagically get the update for free.
The Apple Docs try to foster the most widely applicable and sustainable design patterns.
Dependency injection is preferred because it allows for the most flexible, expandable, reusable and maintainable design.
As apps grow in complexity, using a quasi-singleton like parking the context in the app delegate breaks down. In more complex apps, you may have multiple context tied to multiple stores. You might want the same view-controller/view pair to display data from different context at different times or you may end up with multiple context on different threads/operations. You can't pile all those context up in the app delegate.
If you have a simple app with a single context then using the quasi-singleton with the app delegate can work well. I've used it on several smaller apps in the past without immediate issue but I did hit scalability problems on a couple of apps when the apps grew overtime.
Which pattern to use depends on your shipping constraints and you best guesses about of the evolution app over its entire lifecycle. If its a small one shot app, then the app delegate quasi-singleton will work fine. If the app is more complex, might grow more complex or might spawn other related apps that will reuse existing components, then dependency injection is the way to go.
I come from an MVC background (Flex and Rails) and love the ideas of code separation, reusability, encapsulation, etc. It makes it easy to build things quickly and reuse components in other projects. However, it has been very difficult to stick with the MVC principles when trying to build complex, state-driven, asynchronous, animated applications.
I am trying to create animated transitions between many nested views in an application, and it got me thinking about whether or not I was misleading myself... Can you apply principles from MVC to principles from Artificial Intelligence (Behavior-Trees, Hierarchical State Machines, Nested States), like Games? Do those two disciplines play nicely together?
It's very easy to keep the views/graphics ignorant of anything outside of themselves when things are static, like with an HTML CMS system or whatever. But when you start adding complex state-driven transitions, it seems like everything needs to know about everything else, and the MVC almost gets in the way. What do you think?
Update:
An example. Well right now I am working on a website in Flex. I have come to the conclusion that in order to properly animate every nested element in the application, I have to think of them as AI Agents. Each "View", then, has it's own Behavior Tree. That is, it performs an action (shows and hides itself) based on the context (what the selected data is, etc.). In order to do that, I need a ViewController type thing, I'm calling it a Presenter. So I have a View (the graphics laid out in MXML), a Presenter (defining the animations and actions the View can take based on the state and nested states of the application), and a Presentation Model to present the data to the View (through the presenter). I also have Models for value objects and Controllers for handling URLs and database calls etc... all the normal static/html-like MVC stuff.
For a while there I was trying to figure out how to structure these "agents" such that they could respond to their surrounding context (what's selected, etc.). It seemed like everything needed to be aware of everything else. And then I read about a Path/Navigation Table/List for games and immediately thought they have a centrally-stored table of all precalculated actions every agent can take. So that got me wondering how they actually structure their code.
All of the 3D video game stuff is a big secret, and a lot of it from what I see is done with a graphical UI/editor, like defining behavior trees. So I'm wondering if they use some sort of MVC to structure how their agents respond to the environment, and how they keep their code modular and encapsulated.
"Can you apply principles from MVC to
principles from Artificial
Intelligence (Behavior-Trees,
Hierarchical State Machines, Nested
States), like Games?"
Of course. 99.9% of the AI is purely in the Model. The Controller sends the inputs to it, the View is how you represent it on the screen to the user.
Now, if you want to start having the AI control something, you may end up nesting the concepts, and your game 'model' contains a Model for an entity, a Controller for the entity which is the AI sending commands to it, and a View for the entity which represents the perceptions of that entity that the Controller can work with. But that's a separate issue from whether it can 'play nicely'. MVC is about separating presentation and input from logic and state and that aspect doesn't care what the logic and state looks like.
Keep this in mind:
The things which need to react simply have to be aware of the things to which they need to react.
So if they need to know about everything, then they need to know about everything.
Otherwise, -how- do you make them aware? In 3D video games stuff, say first-person shooters, the enemies react to sound and sight (footsteps / gunshots and you / dead bodies, for instance). Note that I indicated an abstract basis, and parts of the decision tree.
It might be wrong in your specific case to separate the whole thing between several agents, and simpler to leave it to one main agent who can delegate orders to separate processes (/begin babble) : each view could be a process which could be told to switch to any (a number of) view by the main agent, depending on what data the main agent has received.
Hope that helps.. Take it all with a grain of salt :)
It sounds like you need to make more use of the Observer/Event Aggregator pattern. If multiple components need to react to arbitrary application events without introducing undue coupling, then using an event aggregator would help you out. Example: when an item is selected, an application event is published, relevant controllers tell their view to run animations, etc. Different components aren't aware of others, they just listen for common events.
Also, the code that makes the view do things (launch animation depending on model/controller state) - that's part of the View itself, so you don't have to make your architecture weird by having a controller and a viewcontroller. If it's UI specific code, then it's part of the view. I'm not familiar with Flex, but in WPF/Silverlight, stuff like that would go into the code-behind (though for the most part Visual State Manager is more than enough to deal with state animations so you can keep everything in XAML).