knowing that in typical MVC implemented iOS projects the Model, view, Controller will communicate in the below patterns.
View to Controller using IBActions, Delegation
Controller to Model using direct method invocations or call backs using blocks
Model to Controller using Delegation or KVO
Controller to View using IBOutlets
correct me if i was wrong anyplace.
My question is how this would happen in a typical MVVM implemented Projects.I want the best communication approaches between components & please justify also how a particular one is better than others if anything has more than one way of communication availability.for example (Delegation & callBacks) mostly its preferable going with Call backs for more precise & readable code.
I will also up vote those who gives me the best answer.
Data Flow describe the communication of elements in MVVM:
Data Flow
1. UI calls method from ViewModel (Presenter).
2. ViewModel executes Use Case.
3. Use Case combines data from User and Repositories.
4. Each Repository returns data from a Remote Data (Network), Persistent DB Storage Source or In-memory Data (Remote or Cached).
5. Information flows back to the UI where we display the list of items.
In this article, there is a more detailed description of MVVM
https://tech.olx.com/clean-architecture-and-mvvm-on-ios-c9d167d9f5b3
First of all, I agree with you about what you pointed out about MVC. I just want to make a discussion about MVC and MVVM from my point of views
From the architecture point of view, in the typical MVC setup, Models represent data, Views represent user interfaces, and View Controllers mediate the interactions between the V and M. The relationships between VC and V, VC and M are tight coupling. Moreover, from that setup, VC will handle a lot of logics and become massive due to over responsibilities.
In MVVM, VC and V are be treated as a component, M still works as it is in MVC. The new component VM, which encapsulates data/logics that the V can bind to and any logics and action can be performed. The connection between V and VM is loose coupling. Why? because the V keeps referent of VM, however, the VM doesn't know the V and it just can be communication with the V via binding system.
From the advantages of MVVM in application development point of view, in which it comes with several benefits. We can easy to write Unit Test to test the logic of VM. We can easy to modify the V (UI) due to now it is just binding to VM.
Related
So, I am currently refactoring a really large project to VIPER architecture and most of its module's views are UITableViews. I discovered almost every topic on the internet about VIPER and UITableView, but one thing remains unclear: where should I store ViewModel and do I really need them?
For example, I have simple VIPER module with UITableViewController and I need to present list of items. Interactor fetches JSON with array of some items which I decode to Codable structs. Then I push array of this structs from interactor back to presenter via InteractorOutput protocol. And now I have two questions:
Do I have to use another data model (ViewModel) to show data in view, or can I go with already existing Codable Struct?
Where should I store my ViewModels? Inside Presenter and ask for the data from the View like this: presenter.getData(forItemAt: indexPath.row). Or I have to push array of ViewModels to View and ask View to show them?
As described in https://TheSwiftDev.com/the-ultimate-viper-architecture-tutorial,
The UITableView is quarantined within the view zone.
There are no view models per se. That purpose of other architectures is carved up differently in VIPER, mainly in the presenter zone but without overt knowledge of the view itself (instead focusing on the business-rules of the use-case). A UI-view in the VIPER view zone conforms to at least one use-case. The data flowing from interactor zone (acquisition/storage) through presenter zone (business/app-domain rule-enforcement/processing) to view zone (and vice versa) is modeled without direct knowledge of the specific OS's specific UI constructs & their parameter needs. When crossing VIPER zones, the entities are modeled as if portable (even if not yet) to other UIs on other OSes. For example, when developing for iOS/iPadOS/WatchOS apps, the interzone exchange of events & data/entities is done so that they are at least agnostic of the peculiarities of iOS/iPadOS/WatchOS UI view constructs & parameters thereof so that the 4 VIPER zones other than view & router {interactor, presenter, entities} remain unchanged in a MacOS version of the same app. With care (e.g., Swift on all non-Apple platforms; OpenCombine framework instead of Apple Combine framework for interzone effect-reactive dataflow) this concept can be extrapolated to Android & UWP version of the app as well, but the Apple-centric portions of interactor zone would need to change as well, which is the reason for quarantining each topic compartmentalized in a zone so that it does not contaminate other zones (as seen is Massive View Controller architecture).
The presenter zone should have no knowledge of or access to UITableView constructs at all. Hence, presenter.getData(forItemAt: indexPath.row) would be replaced with the presenter working on a collection of entities where the collection of entities might get UI-viewed in view zone as a UITableView on iOS/iPadOS/WatchOS but get UI-viewed quite differently on MacOS or Android or UWP, perhaps not as a table at all, but rather as a 2D array of icons/choices to router to navigate. Your “Or [do] I [need to] have to push array of ViewModels to View and ask View to show them?” is nearly hitting the nail on the head, except that VIPER architecture does not use the term ViewModel there; use the word entity instead (i.e., purely app-domain entities divorced from UI and from OS).
Codable is an interface within Apple's JSON processing. Hence, it would need to be quarantined within interactor zone for portability (real or anticipated-for-good-mental-hygiene) to nonApple OSes. The input from (and output to) JSON interactor would need be expressed in entities that are purely app-domain without knowledge of a nonportable framework such as Codable in SwiftUI. There would need to be a conversion from Apple-centric ways of representing JSON processing's output to the purely app-domain ways of representing those equivalent entities.
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 found it difficult to argue with anything in this critique of ASP.net MVC's framework for page composition.
http://www.matlus.com/problems-with-asp-net-mvc-framework-design/
Particularly these points:
No access to view or partial view instances
ViewData is your loosely typed information carrier
Controller is not really in control
Child Actions have no sense of the Request Context
Views are coupled to controllers
For small applications, I don't think that a lot of these prove to be much of a problem, but in large applications where you want to reuse a lot of shared components, or even if you just have a large application that depends on multiple backend sources of information to obtain all of the information necessary to render a view, it starts to break down.
Various half-solutions to these problems have been proposed but they do not appear to scale well or have undesirable design constraints.
Here is an example application scenario:
50% of page content is common across all pages within an application (header, footer, menus, etc.)
Your application may actually be comprised of multiple areas, each with their own controllers, etc. for independent development.
A number of the page elements (menus, page header information, footers, disclosures) that are in the common page content require one or more service calls to fill out the data for rendering.
Okay, so in asp.net mvc3, let's say that you decide that you want to share a common Razor layout that contains the 50% common UI markup. This assists with Separation of Concerns in that application developers don't need to be concerned about common ui and can focus on the logic and views specific to their domain of expertise.
However, this completely breaks down in the case that this shared layout needs data (some semblance of one or more model types) to render itself completely. You may have independent elements on the page that each need a particular data model, such as:
* primary menu model
* secondary menu model
* footer links model
* authorization model
* footer disclaimers model
And each of these models may have separate sources. So although you can share the template, there is not an easy way to share the logic to build each of these models -- and there is definitely not one that is generic, extensible, and performant that I have seen.
Some approaches to this problem that I have seen are:
Strongly type the common layout, which requires all view models to subclass a common base model class. (but there is no general solution to populating such a meta-model, and this is limiting in design and makes models huge and harder to test) Additionally, model population still falls to every controller, violating the Separation of Concerns and Single Responsibility Principle and complicating unit testing controllers by piling on lots of extra logic to populate the meta-model in addition to the view-specific model information.
Leave the common layout untyped, so you don't have to inherit from a common base model, but this requires you to use ViewData or ViewBag to communicate all of the disparate models that the template needs so you lose strong typing benefits and end up with a loose data contract. You still have the problem of a lack of a general solution to populating the meta-model and all that goes along with that.
Every controller has to subclass a common base controller class to support a common layout and model. Logic for building the common aspects of the meta-model goes here. But this is not always a desirable architecture or design constraint. This does at least resolve the Separation of Concerns issues.
Instead of a meta-model, use child actions via RenderAction() in your common layout to make reusable "portlet" style widgets that each know independently how to build their data model and provide it to their view. This is really good for Separation of Concerns, but has its own litany of downsides: views effectively making service calls during rendering via the child actions, child actions are completely unaware of the original request context, violates DRY principle as each child action is unaware of what has gone before it so each could make the same service calls over and over again in the same http request, and others. Imagine 20-30 elements of a page that all needed to invoke RenderAction() independently...
There are additional cases (some seen on stackoverflow as well) where there are other problems with RenderAction() as a solution. e.g. the fact that issuing multiple RenderAction() calls in a loop results in serial execution of all of those controller methods. There is no opportunity for parallelism with RenderAction(). I/O bound service calls in each child controller action cause the whole rendering process to wait on I/O. A controller only has knowledge of its immediate view and model and nothing has a complete picture of what is going to be inside the view in order to parallelize some operations.
The author of the above critique developed a different UI model on top of ASP.Net mvc called Quartz that allows a God Controller to have intimate knowledge of the views and can hand each of them a view model so has the opportunity to parallelize service calls in a central place to build those view models. I don't know if this is the best design to provide hooks for overcoming the problems but looks promising.
My question is, what is the best practice for building a complex application on top of ASP.Net MVC that cleanly solves these problems? I have thought of a couple possibilities (although none may be practical within ASP.Net MVC--that is TBD) but someone else must have ran into this already. What are the design patterns within ASP.Net MVC or what is coming down the pike that could make this a tractable problem?
Personally, I think that the advantages of using Child Actions via RenderAction outweigh the disadvantages.
You can create 'widget' sort of elements, and wrap up their logic in a controller action - this way the view calling the widget can remain quite ignorant of what the Child Action is doing and how it is doing it - leading to a nice separation of concerns.
You have detailed the disadvantages of this approach, however I think that the negative impact can be minimised with a reasonable caching strategy.
I'm not sure there's really much more I can contribute to this "question". I think you have a good understanding of the problems and solutions, advantages and disadvantages.
In the app I'm currently working on, we utilize a couple of these approaches by having both a base model object as well as a base controller. In order to minimize roundtrips, we store some data in session and re-populate in the model by overriding the OnActionExecuted in the base controller and grab the model out of the context and set properties out of session.
I'd certainly like to hear any wonderful solutions as well, but I think these are just the tradeoffs to deal with.
I am looking for some guidance on how to incorporate business rules into an asp.net mvc application and how they relate to the model.
First a little background so we know what kind of solutions are relative for this question. At work we use WinForms, MVP, BusinessObjects, DataAccessObjects, and DataTransferObjects. The boundaries of the layers use DTOs to send parameters to methods and as return types, or return List types.
Right now we are adding a facade layer to translate the DTOs into Domain Objects for the UI to work with, since the architect does not like how using DTOs in the PresentationLayer is working currently. I am comfortable about all of this in theory aside from it being practical or not.
I am making a website for fun, but for considerations lets say it serves the same amount of traffic as SO, something like 60,000 hits a month last I heard. I am comfortable with the mechanics of the controllers and the views, and how the model integrates with the two.
I am using NerdDinner as a sample for building the site and I follow the Repository pattern implementation in the examples. What I don't get is how to incorporate business objects into the mix.
I hear people talk about LINQ as the DataAccessLayer/DataAccessObjects. If I force all of my requests though the business objects as I am used to I have introduced some weird dependencies. Both my UI and my BO have to know about my DAO.
What would kind of make sense is to use the LINQ classes as a true DAO layer, hide it behind the BO, and have the BO transform between POCO and LINQ objects.
My only concern there is I am fine with binding my UI to LINQ classes, and don't really need all the extra work, I am happy with a thin lightweight approach as in NerdDinner.
So what I have essentially is the Repository that is instantiated in the controllers that takes and return LINQ objects. My business objects have static methods that just take LINQ classes and perform some calculation, say apply a certain states tax %, or w/e.
Since a lot of these calculations have to be done across the results of the repository I am thinking of combining them into one central area, like a facade layer, but one that just does transforms against the data and not translating to other objects sets (DomainObjects <-> DTOs).
Should I do that, or should I say that those business methods really are part of my model and that they should be in the repository methods that return the objects?
From a design standpoint I would design it like this. Of course naming is just for the purpose of this post you don't have to name your DAL and BLL ..Repository and ..Service.
Have repositories (or one) where your data access/queries should be happening. It should ideally just contain queries (compiled or not). I personally have a repository for each data type to help keep queries separated.
The next layer should be your business layer which I like to call services. These classes are responsible for all logic regarding validation, prep steps and anything else needed to be done to get the consumer of the service the information it needs. As with an ASP.NET MVC app I have my services return view models which are then directly passed into strongly-typed views. With my services I usually group them logically together instead of one for each data type.
This is a great design because it keeps your data access code and presentation code nice and thin and most of the logic where things can go wrong is in your service (or business) layer.
My controllers turn over the request to the appropriate service. The Service then makes calls to various Repositories. Repositories use Linq to Sql Entities purely for DataAccess and then map and return as Domain Objects. The service then decides what the Controller will present and replaces the DO with Presentation objects which are returned to the Controller to display in View.
SO I have Services-Repositories-Domain Objects- Presentation Objects
I am asking because it seems like i have a lot of objects, some not doing anything but passing data. Is this a reasonable scenairo or am i not following proper MVC pattern?
Yes, you've got the right idea. It can be a lot of classes and interfaces (not even counting the unit tests and mock/test classes) but if you have a decent sized application, you're libel to have many anyway. But to start out, it's a lot of work for not much initial gain.
I have seen projects skip the some of the services implementations for basic services that just pass through to the repository without any value added by the service. They go straight to the repository from the controller and don't seem to lose much.
There are other ways to ease the burden of some classes by using tools where possible. For example, projects like AutoMapper can help streamline your domain object to view model mappings.
If your application is big enough, your pattern makes sense. Otherwise, I smell overengineering...
Ask yourself: what if this layer didn't exist and you'll find out if it's true or not.
I had a very similar scenario. Initially my project had UI, Controllers, Service Layer and Repositories. My unit tests covered both the service layer and repositories (filters) and in some cases the unit tests were doing the same thing (as the service layer was sometimes a pass through to the repositories).
Due to a large refactor I cut out the service layer and this gave me a lot of flexibility with the Controllers dealing directly with the Repositories and applying Filters to get exactly what I want.
One problem I ran into was you cannot Serialize Linq2Sql objects and therefore sometimes had to translate these object to presentation objects.