Privacy Notice

This website uses cookies to create the best experience for you.

Learn more: Privacy Policy .

This site requires your consent to acknowledge and accept the use of cookies.

⚠ Note: some features such as interactive comments and discussions require cookies. Choosing not to consent will disable those features. You can return to the Privacy Policy at any time to opt in.

Developer for Life

Code all the things.

Jeremy Likness

Model-View-ViewModel (MVVM) Explained

Data-binding still delights after a decade

The purpose of this post is to provide an introduction to the Model-View-ViewModel (MVVM) pattern. While I’ve participated in lots of discussions online about MVVM, it occurred to me that beginners who are learning the pattern have very little to go on and a lot of conflicting resources to wade through in order to try to implement it in their own code. I am not trying to introduce dogma but wanted to pull together key concepts in a single post to make it easy and straightforward to understand the value of the pattern and how it can be implemented. MVVM is really far simpler than people make it out to be.

This post was originally written in 2010 with Silverlight examples. The current article has been updated to use modern examples. If you’re interested, you can read the original at CodeProject.

For a more recent look at the patterns behind MVVM, read:

The Three D’s of Modern Web Development

Learn the history of and decompose modern JavaScript frameworks like Angular, React, and Vue by learning about dependency injection, declarative syntax, and data-binding.

Why Care About MVVM

Why should you, as a developer, even care about the Model-View-ViewModel pattern? There are a number of benefits this pattern brought to WPF and Silverlight development, and are now reflected in modern front-end JavaScript frameworks (often called _MV*_ when they don’t explicitly provide a viewmodel). Before you go on, ask yourself:

  • Do you need to share a project with a designer, and have the flexibility for design work and development work to happen near-simultaneously?
  • Do you require thorough unit testing for your solutions?
  • Is it important for you to have reusable components, both within and across projects in your organization?
  • Would you like more flexibility to change your user interface without having to refactor other logic in the code base?

If you answered “yes” to any of these questions, these are just a few of the benefits that using the MVVM model can bring for your project.

I’ve been amazed at some conversations I’ve read online. Things like, “MVVM only makes sense for extremely complex UI” or “MVVM always adds a lot of overhead and is too much for smaller applications.” The real kicker was, “MVVM doesn’t scale.” In my opinion, statements like this speak to knowledge and implementation of MVVM, not MVVM itself. In other words, if you think it takes hours to wire up MVVM, you’re not doing it right. If your application isn’t scaling, don’t blame MVVM, blame how you are using MVVM. Binding 100,000 items to a list box can be just silly regardless of what pattern you are following.

So the quick disclaimer: this is MVVM as I know it, not MVVM as a universal truth. I encourage you to share your thoughts, experiences, feedback, and opinions using the comments. If you feel something is incorrect, let me know and I’ll do my best to keep this post updated and current.

MVVM at a Glance

Let’s examine the pieces of the MVVM pie. We’ll start with the basic building block that is key for all applications: data and information . This is held in the model.

The model

The model is what I like to refer to as the domain object. The model represents the actual data and/or information we are dealing with. An example of a model might be a contact (containing name, phone number, address, etc.) or the characteristics of a live streaming publishing point.

The key to remember with the model is that it holds the information, but not behaviors or services that manipulate the information. It is not responsible for formatting text to look pretty on the screen, or fetching a list of items from a remote server (in fact, in that list, each item would most likely be a model of its own). Business logic is typically kept separate from the model, and encapsulated in other classes that act on the model. This is not always true: for example, some models may contain validation.

It is often a challenge to keep a model completely “clean.” By this I mean a true representation of “the real world.” For example, a contact record may contain a last modified date and the identity of the modifying user (auditing information), and a unique identifier (database or persistence information). The modified date has no real meaning for a contact in the real world but is a function of how the model is used, tracked, and persisted in the system.

This is a simple example of a model expressed as a JSON (JavaScript) object. The model contains a list of items and associated prices.

The view

The view is what most of us are familiar with and the only thing the end user really interacts with. It is the presentation of the data. The view takes certain liberties to make this data more presentable. For example, a date might be stored on the model as number of seconds since midnight on January 1, 1970 (Unix Time). To the end user, however, it is presented with the month name, date, and year in their local time zone. A view can also have behaviors associated with it, such as accepting user input. The view manages input (key presses, mouse movements, touch gestures, etc.) which ultimately manipulates properties of the model.

In MVVM, the view is active. As opposed to a passive view which has no knowledge of the model and is completely manipulated by a controller/presenter, the view in MVVM contains behaviors, events, and data-bindings that ultimately require knowledge of the underlying model and viewmodel. While these events and behaviors might be mapped to properties, method calls, and commands, the view is still responsible for handling it’s own events and does not turn this completely over to the viewmodel.

One thing to remember about the view is that it is not responsible for maintaining its state. Instead, it will synchronize this with the viewmodel.

Here is how to define a view using the legacy Angular.js framework.

Notice that it uses valid HTML that is extended with features like data-binding to properties ( {{selected.name}} ) and functions ( ng-click ). The model contains a list, but it’s the view that defines how that list is rendered using the ng-repeat directive. The model contains a number in selected.price but it is passed through a currency filter to display as money.

The ViewModel (Our Controller/Presenter)

The controller

The viewmodel is a key piece of the triad because it introduces Presentation Separation , or the concept of keeping the nuances of the view separate from the model. Instead of making the model aware of the user’s view of a date, so that it converts the date to the display format, the model simply holds the data, the view simply holds the formatted date, and the controller acts as the liaison between the two. The controller might take input from the view and place it on the model, or it might interact with a service to retrieve the model, then translate properties and place it on the view.

The viewmodel also exposes methods, commands, and other points that help maintain the state of the view, manipulate the model as the result of actions on the view, and trigger events in the view itself.

MVVM, while it evolved “behind the scenes” for quite some time, was introduced to the public in 2005 via Microsoft’s John Gossman blog post about Avalon (the code name for Windows Presentation Foundation, or WPF). The blog post is entitled, Introduction to Model/View/ViewModel pattern for building WPF Apps and generated quite a stir judging from the comments as people wrapped their brains around it.

I’ve heard MVVM described as an implementation of Presentation Model designed specifically for WPF (and later, Silverlight).

The examples of the pattern often focus on XAML for the view definition and data-binding for commands and properties. These are more implementation details of the pattern rather than intrinsic to the pattern itself, which is why I offset data-binding with a different color:

Simple MVVM Diagram

Here is what a sample viewmodel looks like, expanding our Angular.js example.

The viewmodel exposes the model as a value named list and sets the list to a scope that then participates in real-time data-binding. The pick method is used to select an item from the list for display in the view that was defined earlier.

For larger applications, I prefer to wire in references externally or use a dependency injection framework. Learn more about dependency injection here:

Dependency Injection in Javascript 101

Large JavaScript projects may have dozens or even hundreds of related components interacting with each other. Managing dependencies between components can become incredibly complex if you aren't taking advantage of dependency injection. Learn what DI is and how to implement it with a simple reference application.

What’s nice is we have the flexibility to build it like this initially and then refactor as needed - again, you do not have to use any of these frameworks to take advantage of the pattern, as you can see from this example. It fetches the list right away, which is a hard-coded list of values.

Putting it Together

Let’s get a little more specific and look at how this would be implemented in a sample application. Here is what an X-ray of a sample MVVM set up may look like:

MVVM X-Ray

So what can we gather from this snapshot?

First, the IConfig represents a configuration service (in a newsreader it may contain the account information and feeds that are being fetched), while the IService is “some service” - perhaps the interface to fetch feeds from RSS sources in a news reader application.

The View and the ViewModel

  • The view and the viewmodel communicate via data-binding, method calls, properties, events, and messages
  • The viewmodel exposes not only models, but other properties (such as state information, like the “is busy” indicator) and commands (functions that are called to handle events)
  • The view handles its own UI events, then maps them to the viewmodel via commands
  • The models and properties on the viewmodel are updated from the view via two-way data-binding

The ViewModel and the Model

The viewmodel becomes wholly responsible for the model in this scenario. Fortunately, it’s not alone:

  • The viewmodel may expose the model directly, or properties related to the model, for data-binding
  • The viewmodel can contain interfaces to services, configuration data, etc. in order to fetch and manipulate the properties it exposes to the view

The Chicken or the Egg

You might have heard discussion about view first or viewmodel first. In general, I believe most developers agree that a view should have exactly one viewmodel. There is no need to attach multiple viewmodels to a single view. If you think about separation of concerns, this makes sense, because if you have a “contact widget” on the screen bound to a “contact viewmodel” and a “company widget” bound to a “company viewmodel”, these should be separate views, not a single view with two viewmodels.

A view may be composed of other views, each with its own viewmodel. Viewmodels might compose other viewmodels when necessary (often, however, I see people composing and aggregating viewmodels when in fact what they really want is messaging between viewmodels).

While a view should only have one viewmodel, a single viewmodel might be used by multiple views (imagine a wizard, for example, that has three views but all bind to the same viewmodel that drives the process).

Complete Examples

This is the complete example using Angular.js:

Click to view the fiddle.

To compare, here is a different example using Vue.js :

And finally, an example using plain Vanilla.js :

What MVVM Isn’t

No discussion would be complete unless we talked about what MVVM isn’t.

MVVM isn’t a complete framework. It’s a pattern, and might be part of a framework, but it’s only a piece of the overall solution for your application architecture. It doesn’t address, and doesn’t really care, about what happens on your server or how your services are put together. It does stress separation of concerns, which is nice.

I bet that nowhere in this article did you read a rule that stated, “With MVVM, code-behind is not allowed”. This is a raging debate, but the pattern itself doesn’t tell you how to implement your view, whether that is with XAML, HTML, code-behind, JavaScript, or a combination of everything. I would suggest that if you are spending days writing something just to avoid minutes of code-behind, your approach is wrong.

It is not required for all applications. I believe that line-of-business, data-driven, and forms-based applications are prime candidates for MVVM. Games, entertainment websites, paint programs, and others may not make sense. Be sure you are using the right tool for the right job.

MVVM is not supposed to slow you down! All new patterns and frameworks come with a learning curve. You’ll have to accept that your developers need to learn and understand the pattern, but you should not accept that your entire process suddenly takes longer or becomes delayed. The pattern is useful when it accelerates development, improves stability and performance, reduces risk, and so forth. When it slows development, introduces problems, and has your developers cringing whenever they hear the phrase “design pattern”, you might want to rethink your approach.

Hopefully this helps illustrate what MVVM, why it is useful, and helps you better understand modern frameworks that are based on the _MV*_ paradigm.

Appendix: Before MVVM

MVVM is fairly recent in the longer history of design or view patterns. Here are a few older and popular patterns with illustrations.

Model-View-Controller (MVC)

This software architecture pattern was first described in the context of Smalltalk at Xerox in 1979. If you are interested, you can download some of those original papers (PDF format) by clicking here (PDF) .

MVC

Model-View-Presenter (MVP)

In 1996, the Model-View-Presenter pattern ( PDF ) was introduced to the world. This pattern builds on MVC but places special constraints on the controller, now called the presenter. A general overview looks like this:

MVP

Martin Fowler describes this pattern with two flavors: the Supervising Controller/Presenter and the Passive View .

Presentation Model

In 2004, Martin Fowler published his description of the Presentation Model . The summary is quite succinct: “Represent the state and behavior of the presentation independently of the GUI controls used in the interface.” As you can see, MVVM is a specialized form of this pattern:

Presentation Model

Thanks for reading! Please share your thoughts and feedback below.

  • Design Pattern
  • Model View ViewModel

Let's Connect!

Support Parkinson's Disease   Parkinson's Disease Blog    @JeremyLikness    JeremyLikness    MrLikness    JeremyLikness    cdaJeremyLikness    @JeremyLikness

Try these articles

DEV Community

DEV Community

Geoffrey Kim

Posted on Jul 7, 2023

Mastering MVVM: A Comprehensive Guide to the Model-View-ViewModel Architecture

Introduction to mvvm.

Model-View-ViewModel (MVVM) is a software architectural pattern that facilitates the separation of the development of the graphical user interface from the business logic or back-end logic (the data model). The View Model in MVVM represents an abstraction of the View, which contains a View's state and behavior.

Understanding the Components of MVVM

The Model in MVVM represents the data and business logic of the application. It is responsible for retrieving data, processing it, and defining how the data can be changed and manipulated.

The View is responsible for defining the structure, layout, and appearance of what users see on the screen. Ideally, the View is purely declarative, meaning it defines "What" but not "How".

The ViewModel in MVVM architecture serves as a bridge between the Model and the View. It's responsible for handling the logic for the UI and acts as an abstraction of the View, which contains a View's state and behavior.

The ViewModel communicates with the Model and converts its data into a format that can be easily managed and presented by the View. This conversion includes implementing properties and commands to which the View can bind to, enabling the View to remain isolated from the complexities of the business logic or back-end logic.

In terms of managing the UI's state and behavior, the ViewModel exposes data-binding friendly properties and commands for the View to use. These properties and commands provide a way for the View to update in response to changes in the Model's state and react to user interactions, respectively. This means that the ViewModel handles all UI actions by using command patterns and can also manage navigation, dialog, and other UI services.

By doing so, the ViewModel enables a clean separation of concerns between the UI and business logic, improves testability, and allows for more efficient code reuse and parallel development.

Advantages of MVVM

MVVM has several advantages that make it an attractive choice for software development, particularly for applications with complex user interfaces.

Clear Separation of UI and Business Logic : MVVM provides a clear separation between the User Interface (View) and the business logic or back-end logic (Model). This separation makes it easier to work on the UI and the business logic independently of each other. For example, a UI designer can focus on improving the user interface without having to understand the underlying business logic, and vice versa.

Improved Maintainability : With the separation of concerns provided by MVVM, changes in one component (Model, View, or ViewModel) have minimal impact on the others. This isolation makes the codebase easier to maintain and extend over time. For instance, changing the business logic in the Model does not require changes in the View.

Enhanced Testability : The separation of components in MVVM also improves testability. The ViewModel can be tested independently of the UI and the data access layers, making unit testing easier and more robust.

Efficient Code Reuse and Parallel Development : The ViewModel in MVVM can be reused across multiple views, or even across different platforms (in the case of cross-platform development frameworks like Xamarin or Flutter). This reuse can lead to significant time savings and increased consistency across the application. Additionally, since the Model, View, and ViewModel are decoupled, different teams can work on them in parallel, speeding up the development process.

Data Binding : The data binding between View and ViewModel allows for automatic propagation of changes, which means that when data changes in one place, it is updated everywhere it's referenced. This leads to less boilerplate code and a single source of truth, making the code cleaner and easier to understand.

By understanding these advantages, developers can make more informed decisions about when to use the MVVM architecture and how to best leverage its strengths.

Implementing MVVM in Practice

Implementing MVVM requires a good understanding of data binding and observable patterns. In the context of MVVM:

Data Binding : This is the connection between the ViewModel and the View. It ensures that changes in the ViewModel are automatically reflected in the View.

Observable Patterns : These are used to notify the View of any changes in the ViewModel.

Now, let's walk through a simple example of implementing MVVM in a Flutter application, which will demonstrate these concepts in action.

First, let's define our Model. In this case, let's say we have a simple User model:

Next, we'll create our ViewModel. The ViewModel will have a User object and a method to change the user's name. Here, we use the ChangeNotifier class to implement the observable pattern:

Finally, we'll create our View. In Flutter, this could be a widget. Here, we use the ChangeNotifierProvider and Consumer widgets to implement data binding:

In the View, we use the Consumer widget to listen for changes in the ViewModel and update the UI accordingly. When the ViewModel calls notifyListeners() , it triggers a rebuild of the Consumer widget, effectively updating the View.

This is a very basic example, but it demonstrates the key concepts of MVVM in practice, including data binding and observable patterns.

Understanding and implementing the Model-View-ViewModel (MVVM) architecture can greatly improve the quality of your code and your productivity as a developer. It provides a clear separation of concerns, improves maintainability and testability, and allows for efficient code reuse and parallel development.

However, like any architectural pattern, MVVM is not a one-size-fits-all solution. It's important to understand its strengths and weaknesses and when it's appropriate to use it.

MVVM shines in applications where you have complex user interfaces and where a clear separation between the UI and the business logic can lead to cleaner, more maintainable code. It's particularly useful in scenarios where you want to reuse logic across multiple parts of an application or even across different platforms.

On the other hand, for simple applications with minimal UI complexity, using MVVM might be overkill. For example, if you're building a straightforward application with only a few screens and minimal business logic, such as a calculator app, the overhead of setting up the Model, View, and ViewModel and the data bindings between them might not be worth it.

Furthermore, MVVM relies heavily on data binding and observable patterns. If you're working in a framework or language that doesn't support these features well, implementing MVVM can be challenging. For instance, if you're working with a legacy codebase in a language that doesn't have built-in support for data binding or observables, it might be more efficient to use a simpler architectural pattern or to refactor the codebase to a more modern language or framework before attempting to implement MVVM.

In conclusion, MVVM is a powerful architectural pattern with many benefits, but it's not always the best choice. As a developer, it's important to understand the needs of your specific project and choose the architecture that best fits those needs.

Top comments (0)

pic

Templates let you quickly answer FAQs or store snippets for re-use.

Are you sure you want to hide this comment? It will become hidden in your post, but will still be visible via the comment's permalink .

Hide child comments as well

For further actions, you may consider blocking this person and/or reporting abuse

javafullstackdev profile image

The Ultimate Mobile App Developer Roadmap for 2024

JavaFullStackDev.in - Aug 6

pushpendra_sharma_f1d2cbe profile image

Message Passing in C++

Pushpendra Sharma - Aug 6

labby profile image

Today's Trending Projects: Sum of Prime Numbers Under 100 and More

Labby - Jul 23

gauravshekhar13 profile image

Asynchronous Non-Blocking REST API Using Java and its impact in Financial Services

Gaurav Shekhar - Jul 22

DEV Community

We're a place where coders share, stay up-to-date and grow their careers.

Stack Exchange Network

Stack Exchange network consists of 183 Q&A communities including Stack Overflow , the largest, most trusted online community for developers to learn, share their knowledge, and build their careers.

Q&A for work

Connect and share knowledge within a single location that is structured and easy to search.

In MVVM, how much of the business logic should reside in the View Model, and how much should reside in the Model?

I wondered what is the "correct" or "intended" interpretation of MVVM? I worked mainly with WPF but I guess it is still relevant to all platforms embracing MVVM architectural pattern.

1. ViewModel as application

  • Model is representation of data+logic for retrieving the data
  • ViewModel is all the application logic and is UI agnostic, where you could in principle have Console application as your View , where concepts of windows, dialogs, docks and other UI elements do not make sense
  • View - any UI, graphical or text-based

2. Model as Application

  • Model is not only representation of data+logic for retrieving the data, but also all specific application logic, from there you just add a bit of work to create a console version of your application
  • ViewModel all the view logic, but abstracted away from the specific UI classes, this will allow the ViewModel to be unit tested without calling UI as you could mock the UIElements
  • View - specific UI layer, preferably "dumb"

I would say that until now I interpreted MVVM as in the first approach, but I increasingly see the evidence that most people use second approach. It seems from very superficial look at AvalonDock for example that they perhaps favour 2nd approach and similarly every developer who implements view-specific command (e.g. opening a dialog from ViewModel ), but abstracted away from UI/View classes also uses 2nd approach.

I know that I should use whatever approach is most feasible, but I have a feeling that I am missing something. Maybe 1st approach is a different pattern altogether and I also wonder what creators of MVVM thought. Also I may face in foreseeable future that I would need to port my WPF application to another platform and can see that 2nd approach could make porting more difficult.

I've also recently realised that understanding original intentions behind designing a framework or pattern will help with clean design of software. E.g where I started to embrace WPF concepts in more detail, the quality of code and design improved. So I want to have clear understanding of intentions behind MVVM and hopefully my design will improve.

Robert Harvey's user avatar

  • 1 MVVM is originally WPF-centric variant of what Fowler calls Presentation Model , where Model is some part of the internal (non-presentation) layer code associated with this view (or views) or use case, while the ViewModel is the Presentation Model, residing in the presentation layer. –  Filip Milovanović Commented Mar 3, 2022 at 14:55

2 Answers 2

To determine the best course of action, one only needs to examine basic principles of OOP, SOLID and Separation of Concerns. Once that is done, the natural order of MVVM becomes obvious.

Applying those principles to MVVM leads one to several natural conclusions:

UI structures that can be represented as XAML should be written as such. Your View should be comprised primarily of XAML. Avoid building your View using code-behind, if you can.

Custom code having to do with direct user interaction can go into the view's code-behind. This includes things like mouse clicks, keystrokes and wheel movements that can not be accommodated automatically by WPF in XAML. However ...

Most UI interaction should get pushed back into the View Model, in the form of Command and Data Bindings, and handled there. This code tends to be more stable and less complex than code-behind, and produces less "spaghetti code."

If it's anything else, it gets handled in the Model.

Model classes tend to be ordinary C# classes, because they don't require data binding properties or tight coupling to UI structures. This makes them much easier to mock, unit test, and apply SOLID principles to improve their overall organizational structure.

So in summary:

  • Push as much logic as you can out of the View (code-behind) and into the View Model.
  • Push as much logic as you can out of the View Model into the Model.

The most common mistake I see in large WPF programs is putting too much of the program's logic into the View Models. This makes the View Models large, multi-responsibility classes that violate SRP. Programmers who write classes like this often have to use #region directives to manage the sheer amount of code.

How much code is too much code in a View Model? A good View Model should have less than 800 lines of code in it, and typically much less than that. If your program logic doesn't have directly to do with the data bindings in your View Model, write model classes and call methods on those classes from your data bindings.

  • Thank you for the fresh take on that. I am definitely guilty of having large ViewModels and the idea of binding directly to the Model is something new to me and I definitely need to rethink how I design my WPF applications –  Piotr Golacki Commented Mar 7, 2022 at 9:28
  • 3 Your UI (the View) will bind directly to the View Model. The View Model will call ordinary methods in the Model. As such, I wouldn't call it "direct binding" to the model as such, unless by that you mean making calls to the model directly from the View Model. –  Robert Harvey Commented Mar 7, 2022 at 11:25
  • Ok that's closer to what I'm doing anyway –  Piotr Golacki Commented Mar 7, 2022 at 11:56

Over ten years I have developed using MVVM and WPF I agree with Robert Harvey.

In the beginning, and I think most developers fall into this pattern, I started with very large view models. In time I realized this was because of the widely used recommendation of delegate commands (e.g. DelegateCommand, ActionCommand) and placing command logic in the view models.

The result of this is that developers also end up writing model code inside the view model, and not purposefully, and it is not good when your view models become many thousands of lines of code with far too many responsibilities.

As time went on and so did my discovery and mastery of MVVM, I realized how important commands are, how important the model layer is, and how important INotifyPropertyChanged is, and how less relevant the view model is.

The largest application I have developed with MVVM is approximately 53,000 lines of code (excluding Xaml) and contains numerous "modules", "areas", services. It is built on top of an extensive framework I developed with many practices at play; Domain Driven Design (domain entities, domain services), imaging code (files, TIF, PDF, TWAIN), extensive data access (SQL Server), and so on. You can infer that this application is part of a larger enterprise application and its framework are much more extensive.

Simply put, from an MVVM perspective, you have a view, a view model both with clear concerns, and everything else is a model. Read this, over, and over, and over, and over until it clicks.

I think a good metric for your mastery of MVVM is to look at any of your view models and answer these questions?

  • Does it have I/O, Network, or data access related code (including abstractions like Entity Framework)?
  • Does it have a lot of logic that has nothing to do with data-binding or view concerns?
  • Does it actually model your view?
  • Is all the command logic in the view model?
  • Is it a lot of code?

For me, I could answer a lot of these questions with 'Yes' for a lot of MVVM applications I have seen, including ones I built. If you were to remove the bulk of this code and push it into separated command classes, you can find that your view models become thin and almost empty of real logic. Then, you look to your commands and say, these can be simplified too, leading to conclude the construction of new model classes.

In the end, you will find your views, view models, and commands are very lightweight and easy to maintain, and your ratio of application code becomes something like 10/5/5/80 (view, view model, command, model).

Let's revisit your original question "In MVVM, how much of the business logic should reside in the view model, and how much should reside in the Model?".

A: Possibly near 0, and possibly near 100%, if you can achieve both.

View models are nearly empty and it is almost entirely the commands that do the real work interacting with the model and view model. Now commands are "part of the view model", even still, this is important to understand.

Here is an architectural diagram from my application.

Now, what is missing from this diagram is the model layer and you see there is a task system. This is simply because I created a special task system to manage the large amount of asynchrony this application requires. But the tasks are models, and they along with commands and other models themselves have the majority of source code for the application.

The average view model in this application has less than 500 lines of code and zero view models greater than 1000 lines of code.

None of the view models have any:

  • I/O, Network, or data access related code or even references to
  • Business logic
  • Command logic
  • Large number of models

If I were to describe their responsibility it would be:

  • Model the view
  • Take dependencies
  • Initialize commands (with dependencies)
  • Use PropertyChanged e
  • Have mostly read and write properties so commands can interact

Here is a typical view model.

It exposes one model, TwainOptions to which the view binds directly to its values because this model is a) part of this application codebase b) supports change notification c) does not require a data template for its type and concluding d) there is no reason to make the view model provide a facade for it or create another view model.

Considering that "commands are part of the view model", but simply encapsulated into their own classes, they do the bulk of work reading and writing property values of both the view model and model classes. I hope you see the prospect here; that the alternative is to have all your command logic in the view model, then it is massive, but rather we have it separated out into various command classes, thus have a maintainable codebase.

To conclude, and I feel my answer is still very bad, I feel that most developers do MVVM wrong. That if your view models are "fat" the application becomes very complex and difficult to maintain.

MVVM is a wonderful pattern, and it still comes with many complexities, but I think the pattern has lost its original definition and meaning as it seems to be very difficult to find good information on it, and thus people still ask this question to this very day.

In short, the view model is simply there to "model the view" and provide a data-binding source that you can interact with from code, but the bulk of your application logic, business logic, data access logic should entirely be in the model layer. How this model layer looks and is organized is up to you.

I will further add that view models have another important purpose, at least in WPF for data templates. You should generally have a view model for each type of data template or visa-vera (unless they're shared) because view models are the construct the view understands. In my application, it is also less common for the view to bind directly to models.

Because: you may or may not control the model. They may not support change notification, therein lies another purpose of the view model, to abstract and provide this. You want views and view models to change together. You want views/view models and models to change independently of one another.

MVVM also gets difficult when you introduce asynchronous programming and multithreading, and you must decide how to handle this, but there are practices for that also such as true asynchronous methods and synchronous library code and letting the UI decide when to run a task (e.g. Task.Run).

The question and answers are complex, I feel I could author an entire book to answer this one simple question you asked.

I hope I provided at least some valuable perspective for you and I hope it helps you greatly.

David Anderson's user avatar

  • 2 great answer, very informative thank you! –  Piotr Golacki Commented Jun 9, 2022 at 13:35

Your Answer

Reminder: Answers generated by artificial intelligence tools are not allowed on Software Engineering Stack Exchange. Learn more

Sign up or log in

Post as a guest.

Required, but never shown

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy .

Not the answer you're looking for? Browse other questions tagged mvvm or ask your own question .

  • The Overflow Blog
  • This developer tool is 40 years old: can it be improved?
  • Unpacking the 2024 Developer Survey results
  • Featured on Meta
  • We've made changes to our Terms of Service & Privacy Policy - July 2024
  • Introducing an accessibility dashboard and some upcoming changes to display...

Hot Network Questions

  • How is clang able to evaluate loops without getting stuck in an infinite loop?
  • How different is Wittgenstein's Language game from Contextuality?
  • Possible downsides of not dealing with the souls of the dead
  • How to remove Incoming/Outgoing changes graph in VSCode?
  • Word/phrase for avoiding a task because it has a lot of unknowns
  • Connect electric cable with 4 wires to 3-prong 30 Amp 125-Volt/250-Volt outlet?
  • Does a cancellation of an accepted review request before the due date happen often?
  • An English equivalent of the Japanese idiom "be tied with a red string (of destiny)"
  • Why don't charges on surface of current carrying wire move?
  • Why don't aircraft use D.C generators?
  • A convergent, but large, sum of integer reciprocals
  • Select correct effect size (Cohen's d) for power analysis
  • How to proceed if my manager is ghosting me?
  • Either-or Implication Constraints for a Group of Non-negative Continuous or Integer Variables
  • GND plane on both sides?
  • Tritone substitution in Haydn string quartet?
  • What happens if your child sells your car?
  • Does hermeneutics categorize flaws in exegeses? (with reference to an exegesis of Colossians 3:16 and Ephesians 5:19)
  • Looking for a Saturday Morning Cartoon with Lava Cannons
  • Can right shift by n-bits operation be implemented using hardware multiplier just like left shift?
  • Is there a formal definition of an animal?
  • Why is my single speed bike incredibly hard to pedal
  • Does the volume of air in an air tight container affect food shelf life?
  • Selecting 2 largest elements out of 4, preserving order

view model presentation logic

DevCodeLight

DevCodeLight

Software Engineering: Model View ViewModel (MVVM)

The term “Model-View-ViewModel” (MVVM) is a software architecture pattern commonly used in the development of software applications, especially in user interface applications such as web and mobile apps. MVVM is a variant of the Model-View-Controller (MVC) pattern and focuses on separating the presentation logic from the business logic of an application.

view model presentation logic

In MVVM, the three main components are:

  • Model : Similar to Model-View-Controller (MVC), the Model represents the data and business logic of the application. This can include operations such as retrieving data from a database, performing calculations, and applying business rules.

In this example, the UserModel represents user data, including the username and email address.

  • View : The View is the user interface presented to the end user. In MVVM, the view handles the presentation and visual structure of the application. The view does not contain business logic; it simply displays information and responds to user interactions.

In this example, the user_profile.xml view defines the user interface to display user details, such as the username and email address.

  • ViewModel : The ViewModel acts as an intermediary between the Model and the View. It is responsible for handling the presentation logic and view logic of the application. The ViewModel is specific to the view and contains the necessary logic to present data in the appropriate format for the view. It can also handle user events and actions from the view, such as button clicks or input field changes. Additionally, the ViewModel communicates with the Model to fetch and update data as needed.

In this example, the UserViewModel acts as an intermediary between the UserModel and the view. It provides methods to get the user data in a way that is suitable for the view.

Differences between Model-View-ViewModel and Model-View-Controller

The main difference between MVVM and MVC lies in how the presentation logic is handled and organized. In MVVM, the presentation logic is encapsulated in the ViewModel, allowing for greater separation of concerns and better code modularity . This facilitates unit testing of the presentation logic and the reuse of UI components in different parts of the application.

Technologies using Model-View-ViewModel (MVVM)

The Model-View-ViewModel (MVVM) architecture pattern is used in a variety of software development technologies, especially in user interface application development, such as web, mobile, and desktop applications.

Web technologies :

  • AngularJS, Angular, React, Vue.js : These frontend development frameworks for JavaScript enable the implementation of MVVM patterns to create interactive and dynamic web applications.
  • ASP.NET MVC, ASP.NET Core : Microsoft’s web development frameworks that support the MVVM pattern to create scalable and high-performance web applications.

Mobile technologies :

  • Android (with Kotlin or Java) : The MVVM pattern is widely used in Android mobile application development using frameworks such as Android Architecture Components or third-party libraries like RxJava.
  • iOS (with Swift or Objective-C) : In iOS application development, MVVM is implemented using frameworks like SwiftUI or UIKit along with design patterns such as Observables or Reactive Programming.

Desktop technologies :

  • WPF (Windows Presentation Foundation) : In Windows desktop application development, MVVM is widely used with WPF due to its excellent support for the MVVM pattern and data binding.
  • JavaFX : For desktop application development in Java, MVVM can be implemented using JavaFX along with libraries like JavaFX Bindings for data binding.

Cross-platform technologies :

  • Flutter : A cross-platform development framework that uses the MVVM pattern to create mobile and desktop applications using a single codebase.
  • React : A development framework driven by Facebook for web and mobile development. It can also employ the MVVM model, though MVC is more common.
  • Xamarin : A cross-platform development platform that allows the development of native mobile applications for iOS, Android, and Windows using the MVVM pattern and the C# programming language.

view model presentation logic

Comparte esto:

Leave a comment cancel reply.

Save my name, email, and website in this browser for the next time I comment.

Presentation Model

Represent the state and behavior of the presentation independently of the GUI controls used in the interface

Also Known as: Application Model

19 July 2004

This is part of the Further Enterprise Application Architecture development writing that I was doing in the mid 2000’s. Sadly too many other things have claimed my attention since, so I haven’t had time to work on them further, nor do I see much time in the foreseeable future. As such this material is very much in draft form and I won’t be doing any corrections or updates until I’m able to find time to work on it again.

GUIs consist of widgets that contain the state of the GUI screen. Leaving the state of the GUI in widgets makes it harder to get at this state, since that involves manipulating widget APIs, and also encourages putting presentation behavior in the view class.

Presentation Model pulls the state and behavior of the view out into a model class that is part of the presentation. The Presentation Model coordinates with the domain layer and provides an interface to the view that minimizes decision making in the view. The view either stores all its state in the Presentation Model or synchronizes its state with Presentation Model frequently

Presentation Model may interact with several domain objects, but Presentation Model is not a GUI friendly facade to a specific domain object. Instead it is easier to consider Presentation Model as an abstract of the view that is not dependent on a specific GUI framework. While several views can utilize the same Presentation Model , each view should require only one Presentation Model . In the case of composition a Presentation Model may contain one or many child Presentation Model instances, but each child control will also have only one Presentation Model .

Presentation Model is known to users of Visual Works Smalltalk as Application Model

How it Works

The essence of a Presentation Model is of a fully self-contained class that represents all the data and behavior of the UI window, but without any of the controls used to render that UI on the screen. A view then simply projects the state of the presentation model onto the glass.

To do this the Presentation Model will have data fields for all the dynamic information of the view. This won't just include the contents of controls, but also things like whether or not they are enabled. In general the Presentation Model does not need to hold all of this control state (which would be lot) but any state that may change during the interaction of the user. So if a field is always enabled, there won't be extra data for its state in the Presentation Model .

Since the Presentation Model contains data that the view needs to display the controls you need to synchronize the Presentation Model with the view. This synchronization usually needs to be tighter than synchronization with the domain - screen synchronization is not sufficient, you'll need field or key synchronization.

To illustrate things a bit better, I'll use the aspect of the running example where the composer field is only enabled if the classical check box is checked.

Figure 1: Classes showing structure relevant to clicking the classical check box

Figure 2: How objects react to clicking the classical check box.

When someone clicks the classical check box the check box changes its state and then calls the appropriate event handler in the view. This event handler saves the state of the view to Presentation Model and then updates itself from the Presentation Model (I'm assuming a coarse-grained synchronization here.) The Presentation Model contains the logic that says that the composer field is only enabled if the check box is checked, so the when the view updates itself from the Presentation Model , the composer field control changes its enablement state. I've indicated on the diagram that the Presentation Model would typically have a property specifically to mark whether the composer field should be enabled. This will, of course, just return the value of the isClassical property in this case - but the separate property is important because that property encapsulates how the Presentation Model determines whether the composer field is enabled - clearly indicating that that decision is the responsibility of the Presentation Model .

This small example is illustrates the essence of the idea of the Presentation Model - all the decisions needed for presentation display are made by the Presentation Model leaving the view to be utterly simple.

Probably the most annoying part of Presentation Model is the synchronization between Presentation Model and view. It's simple code to write, but I always like to minimize this kind of boring repetitive code. Ideally some kind of framework could handle this, which I'm hoping will happen some day with technologies like .NET's data binding.

A particular decision you have to make with synchronization in Presentation Model is which class should contain the synchronization code. Often, this decision is largely based on the desired level of test coverage and the chosen implementation of Presentation Model . If you put the synchronization in the view, it won't get picked up by tests on the Presentation Model . If you put it in the Presentation Model you add a dependency to the view in the Presentation Model which means more coupling and stubbing. You could add a mapper between them, but adds yet more classes to coordinate. When making the decision of which implementation to use it is important to remember that although faults do occur in synchronization code, they are usually easy to spot and fix (unless you use fine-grained synchronization).

An important implementation detail of Presentation Model is whether the View should reference the Presentation Model or the Presentation Model should reference the View. Both implementations provide pros and cons.

A Presentation Model that references a view generally maintains the synchronization code in the Presentation Model . The resulting view is very dumb. The view contains setters for any state that is dynamic and raises events in response to user actions. The views implement interfaces allowing for easy stubbing when testing the Presentation Model . The Presentation Model will observe the view and respond to events by changing any appropriate state and reloading the entire view. As a result the synchronization code can be easily tested without needing the actual UI class.

A Presentation Model that is referenced by a view generally maintains the synchronization code in the view. Because the synchronization code is generally easy to write and easy to spot errors it is recommended that the testing occur on the Presentation Model and not the View. If you are compelled to write tests for the view this should be a clue that the view contains code that should belong in the Presentation Model . If you prefer to test the synchronization, a Presentation Model that references a view implementation is recommended.

When to Use It

Presentation Model is a pattern that pulls presentation behavior from a view. As such it's an alternative to to Supervising Controller and Passive View . It's useful for allowing you to test without the UI, support for some form of multiple view and a separation of concerns which may make it easier to develop the user interface.

Compared to Passive View and Supervising Controller , Presentation Model allows you to write logic that is completely independent of the views used for display. You also do not need to rely on the view to store state. The downside is that you need a synchronization mechanism between the presentation model and the view. This synchronization can be very simple, but it is required. Separated Presentation requires much less synchronization and Passive View doesn't need any at all.

Example: Running Example (View References PM) (C#)

Here's a version of the running example , developed in C# with Presentation Model .

Figure 3: The album window.

I'll start discussing the basic layout from the domain model outwards. Since the domain isn't the focus of this example, it's very uninteresting. It's essentially just a data set with a single table holding the data for an album. Here's the code for setting up a few test albums. I'm using a strongly typed data set.

The Presentation Model wraps this data set and provides properties to get at the data. There's a single instance of the Presentation Model for the whole table, corresponding to the single instance of the window. The Presentation Model has fields for the data set and also keeps track of which album is currently selected.

class PmodAlbum...

PmodAlbum provides properties to get at the data in the data set. Essentially I provide a property for each bit of information that the form needs to display. For those values which are just pulled directly out of the data set, this property is pretty simple.

The title of the window is based on the album title. I provide this through another property.

I have a property to see if the composer field should be enabled.

This is just a call to the public IsClassical property. You may wonder why the form doesn't just call this directly - but this is the essence of the encapsulation that the Presentation Model provides. PmodAlbum decides what the logic is for enabling that field, the fact that it's simply based on a property is known to the Presentation Model but not to the view.

The apply and cancel buttons should only be enabled if the data has changed. I can provide this by checking the state of that row of the dataset, since data sets record this information.

The list box in the view shows a list of the album titles. PmodAlbum provides this list.

So that covers the interface that PmodAlbum presents to the view. Next I'll look at how I do the synchronization between the view and the Presentation Model . I've put the synchronization methods in the view and am using coarse-grained synchronization. First I have a method to push the state of the view into the Presentation Model .

class FrmAlbum...

This method is very simple, just assigning the mutable parts of the view to the Presentation Model . The load method is a touch more complicated.

The complication here is avoiding a infinite recursion since synchronizing causes fields on the form to update which triggers synchronization.... I guard against that with a flag.

With these synchronization methods in place, the next step is just to call the right bit of synchronization in event handlers for the controls. Most of the time this easy, just call SyncWithPmod when data changes.

Some cases are more involved. When the user clicks on a new item in the list we need to navigate to a new album and show its data.

Notice that this method abandons any changes if you click on the list. I've done this awful bit of usability to keep the example simple, the form should really at least pop up a confirmation box to avoid losing the changes.

The apply and cancel buttons delegate what to do to the Presentation Model .

So although I can move most of the behavior to the Presentation Model , the view still retains some intelligence. For the testing aspect of Presentation Model to work better, it would be nice to move more. Certainly you can move more into the Presentation Model by moving the synchronization logic there, at the expense of having the Presentation Model know more about the view.

Example: Data Binding Table Example (C#)

As I first looked at Presentation Model in the .NET framework, it seemed that data binding provided excellent technology to make Presentation Model work simply. So far limitations in the current version of data binding holds it back from places that I'm sure it will eventually go. One area where data binding can work very well is with read-only data, so here is an example that shows this as well as how tables can fit in with a Presentation Model design.

Figure 4: A list of albums with the rock ones highlighted.

This is just a list of albums. The extra behavior is that each rock album should have it's row colored in cornsilk.

I'm using a slightly different data set to the other example. Here is the code for some test data.

The presentation model in this case reveals its internal data set as a property. This allows the form to data bind directly to the cells in the data set.

To support the highlighting, the presentation model provides an additional method that indexes into the table.

This method is similar to the ones in a simple example, the difference being that methods on table data need cell coordinates to pick out parts of the table. In this case all we need is a row number, but in general we may need row and column numbers.

From here on I can use the standard data binding facilities that come with visual studio. I can bind table cells easily to data in the data set, and also to data on the Presentation Model .

Getting the color to work is a little bit more involved. This is straying a little bit away from the main thrust of the example, but the whole thing gets its complication because there's no way to have row by row highlighting on the standard WinForms table control. In general the answer to this need is to buy a third party control, but I'm too cheap to do this. So for the curious here's what I did (the idea was mostly ripped off from http://www.syncfusion.com/FAQ/WinForms/). I'm going to assume you're familiar with the guts of WinForms from now on.

Essentially I made a subclass of DataGridTextBoxColumn which adds the color highlighting behavior. You link up the new behavior by passing in a delegate that handles the behavior.

class ColorableDataGridTextBoxColumn...

The constructor takes the original DataGridTextBoxColumn as well as the delegate. What I'd really like to do here is to use the decorator pattern to wrap the original but the original, like so many classes in WinForms, is all sealed up. So instead I copy over all the properties of the original into my subclass. This won't work is there are vital properties that can't be copied because you can't read or write to them. It seems to work here for now.

Fortunately the paint method is virtual (otherwise I would need a whole new data grid.) I can use it to insert the appropriate background color using the delegate.

To put this new table in place, I replace the columns of the data table in the page load after the controls have been built on the form.

class FrmAlbums...

It works, but I'll admit it's a lot more messy than I would like. If I were doing this for real, I'd want to look into a third party control. However I've seen this done in a production system and it worked just fine.

This browser is no longer supported.

Upgrade to Microsoft Edge to take advantage of the latest features, security updates, and technical support.

December 2011

Volume 26 Number 12

MVPVM Design Pattern - The Model-View-Presenter-ViewModel Design Pattern for WPF

By Bill Kratochvil | December 2011

Of all the successful projectsI’ve been a part of, the most successful ones shared a common result: As the application grew larger, the codebase became smaller. On the surface, this may seem contradictory, but coding in an Agile environment lends itself to a shrinking codebase. As requirements change, refactoring occurs, and this refactoring opportunity—coupled with hindsight—provides the ability to reuse existing components more efficiently while eliminating duplicate code in the process.

In contrast, there have been some monolithic projects, which were sometimes deemed successful, where the source code grew and grew with little opportunity for reuse. These projects became resource-intensive and a risk to future growth. What was the fundamental difference? The infrastructural design pattern used. The patterns you use will determine whether you paint yourself into a corner or keep your back to the open opportunities the future might bring.

In this article, I’ll present one such pattern—overlooked by many Windows Presentation Foundation (WPF) developers because of the popularity of the Model-View-ViewModel (MVVM) pattern—called the Model-View-Presenter-ViewModel (MVPVM) pattern. This enterprise application design pattern was introduced in the Microsoft patterns & practices Prism project ( Prism.CodePlex.com ). (Note: This pattern was unnamed, so I refer to it as MVPVM.) Prism is best described with an excerpt from its Web site overview:

“Prism provides guidance designed to help you more easily design and build rich, flexible, and easy-to-maintain Windows Presentation Foundation (WPF) desktop applications, Silverlight Rich Internet Applications (RIAs), and Windows Phone 7 applications. Using design patterns that embody important architectural design principles, such as separation of concerns and loose coupling, Prism helps you to design and build appli­cations using loosely coupled components that can evolve independently but that can be easily and seamlessly integrated into the overall application. These types of applications are known as composite applications.”

The popularity and success of MVVM overshadows MVPVM even though MVPVM is the evolution of MVVM (as this article will demonstrate). MVPVM provides all of the power and capability of MVVM while introducing the scalability and extensibility of the Model-View-Presenter (MVP) pattern. If your understanding is that MVVM has evolved from MVP for WPF, then you’ll find this article enlightening.

Before we can fully appreciate the power and benefits of MVPVM, we have to understand how this pattern evolved—we have to understand our history. The Model-View-Controller (MVC) pattern is a crucial component to achieving this understanding, so I’ll first introduce MVC, perhaps in a way you’ve never seen before.

The MVC Pattern

Please note that this MVC discussion is within the context of desktop applications; Web applications are another story and beyond the scope of this article.

In Martin Fowler’s “GUI Architectures” document ( bit.ly/11OH7Y ), he states the following about MVC: “Different people reading about MVC in different places take different ideas from it and describe these as ‘MVC.’ If this doesn’t cause enough confusion, you then get the effect of misunderstandings of MVC that develop through a system of Chinese whispers.” The “Whatsa Controller Anyway” document at bit.ly/7ajVeS sums up his point nicely stating: “Computer scientists in general have an annoying tendency to overload terms. That is to say, they tend to assign more than one meaning (sometimes contradictory) to the same word.” 

Smalltalk MVC gets further complicated by the fact that developers lack a common core of experience with their great architects in regard to the architect environment. As such, the overloading of terms and “Chinese whispers” are convoluted even more by the fact that most of us don’t even know what a Controller is because we’ve never had to use one—the OS has always handled its functionality for us. With a few facts to provide the common core of experience we lack, you’ll find MVC is actually easy to understand, and that the “C” in MVC has nothing in common with the “P” in MVP.

The Controller does have a concrete origin (which is well worth understanding but doesn’t necessarily match modern approaches to MVC in the context of current technologies). The founding father of MVC, Trygve Reenskaug, wrote about that in 1979 in his document on “Models-Views-Controllers” ( bit.ly/2cdqiu ). This document begins to provide some insight on the purpose of the Controller. Reenskaug wrote:

“A controller is the link between a user and the system. It provides the user with input by arranging for relevant views to present themselves in appropriate places on the screen. It provides means for user output by presenting the user with menus or other means of giving commands and data. The controller receives such user output, translates it into the appropriate messages and passes these messages on to one or more of the views.

A controller should never supplement the views, it should for example never connect the views of nodes by drawing arrows between them.

Conversely, a view should never know about user input, such as mouse operations and keystrokes. It should always be possible to write a method in a controller that sends messages to views, which exactly reproduce any sequence of user commands.”

This concept is illustrated in Figure 1 .

A “message,” in the context of MVC object-oriented programming (OOP), is a means of executing methods. They were described as “messages” because back then, virtual calls were a new concept and it was a way of distinguishing them from static function calls. In Chapter 1.2 of the book “Smalltalk, an Introduction to Application Development Using VisualWorks” (Prentice Hall, 1995), by Trevor Hopkins and Bernard Horan, the authors note “… if the receiving object understands the message it has been sent, then one of its internal operations (or methods) will be performed. This, in turn, may cause some computation to take place (by acting on one or more of the object’s internal variables).” (Note: This “message-sending” OOP concept is available in Prism via its EventAggregator.)

The book nicely outlines the responsibilities of Smalltalk MVC in Chapter 29, “Introduction to Models, Views and Controllers,” by teaching us that Controllers derive from the Controller class. It states, “Instances of this class have a reference to a sensor representing the mouse and keyboard, so that it can process input.” It continues to tell us that the two distinct actions initiated from a Controller are communications with the Model (see Figure 1 ) and communications with the View without affecting the Model.

Controller Receives Input and Sends Message (Method to Execute); Views Can’t Catch User Input

In Smalltalk MVC, “every” View will have a Controller and only one Controller at any given time can be active. In the original Smalltalk MVC, the UI was polled; the top-level ControlManager class asks each of the Controllers of the active View if it wants control. Only the View that contains the cursor can accept control. If a View is read-only, there’s a NoController class available that’s designed to refuse control. A View with subviews has the responsibility to poll the Controllers of its subviews. Once a Controller has accepted control, it will query the results of the keyboard or mouse and send messages to the View or Model as applicable, such as mouse move, button click and so on. In MVVM terms, this would be comparable to subscribing to a control’s events in either the View’s codebehind or via a ViewModel command. When a user interacts with the control, the applicable method will be called.

By this point, you can start to get a glimpse behind the purpose of the Controller within the context of MVC and an environment that doesn’t automatically handle events for you. Unlike Smalltalk MVC developers, WPF developers don’t have to query keyboard buffers and package and raise events. You merely subscribe to them and the applicable method “automagically” receives them via the Microsoft Event Pattern. With this knowledge, the following will perhaps have a different, and less confusing, meaning.

In Steve Burbeck’s article, “Applications Programming in Smalltalk-80: How to Use Model-View-Controller (MVC)” ( bit.ly/3ZfFCX ), he states the following:

“The controller interprets the mouse and keyboard inputs from the user, commanding the model and/or the view to change as appropriate. Finally, the model manages the behavior and data of the application domain, responds to requests for information about its state (usually from the view), and responds to instructions to change state (usually from the controller).”

See Figure 2 for an illustration of this concept.

Smalltalk Model-View-Controller

A final point to bring clarity to what could be a muddy topic is in the document, “Twisting the Triad, the Evolution of the Dolphin Smalltalk MVP Application Framework,” by Andy Bower and Blair McGlashan at bit.ly/o8tDTQ (PDF download). This is one of the more comprehensive documents I’ve read on the topic. The authors note the following about the Controller: “The views, of course, are responsible for displaying the domain data while the controllers handle the raw user gestures that will eventually perform actions on this data.”  

I bring this final point up so that I have an opportunity to provide another definition. To fully comprehend the article (and others on MVC), you have to understand what “gestures” means (see Figure 1 ). In my research, I came across the article, “An Introduction to GUI Programming with UIL and Motif” ( bit.ly/pkzmgc ), which states the following:

“The essence of these steps is that a Motif program does nothing until the user requests some action. The actions are requested by selecting a menu item, by clicking a button or other window, or by pressing a key. These, collectively, are user gestures. Each gesture will trigger an application function to carry out some tasks.”

Andy Bower, coauthor of “Twisting the Triad,” shared his thoughts on “gestures” with me:

“My take on ‘gestures’ is that they’re a coalescence of one or more user events into something more meaningful.

For example a TextController might absorb key down and key up events and convert them into individual ‘keypress’ gestures. Similarly, a SelectionInListController (the Controller attached to a list box) might absorb several mouse-down, mouse-tracking and mouse-up events within a list and treat them as a single list ‘selection’ gesture.

Looked at like this, we see that a modern event-driven OS already does most of this gesture processing for us.”

To summarize Controller logic, you can see that the Controller function is rather consistent among the variations of MVC referenced. Because Microsoft controls (widgets) handle “the mouse and keyboard inputs from the user,” you merely subscribe to the events and point to the method that needs to be executed—the “Controller” within your smart controls executes the method for you (handled at the OS level). As such, you don’t have a need for a Controller, as clearly indicated by the “Twisting the Triad” article. Without the Controller, you’re left with the Model-View pattern for Windows applications. You have to bear this in mind as you study MVC and its application and presentation models because without the Controller, there is no Triad (see Figure 3 ).

Without the Controller, It Has Been Model-View (not Model-View-Controller)

It’s worth mentioning that it was not only the Controller that caused ambiguity with MVC. With Smalltalk MVC, the business/domain logic is in the Model, and with VisualWorks MVC the ApplicationModel contains the “application” logic required to present one or more business/domain objects to the user (see Figure 4 ). The “Twisting the Triad” article covers this in more detail. If you consider that the Application Model and Presentation Model have the same functionality, with the distinct difference being that the Presentation Model “cannot” access the View (Martin Fowler made a clear distinction so as not to overload terms), then WPF developers can quickly grasp Presentation Model because it’s in essence MVVM. John Gossman, founding father of MVVM, explains this in his “PresentationModel and WPF” blog entry at bit.ly/pFs6cV . Like Martin Fowler, he was careful not to overload terms. This effectively gives us a clear understanding of what MVVM is; it’s a “WPF-specific version of the PresentationModel pattern.”

VisualWorks Model-View-Controller

Once you can see MVC in its true light, it helps you understand the true roles of the Model and View. These are in essence the only two locations for business/domain logic. After reading “Twisting the Triad,” you can see it was the responsibilities of the Application Model that were moved to the Presenter and that you can’t simply replace the Controller with a Presenter—it wouldn’t make sense, because they aren’t synonymous.

The MVP Pattern

It’s beyond the scope of this article to go into MVP with the attention it deserves; fortunately, there are numerous documents that address it, such as “Twisting the Triad” and the “Potel Paper,” which you can download at bit.ly/dF4gNn (PDF).

I will, however, note that the “Twisting the Triad” article states an important point that I alluded to, which led to the evolution of MVC to MVP:

“Another irritating feature of MVC, at least with respect to Dolphin, was that the idea of a controller did not fit neatly into the Windows environment. Microsoft Windows, like most modern graphical operating systems, provides a set of native widgets from which user interfaces can be constructed. These ‘windows’ already include most of the controller functionality embodied as part of the underlying operating system control.”

I’d also like to highlight from Martin Fowler’s “GUI Architectures” article his statement that “This need to manipulate the widgets directly was seen by many as a bit of dirty workaround and helped develop the Model-View-Presenter approach.” This is important to understand because MVVM has ingrained the Presentation Model mentality into many WPF developers; they believe it’s “bad programming” to update the View directly. This is true for MVVM and the Presentation Model because once you reference the View, you can no longer reuse the ViewModel with a different View (the main reason for this rule). This limiting factor was one of the reasons Smalltalk MVC evolved to the MVP pattern. With MVPVM, developers can access the View and ViewModel directly (it’s tightly coupled), which permits the View and ViewModel to remain completely decoupled (see Figure 5 ). Views can reuse different ViewModels and ViewModels can be reused by different Views (as you’ll see later when I discuss the MVPVM pattern); this is one of the many great benefits of MVPVM.

Model-View-Presenter, Supervising Controller

Andy Bower shared the following information on the topic with me to provide further clarification:

“It’s perhaps worth pointing out that the aim of all of these patterns is reuse via plugability. Keeping the coupling loose wherever possible and the interfaces as small as possible gives maximum reuse in the way the components can be recombined.

However, note that the Model has effectively two interfaces that must be compatible with any associated View and Presenter. The first is the standard function call interface, used for getting/setting values and performing commands. The second is the event interface, which must be the same as that expected by the View (observer pattern). This combination of interfaces can be referred to as a ‘protocol.’

For example, in Dolphin MVP, a list widget (triad) needs three components with compatible protocols. A ListModel, a ListView and a ListPresenter.”

Once you understand why you don’t want to update a View directly—and realize that this reason contributed to a new design pattern that would permit you to effectively reuse objects by eliminating the constraint of not being able to update the View—then you have the option to embrace the new opportunities that evolution offers. You live in an Agile world and—like your code—you have to change your thought patterns “lest history repeats itself.”

The MVPVM Pattern

I was taught this pattern early in Prism’s lifecycle, specifically in Drop 7 of the CompositeWPF. Lost in all of the mystical powers of Prism, I recognized the MVP pattern, which helped me find some footing. I quickly learned (as I teach new developers) to simply go to the Presenter and you’ll have your starting point for figuring out the code and application. How code execution gets there can be learned later and doesn’t have to interfere with critical timelines; the impact of the difficult learning curves can be managed.

The following definitions of the MVPVM components have excerpts from “Twisting the Triad” as applicable; I found this information to be informative, comprehensive and accurate, so in the interest of presenting to you the best information possible, I’ll merely quote this article’s definitions. These definitions hold true today for MVPVM (see Figure 6 ) as they did for MVP back in March 2000 when “Twisting the Triad” was written.

Model-View-Presenter-ViewModel

(Note: Prism is the context of this article, however, MVPVM will work without Prism; the various components will simply be tightly coupled to their implementation versus being resolved—loosely coupled by the Unity or Managed Extensibility Framework [MEF] dependency injection container.)

MVPVM: The Model

“This is the data upon which the user interface will operate. It is typically a domain object and the intention is that such objects should have no knowledge of the user interface.” —“Twisting the Triad”

The separation of the Model from the ViewModel is required to address the concerns of dependency injection and its use within the Business Logic Layer (BLL) and Data Access Layer (DAL) to Create, Read, Update, Delete and List (CRUDL) persisted data. In MVPVM, only the DAL has access to the persisted Model objects.

MVPVM: The View

“The behavior of a view in MVP is much the same as in MVC. It is the view’s responsibility to display the contents of a model. The model is expected to trigger appropriate change notifications whenever its data is modified and these allow the view to ‘hang off’ the model following the standard Observer pattern. In the same way as MVC does, this allows multiple views to be connected to a single model.” —“Twisting the Triad”

(Note: I used the preceding quote to emphasize that MVP isn’t a new pattern and that it’s as valid today as it was when MVP evolved from MVC. However, the quote does reference the “Model,” whereas MVPVM uses the “ViewModel.”)  

With MVPVM, there’s never a need to have code in codebehind. The Presenter has access to the View and can subscribe to events, manipulate controls and manipulate the UI as required. This proved beneficial while developing the multi-targeted application that accompanies this article. The User ListBox wouldn’t respect the data binding for the selection changed event, so I had to develop a way that would work for all three platforms (because they share the same code). When the View is activated, I call the WireUpUserListBox (see Figure 7 , line 174) and use the View to obtain a reference to my lstUserList control (which resides in a DataTemplate). Once it’s found, I wire up to the SelectionChanged event and update the ViewModel SelectedUser property. This works on the desktop, Silverlight and Windows Phone.

Benefits of Being Able to Access the View Directly

A View has no knowledge of the ViewModel, so they aren’t tightly coupled. As long as a ViewModel supports all of the properties to which a View binds, it can easily use the View. The Presenter is responsible for wiring up Views to their ViewModels by setting their DataContext to the applicable ViewModel.

MVPVM: The Presenter

“While it is the view’s responsibility to display model data, it is the presenter that governs how the model can be manipulated and changed by the user interface. This is where the heart of an application's behavior resides. In many ways, an MVP presenter is equivalent to the application model in MVC; most of the code dealing with how a user interface works is built into a presenter class. The main difference is that a presenter is directly linked to its associated view so that the two can closely collaborate in their roles of supplying the user interface for a particular model.” —“Twisting the Triad”

The Presenter will have dependencies on the interfaces for the BLLs from which it needs to retrieve domain objects (data), as shown in the left pane of Figure 8 . It will use the resolved instances as configured in the module (see Figure 8 , bottom right pane) or bootstrapper to access the data and populate the ViewModel.

Security Module Code

Typically, only the Presenter will be tightly coupled in MVPVM components. It will be tightly coupled to the View, ViewModel and the BLL inter­faces. Presenters aren’t intended to be reused; they address specific concerns as well as the business logic/rules for those concerns. In cases where a Presenter can be reused across enterprise applications, it’s likely a module would be better suited for the task—that is, you could create a login module (project) that could be reused by all of your enterprise applications. If you code against an interface, the module can be easily reused using dependency injection technologies such as the MEF or Unity.

MVPVM: The ViewModel

“In MVP, the model is purely a domain object and there is no expectation of (or link to) the user interface at all.” —“Twisting the Triad”

This prevents the ViewModel from being tightly coupled to a single View, permitting it to be reused by numerous Views. Likewise, the ViewModel will have no application business logic, so ViewModels can be easily shared across enterprise applications. This promotes reuse and application integration. For example, look at Figure 8 , top right pane, line 28. This SecurityCommandViewModel resides in the Gwn.Library.MvpVm.xxxx project (where xxxx = Silverlight, desktop or Windows Phone). Because a User ViewModel will be required in most applications, this is a reusable component. I have to be careful not to pollute it with business logic specific to the demo application. This isn’t a problem with MVPVM, because the business logic will be handled by the Presenter, not within the ViewModel (see Figure 6 ).

(Note: As the ViewModel properties are populated by the Presenter, they’ll raise NotifyPropertyChanged events, which will alert the View that it has new data—it’s the View’s responsibility to update itself to the ViewModel data upon notification.)

The Business Logic Layer

BLLs have no knowledge of the persisted Model data. They work strictly with domain objects and interfaces. Typically, you’ll use dependency injection to resolve your DAL interface within the BLL, so you can later swap out the DAL without affecting any downstream code. Notice in Figure 9 , line 34, that I’m using a MockBll implementation for IBusinessLogicLayer for my demo application. Later I can easily replace it with a production imple­mentation of the interface with one line of code because I’ve developed against an interface.

Registering BLL, DAL and Commands

Business logic isn’t limited to the BLLs. In Figure 9 , I register named types (for IPresenterCommand) so that I can use dependency injection as a factory. When the user clicks on a button (lines 29–33 in Figure 10 ), the command parameter is resolved (instantiated) by the baseclass and the applicable command is executed. For example, the LoginCommand ( Figure 8 , top right pane) is a command that will activate the UserManagerView. All that was required to wire this up was a Button command in XAML and an entry in the SecurityModule (see Figure 8 , bottom right pane, line 32).

DataTemplate for the UserCommandViewModel

The Data Access Layer

Persisted domain data could be stored in SQL databases or XML or text files, or retrieved from a REST service. With MVPVM, only the DAL holds specific information required to retrieve data. The DAL will only return domain objects to the BLL. This averts the need for the BLL to have knowledge of connection strings, file handles, REST services and so on. This enhances scalability and extensibility; you can easily switch your DAL from an XML file to a cloud service without affecting any existing code outside of the DAL and the application configuration file. As long as your new DAL unit tests work for the CRUDL processes, you can configure the application to use the new DAL without impacting current applications and their usage.

Understanding History, Benefitting from Experience

Thanks to the patterns & practices team, I’ve been able to achieve success for my clients using bleeding-edge technologies and patterns such as MVPVM, without failure. I found that by keeping up with the team’s pace, technologies and patterns, that as newer technologies and patterns emerge, I can pull from past experience to help me more easily find my way in new territory.

MVP is a constant and consistent pattern that I’ve seen used since the earliest days of my architectural studies using patterns & practices projects. To fully appreciate MVP, you have to understand your history, particularly the components of MVC. This isn’t easy, because of the numerous factors discussed.

But by understanding our past, and the reason for our evolution, we can more quickly grasp the need for and power of newer patterns. Even with Prism and all of its complexity and magic, you’ll be able to bypass a difficult learning curve by simply knowing this history and appreciating the need for the newer patterns. In all of the successful projects I’ve been involved with since the emergence of this pattern in early drops of Prism, MVPVM has revealed no issues, speed bumps or brick walls (through evolution they appear to have been eliminated), permitting developers to increase velocity as we build applications that are scalable, extensible and stable.

Bill Kratochvil , an independent contractor, is a lead technologist and architect for an elite team of developers working on a confidential project for a leading company in the medical industry. His own company, Global Webnet LLC, is based in Amarillo, Texas .

Thanks to the following technical experts for reviewing this article: Andy Bower , Christina Helton and Steve Sanderson

Additional resources

C# Corner

  • TECHNOLOGIES
  • An Interview Question

WPF

MVVM Architecture

view model presentation logic

  • Varun Setia
  • Jun 05, 2024
  • Other Artcile

Learn about the significance of software architecture like MVVM, which separates UI from backend, enhancing maintainability. Explore MVVM's components: Model (business logic), View (UI), ViewModel (presentation logic). Implement it in WPF using ICommand, INotifyPropertyChanged for dynamic UI updates.

Introduction

Software architecture is very important. Without implementing software architecture, UI code can be tightly coupled with backend code. This increases the cost of maintenance and makes our code Spaghetti, as lines of code start increasing with time. To address this concern, there are many software architectures that are available, such as Model -View - Controller (MVC), Model-View-Presenter (MVP), Model-View-ViewModel (MVVM), Model-View-Update (MVU), etc. Each pattern has its own advantages. Design patterns evolve with time and we start using more modern patterns as per skills and team size. Mostly, enterprise applications are developed using architecture that makes code well maintained and easy to work.

In this tutorial, we are going to discuss MVVM Architecture. This software architecture pattern helps us to address the Separation of Concern. It separates the GUI design from the application's backend, making it loosely coupled. It is used mostly in developing client applications. Let's understand each component of MVVM.

The model represents the domain model also considered as Business Logic / Data Access Logic or we can abstractly define it as the backend of the application. They hold application data.

View Represents the UI of the application. This is what the user interacts with. It is the presentation part.

It is the logic of View. The ViewModel is also called as presentation logic. The View and ViewModel communicate with each other. The Request from ViewModel is forwarded to Model / Business Logic Layer / Data Access Layer. It allows sharing of computed/resultant data to the view.

View model

There are popular frameworks that provide MVVM Architecture, such as

  • DotVVM: Component-based MVVM Architecture for ASP.NET.
  • MVVM Light Toolkit: The popular toolkit to build client applications in XAML.
  • Knockout.js: Dynamic JavaScript UIs with the Model-View-View Model (MVVM) pattern.
  • Vue.js: A popular Javascript framework.

And much more...

Implementing Basic MVVM Architecture in WPF

We are going to implement MVVM architecture in WPF. The Building Blocks of MVVM architecture in WPF are below. Here is a bit of an overview of each.

  • ICommand: This interface provides the code contract for the commanding behaviour of Runtime XAML. It controls the behaviour such as enable, disable of control and behaviour on execution.
  • INotifyPropertyChanged: This interface defines the contract for behaviour when the value of a property changes. It raises PropertyChanged event when the value changes.
  • A binding target object.
  • A target property.
  • A binding source.
  • A path to the value in the binding source to use.

It offers data flow in four ways

  • OneWayToSource

Implementation flow

Implement flow

Code Walkthrough

We will create a generic ICommand Implementation and name it RelayCommand. It will contain system-defined delegates Func and Action.

We will implement INotifyPropertyChanged in ViewModel, it will be implemented for every View that will be created. In this code, we will enable the submit button based on conditions. We will invoke the OnProperyChanged() method on the property set. This method contains an invocation of a PropertyChanged event.

Bind the ViewModel with View through DataContext and name the Properties the same as defined in ViewModel.

In this tutorial, we learned about the importance of architecture, MVVM architecture, and the implementation of MVVM architecture in WPF.

Please feel free to share your thoughts, ideas and suggestions. Thanks for reading!!

  • INotifyPropertyChanged
  • Data Binding

C# Corner Ebook

WPF Simplified: Build Windows Apps Using C# and XAML

  • React Native
  • CSS Frameworks
  • JS Frameworks
  • Web Development

Introduction to Model View View Model (MVVM)

Description of Model is as follows:

  • MODEL: ( Reusable Code – DATA ) Business Objects that encapsulate data and behavior of application domain, Simply hold the data. 
  • VIEW: ( Platform Specific Code – USER INTERFACE ) What the user sees, The Formatted data. 
  • VIEWMODEL: ( Reusable Code – LOGIC ) Link between Model and View OR It Retrieves data from Model and exposes it to the View. This is the model specifically designed for the View. 
Note: Link between Model and View Model is Manipulating Data and between ViewModel and View is 2-way Data Binding. 

BASIC INTRODUCTION:  [ Way to Structure Code]

view model presentation logic

FEATURES:   

  • Life Cycle state of Application will be maintained.
  • The application will be in the same position as where the user left it.
  • UI Components are kept away from Business Logic.
  • Business Logic is kept away from Database operations.
  • Easy to understand and read.

BASIC EXAMPLE:  We want to display Name in Purple Color (not written in the proper format, proper length) or Display Purple Color if Age of a person is > 18 years, Display Pink Color if Age of a person is < 18 years, Then the Logic of Purple and Pink Color would be present in ViewModel. 

SUMMARY:  From Server, Get Data(available in Model Objects), View Model reads Model Objects and then facilitates the easy presentation of data on the view.

The primary differences between MVVM AND MVC are as follows: 

MVVM MVC
The Model is somewhat similar to MVC but here we have ViewModels which are passed to the view and all the logic is in the ViewModel and hence no controller is there. Example: Knockout.js In this pattern, we have models which are basic objects with no code and just properties, views that contribute to presentation items (HTML, WinForms, etc), client-side deletes, and Controllers that focus on the logic part. Examples: ASP.NET MVC, Angular
In MVVM your DeletePerson would be called off of your view model We have a PersonController with an Action DeletePerson that delete a person
We are on the client side so we can hold on to objects and do a lot more logic in a non-disconnected state. MVC is typically used when things are transactional and disconnected as is the case with server-side web. In ASP MVC we send the view through the wire and then the transaction with the client is over.

ADVANTAGES:   

  • Maintainability – Can remain agile and keep releasing successive versions quickly.
  • Extensibility – Have the ability to replace or add new pieces of code.
  • Testability – Easier to write unit tests against a core logic.
  • Transparent Communication – The view model provides a transparent interface to the view controller, which it uses to populate the view layer and interact with the model layer, which results in a transparent communication between the layers of your application.

DISADVANTAGES:  

  • Some people think that for simple UIs, MVVM can be overkill.
  • In bigger cases, it can be hard to design the ViewModel.
  • Debugging would be a bit difficult when we have complex data bindings.

Please Login to comment...

Similar reads.

  • Web Technologies

Improve your Coding Skills with Practice

 alt=

What kind of Experience do you want to share?

Convert Your Native Project to Kotlin Multiplatform — Developer’s Guide

Learn to migrate your Android and iOS apps to Kotlin Multiplatform in 10 easy steps. From preparing repositories to migrating unit tests, it’s all covered in this guide.

view model presentation logic

In  one of our previous posts , we discussed why it is worth migrating your existing Android application to  Kotlin Multiplatform  to share logic with iOS. We already know how the migration process may look like, how to make it iterative, without interfering with regular development, and what the potential risks are and how to mitigate them.

In this article, I would like to  dive deeper into the technical details of the migration process . I’m going to show you some important  technical decisions  you’ll have to make and several common  challenges  you might face. For all of them, you’ll receive my  recommendations  on how to approach them, based on my experience of more than 3 years spent on Kotlin Multiplatform development across several different projects. So please take your seat and enjoy the read!

1. Prepare your repositories

Before we open Android Studio and begin moving classes to the Multiplatform module, we need to prepare our repositories. If you already have separate applications for  Android  and  iOS  operating systems, they are most likely in two separate Git repositories. These codebases don’t know anything about each other, but this will change when we introduce  Kotlin Multiplatform  to the project.  With KMP, both native applications use the same Kotlin code, which implements the common logic.  We need to make this code accessible to them, and there are several ways to do that.

Option 1: A separate repository for the Multiplatform module

In the first approach, we treat this new module more like an independent library. It is located in a separate repository, with both native applications using it as an external dependency.

  • On the Android side, we export the Multiplatform code to an  Android library  and distribute it using  Maven .
  • On the iOS side, we export the Multiplatform code to an  Apple framework  and distribute it using  CocoaPods  or  Swift Package Manager  (SPM).

To simplify and automate this process, we rely on the  KMMBridge tool, which is a Gradle plugin added to the Multiplatform module. It supports distribution using Maven, CocoaPods, and Swift Package Manager right out of the box.

view model presentation logic

This approach is the most complex and I recommend it mainly for  large projects with a large number of developers . Since we treat our Multiplatform module as a library, it is the most effective when we also have a dedicated team working alongside the Android and iOS teams. This way, the Multiplatform library can be properly documented, versioned, and released in regular cycles.

Option 2: Put a shared module in the Android repository

Not every project is large enough, however, to justify creating a separate team to develop a Multiplatform library. Our second option is to put the Multiplatform module inside the Android project repository.  From the Android perspective, there is no big difference between the Android and Multiplatform modules.  They use the same Kotlin language, they are both Gradle modules, and they can both be directly integrated within the project. This means we don’t need to build and distribute an Android library anymore.

On the iOS side, the distribution process looks the same as in the previous setup with a separate repository. We use the  KMMBridge  tool to export the Multiplatform module to an  Apple framework  and publish it using  CocoaPods  or  Swift Package Manager .

view model presentation logic

This solution suits  projects where   only the Android team will be responsible for the development of the Multiplatform codebase . In this case, Android developers use the Multiplatform module just like a regular Android module, simplifying development. The iOS team, on the other hand, still uses it as an external dependency. Adding versioning and documentation to the Multiplatform module is also a worthwhile consideration here, as the iOS team can still treat it as a library. However, if the Android and iOS teams cooperate closely and communicate directly, this might not be necessary.

Option 3: Merge applications into a monorepo

Having a Multiplatform module inside the Android app repository creates asymmetry between the teams. The Android engineers develop the common code while their iOS colleagues only use it. In some projects, this is a desired situation, but in others, not so much. This is why we have a third option where we don’t create any new team, and  all the developers are equally responsible for the development of the Multiplatform codebase .

In this approach, we merge our separate repositories into a single monorepo and add a Multiplatform module to it. Because all the code sits within the same repository, we don’t need any remote artifact distribution solutions like Maven, CocoaPods, or SPM.  Both Android and iOS applications depend on the Multiplatform module directly . On the Android side, we connect it as a  Gradle module  to the application while, on the iOS side, we configure it using  Xcode Build Phases .

view model presentation logic

Having a monorepo is  ideal when Android and iOS developers want to cooperate closely, acting more like a single team . At Droids On Roids, we apply this strategy for new projects with Kotlin Multiplatform, but it is also worth considering when we migrate existing applications. It not only simplifies and speeds up development but also promotes knowledge exchange between engineers.

However, if creating a monorepo is something you would like to avoid,  we can achieve similar results by using  Git submodules . This solution enables us to keep the code in a separate repository while also including it in other repositories. This way, we can connect the Multiplatform module to both native applications directly, without using remote distribution mechanisms like Maven, CocoaPods, or SPM.

2. Think about modularization

No matter which repository configuration you choose, you might want to  modularize your shared code . We often do this in our projects to benefit from code encapsulation, better build performance, and easier parallel work in a team or even across multiple teams. Kotlin Multiplatform is no different here. Since it relies on Gradle just like Android does, we can apply exactly the same modularization strategies.In contrast, iOS doesn’t use Gradle. This means we can’t connect the Multiplatform module to the iOS project the same way we connect it to the Android one. Instead,  our shared Kotlin code is packed into an iOS framework, which can be connected using Xcode Build Phases, CocoaPods, or SPM .

view model presentation logic

The way this framework is packed is very important in multi-module projects. Let’s say we have two Multiplatform modules, such as login and home. There is also a third module called networking, which holds a common HTTP client. Both the login and home modules depend on the networking module. When the Android app imports the login and home modules separately, they still use the same HTTP client from the networking module.

view model presentation logic

The situation looks different on iOS. If we generate two separate frameworks from login and home, each of them contains an exact copy of all the code it depends on. This means  our features don’t use the same HTTP client; instead, they each have a separate copy of it .

view model presentation logic

In multi-module projects where modules have many dependencies on other modules, this behavior can cause  several issues . The biggest one is  the lack of state sharing across modules . If multiple modules use another module to hold a common state, it will not work after compiling to iOS. Each module will have its own independent copy of the state instead of using the shared one. Furthermore,  the application size will grow  unnecessarily due to code duplication across different frameworks.

This is why we should introduce an umbrella module to multi-module KMP projects. The umbrella module is the only one that generates the iOS framework . As a result, the iOS application has only one dependency, the umbrella framework, and it doesn’t depend on other individual modules. The Android app, on the other hand, can depend on individual modules via Gradle, or it can also use just the umbrella for consistency with the iOS.

view model presentation logic

The umbrella module itself depends on all the Multiplatform modules and  decides which ones should be accessible from the native app . For those that are supposed to be strictly used internally by the Multiplatform code, we add them as implementation dependencies to the umbrella module. In contrast, modules that should be public are added as API dependencies and additionally exported from the iOS framework. Below, you can find an example from the build.gradle.kts file of the umbrella module.

kotlin {
  val iosTargets = listoOf(iosArm64(), iosSimulatorArm64())
  configure(iosTargets) {
    binaries.framework {
      baseName = "shared"
      isStatic = true
      // These modules are accessible from iOS app
      export(projects.shared.login)
      export(projects.shared.home)
    }
  }
  sourceSets {
    commonMain.dependencies {
      // These modules are accessible from native apps
      api(projects.shared.login)
      api(projects.shared.home)
      // These modules are used only internally 
      implementation(projects.shared.networking)
    }
  }
}

3. Make your Kotlin code Swift-friendly

On the iOS side, Kotlin translates to Objective-C code, which guarantees support for a wide range of projects in the Apple ecosystem. However, it also requires developers to  design their public Kotlin API with caution , as some language features might be missing after translation to Objective-C.

  • First, developers should get familiar with the official  Kotlin-Swift interopedia . It shows how all Kotlin features look when used from Swift code after translation to Objective-C.
  • It is also worth checking out a great  talk from KotlinConf 2024 , which explains how this interoperability works and what we should do to make our code more Swift-friendly.
  • Next, you should add the  SKIE plugin  to your common module. It is a Kotlin Multiplatform plugin that generates Swift code instead of Objective-C code for certain language features. It makes it easier to use things like Coroutines, Flow, or sealed classes.
  • Lastly, watch for news about direct Kotlin-Swift interoperability. It is on the  Kotlin Multiplatform roadmap for 2024 , so it might already be available by the time you read this article it is already there.

4. Setup dependency injection

Almost every modern mobile application uses some DI solution. In the Android world, the most popular choice is the official  Hilt library  made by Google. Hilt is built on top of Dagger, which is an older Java solution. Because it is based on Java, we can’t use it in the Multiplatform code.

To enable us to use DI with KMP, we need to switch to  the Koin library . If you haven’t heard about it before, Koin is a very lightweight and pragmatic dependency injection framework built 100% with Kotlin. It is a very mature technology, developed and improved over many years, and is the second most popular choice among Android developers, right after Hilt.

The best way to use Koin in a Kotlin Multiplatform app is to  use it only internally within the shared module . We create a separate KoinApplication instance and expose public get functions only for those classes we want to be accessible from native applications.

object SharedModule {
private var koinApplication: KoinApplication? = null
private var koin: Koin
get() = koinApplication?.koin ?: error("SharedModule not initialized")
fun init() {
check(koinApplication == null) { "SharedModule already initialized" }
     koinApplication = koinApplication {
         modules(loginModule, homeModule, networkingModule)
     }
}
fun getLoginViewModel(): LoginViewModel = koin.get()
}

This approach comes with several benefits:

  • We don’t force the Android app to use Koin.  We can use it in the app, but we don’t have to. We can still rely on Hilt and only connect our SharedModule to it.
  • All native applications use SharedModule the same way.  Koin works in the common Kotlin code, but it can’t be used directly in the Swift code. By hiding it inside the Multiplatform module, we expose just a simple, framework-agnostic API that is consistent across different platforms.
  • We might not need a DI solution in native applications at all.  If we decide to move everything up to ViewModel classes to the common Kotlin, we can access them from the UI just by using public getters from the SharedModule without Hilt, Koin, or any other DI solution.
@Composable
fun LoginScreen() {
val viewModel = viewModel { SharedModule.getLoginViewModel() }
}
struct LoginScreen: View {
let viewModel = SharedModule.getLoginViewModel()
}

5. Migrate a model

No matter what app you have, it always contains some model classes. The model represents business objects like User, Product, or Article. These are  classes that hold data and eventually implement some general business rules .

view model presentation logic

In a properly architected application, the model is  the most independent part of the project . It should not have any dependencies on other parts of the application like backend services, databases, system APIs, or the UI.  This makes the model a great starting point for the KMP migration. Let’s say we have a simple Product model that looks as follows:

data class Product(
    val id: String,
    val name: String,
    val description: String,
    val price: Double
)

Moving this class to a Multiplatform module requires no changes, and we can  use it in the iOS app right away , such as inside the Repository class to create a new product, for example.

import shared
class ProductsRepository {
func createNewProduct(
name: String,
description: String,
price: Double
) {
let newProduct = Product(
id: UUID().uuidString,
name: name,
description: description,
price: price
)
...
}
}

Replace Java types with Kotlin types

When Kotlin code is written in a  native Android app , it is common practice to use some Java dependencies in the model. Very common examples are LocalDate and LocalDateTime. As these types come from the Java language, they cannot be used in Multiplatform code.

import java.time.LocalDate
data class Product(
val id: String,
val name: String,
val description: String,
val price: Double,
val dateAdded: LocalDate,
)

Luckily, the Kotlin team implemented their versions of these types in pure Kotlin. They are available in the additional kotlinx-datetime library. All we need to do is replace the imports in our model.

import kotlinx.datetime.LocalDate
data class Product(
val id: String,
val name: String,
val description: String,
val price: Double,
val dateAdded: LocalDate,
)

Jetpack Compose Previews: Delving Deep Into Their Inner Workings

Automate maven central publication, accessibility considerations with stacked cards custom layout.

Carly Solutions GmbH

Senior Android Engineer

SumUp

Senior Android Developer

Our video recommendation, kobweb:creating websites in kotlin leveraging compose html.

view model presentation logic

Senior Cybersecurity Engineer

view model presentation logic

Team Lead App Development (all genders)

view model presentation logic

Senior Full Stack Developer

view model presentation logic

Backend Engineer – Java/Kotlin (m/f/d)

view model presentation logic

Uber – Staff Android Engineer, Rider

view model presentation logic

Expert outils et système d’exploitation Android H/F

view model presentation logic

Senior Backend Developer

Provide platform specific implementation for unsupported types.

Not every Java type has its Kotlin equivalent. For instance, in many projects, I often find developers using the URL type. It is not present in Kotlin, but we can quickly address this by providing a platform-specific implementation using  Kotlin’s expect/actual mechanism .

First, in the common source set of our KMP module, we define an expected URL class. In simple words, we say that we  expect  to have a URL class, but the  actual  implementation should be provided by the specific platform.

expect class URL(path: String)

Then we go to the androidMain source set and implement this expectation using the Java URL type.

import java.net.URL
actual class URL(private val url: URL) {
actual constructor(path: String) : this(URL(path))
override fun toString(): String {
return url.toString()
}
}

The same can be easily achieved on the iOS side using Apple’s NSURL type. We put the following code in the iosMain source set.

import platform.Foundation.NSURL
actual class URL(private val url: NSURL) {
actual constructor(path: String) : this(NSURL(string = path))
override fun toString(): String {
return url.absoluteString.orEmpty()
}
}

6. Migrate data sources

By migrating the model of the app, the team already has a solid foundation on how to work with  Kotlin Multiplatform . Developers know how to put Kotlin code in the Multiplatform module, how to use it in the iOS app, and how to deal with platform-specific implementation using the expect/actual mechanism.

view model presentation logic

Now, we can move on to more complex parts of the application. Our data sources, both remote and local, are good candidates. Their migration strongly depends on the technology we use for backend communication and local storage. Below, I explain how to migrate several of the most popular solutions often found in Android applications.

For REST communication, newer Android applications usually use the  Ktor Client  along with the  Kotlin Serialization  library. These are official tools from JetBrains, implemented in pure Kotlin, which makes them KMP compatible out of the box.  When a project uses these tools, migrating to KMP is just about moving the networking code to the Multiplatform module.

However, there are still many Android projects that don’t use Ktor and rely on the Java-based Retrofit library combined with serializers like Moshi or Gson, which are also Java libraries. In that case, the only available option is to  refactor your networking code to use Ktor and Kotlin Serialization . Luckily, this process is quite simple. After setting up the new libraries, it mainly involves changing annotations in your DTO models and refactoring Retrofit interfaces into Ktor classes.

@JsonClass(generateAdapter = true)
data class ProductApiModel(
@Json(name = "product_id") val productId: String,
@Json(name = "name") val name: String,
@Json(name = "description") val description: String,
@Json(name = "price") val price: Double
)
interface ProductsService {
@GET("products/{product_id}")
suspend fun getProduct(@Path("product_id") productId: Int): ProductApiModel
}
@Serializable
data class ProductApiModel(
@SerialName("product_id") val productId: String,
@SerialName("name") val name: String,
@SerialName("description") val description: String,
@SerialName("price") val price: Double
)
class ProductsService(private val httpClient: HttpClient) {
suspend fun getProduct(productId: Int): ProductApiModel {
return httpClient.get("products/${productId}").body()
}
}

Next to REST communication, more and more applications use GraphQL technology to exchange data with backend services. If your Android app is one of them, you most likely  rely on the  Apollo Kotlin  library as a GraphQL client . The good thing is that this library is already pure Kotlin and fully KMP compatible. So, in this case, you can move all your networking code straight to the Multiplatform module.

Some companies and teams decide not to build backend services on their own for their mobile products. Instead, they choose cloud solutions that offer configurable and ready-to-use backend platforms. The most popular choice in the mobile world is the Firebase platform from Google. We also use it for monitoring our apps with Crashlytics and Analytics.

The Firebase Android SDK is a Java library, so we can’t use it directly in the Multiplatform module. Google hasn’t migrated it to pure Kotlin yet, but there is an open-source  Firebase Kotlin SDK  that does the job . Its API is very similar to the original Firebase Android SDK, but includes the addition of modern Kotlin features like Coroutines and Serialization.

Jetpack DataStore and Room

A big advantage of mobile apps compared to web applications is their ability to operate without a network connection. We usually call this offline mode, and we use local storage solutions to save data received from the backend.

In the Android world, there are two solutions that are the most common choices for this task:  Jetpack DataStore  and  Jetpack Room . Both of them are official libraries from Google, and both are KMP compatible. Thanks to this,  we can stick to the same tools we already use and just move the implementation to the Multiplatform module .

Other local storage solutions

In case you are not interested in using Jetpack libraries for some reason, there are  many other storage solutions that also work with Kotlin Multiplatform . Two of the most prominent ones are  SQLDelight , which generates code from SQL files, and  Realm , which is a NoSQL, object-oriented storage solution.

7. Migrate native APIs and SDKs

Next to backend and local storage, there is one more thing that native applications often communicate with — system APIs and some native third-party SDKs. Properly architected apps always  hide these kinds of interactions behind some abstractions . A very common example is checking the internet connection. So, let’s say we have a simple NetworkConnection interface in our Android app.

interface NetworkConnection {
val isAvailable: Boolean
}

This interface is implemented by the AndroidNetworkConnection class, which uses the ConnectivityManager API offered by the Android system.

import android.net.*
internal class AndroidNetworkConnection(
private val connectivityManager: ConnectivityManager,
) : NetworkConnection, ConnectivityManager.NetworkCallback() {
override var isAvailable: Boolean = true
private set
init {
val request = NetworkRequest.Builder().build()
connectivityManager.registerNetworkCallback(request, this)
}
override fun onAvailable(network: Network) {
isAvailable = true
}
override fun onLost(network: Network) {
isAvailable = false
}
}

Platform-specific code directly in Multiplatform module

The migration of such an implementation to KMP is pretty straightforward. We move the interface to the commonMain source set, while the Android-specific implementation goes to the androidMain source set. The only remaining part is providing an iOS-specific implementation.

view model presentation logic

KMP offers two-way interoperability with the iOS platform , meaning all the native APIs are accessible directly from Kotlin. We can create an IosNetworkConnection class in the iosMain source set and directly use network APIs offered by the iOS system.

import platform.Network.*
import platform.darwin.*
internal class IosNetworkConnection : NetworkConnection {
override var isAvailable: Boolean = true
private set
init {
val monitor = nw_path_monitor_create()
nw_path_monitor_set_update_handler(monitor) { path ->
val status = nw_path_get_status(path)
isAvailable = status == nw_path_status_satisfied
}
nw_path_monitor_set_queue(monitor, dispatch_get_main_queue())
nw_path_monitor_start(monitor)
}
}

Platform-specific code provided by native apps

The only challenge with the previous approach is that all the native APIs are accessible via their  Objective-C implementation . This is why the syntax looks a bit strange in the example above. It works well for simple scenarios, but to integrate more complex APIs or SDKs, you can consider an alternative approach.

view model presentation logic

class IosNetworkConnection: NetworkConnection {
private(set) var isAvailable: Bool = true
init() {
let monitor = NWPathMonitor()
let queue = DispatchQueue.main
monitor.pathUpdateHandler = { path in
let status = path.status
self.isAvailable = status == .satisfied
}
monitor.start(queue: queue)
}
}

In this approach, a shared module only exposes an interface and allows native apps to provide their own implementation during initialization. We can easily achieve this by  passing the implementation as a parameter to the init function of the SharedModule object .

object SharedModule {
fun init(networkConnection: NetworkConnection) {
check(koinApplication == null) { "Library already started" }
val nativeAppModule = module {
single { networkConnection }
}
koinApplication = koinApplication {
modules(nativeAppModule, loginModule, homeModule, networkingModule)
}
}
}

8. Migrate business logic

Until now, we’ve only been migrating the outermost parts of the application to KMP. At this point, your native applications, for both mobile platforms, should not have their own backend communication, local storage, or interfaces/protocols for system APIs and external SDKs. All of these are shared by the Multiplatform module. We also migrated the model representing business objects in our application. Now it’s time for business logic.

view model presentation logic

The way an application’s logic is implemented in different projects may vary. Popular building blocks we often see are Repositories and Use Cases, but you may also find others like Managers, Services, Interactors, etc. If you followed the previous migration steps, moving the business logic to the shared module is pretty straightforward. All you need to do is  move the code from the Android app to the commonMain source set of the shared module . All the components this logic uses, like interfaces for system APIs and external SDKs, or different data sources, are already there.

9. Migrate presentation logic

By migrating all the backend, storage, APIs, SDKs, and logic code, you should already be sharing around 50–60% of the code across Android and iOS applications. That is a pretty good number, but we can do even better. Our last step in the KMP migration is the presentation layer. There are a number of ways to implement it, but nowadays the vast majority of apps rely on ViewModel classes, so I’m going to show you how to make them work in KMP.

view model presentation logic

Use Jetpack ViewModel

In Android applications, our ViewModel classes usually inherit from the  Jetpack ViewModel . This is an official solution from Google that offers valuable functionalities like access to the CoroutineScope and proper lifecycle handling. The good news is that this class was migrated to KMP by Google and  can be used in Multiplatform code the same way we use it on Android . So moving our ViewModels to KMP is just about transferring the code to the shared module without any extra changes involved.

The lifecycle of the ViewModel is handled automatically on Android as our Activities, Fragments, and Destinations conform to the ViewModelStoreOwner interface. The same is not true for the iOS UIViewController and View, so we need to handle it ourselves. Luckily, the solution is quite simple. If you use SwiftUI and the UIHostingController, you can create a  small wrapper class that implements the ViewModelStoreOwner interface  and thus handles the lifecycle of the given ViewModel. It guarantees that the ViewModel’s CoroutineScope is canceled when the ViewModel is no longer needed.

class UIHostingControllerWrapper<V: View, VM: ViewModel> : UIHostingController<V>, ViewModelStoreOwner {
let viewModelStore = ViewModelStore()
init(rootView: V, viewModel: VM) {
super.init(rootView: rootView)
let key = String(describing: VM.self)
viewModelStore.put(key: key, viewModel: viewModel)
}
deinit {
viewModelStore.clear()
}
}

Collect data Flow in the UI

On Android, our ViewModels expose streams of data to the UI. We usually use Coroutine Flow for this purpose. An example ViewModel with a list of products may look like this:

class ProductListViewModel : ViewModel() {
val products: StateFlow<List<Product>>
}

For Compose, nothing changes. We still collect this Flow using available functions like collectAsState. The situation looks a bit different in the iOS project.  The SKIE plugin transforms Kotlin Flow into a Swift AsyncSequence . SwiftUI doesn’t have a built-in function to observe AsyncSequence, but we can create a simple ViewModifier to achieve that.

private struct StateBinding<State>: ViewModifier {
@Binding var state: State
let stateFlow: SkieSwiftStateFlow<State>
func body(content: Content) -> some View {
content.task {
for await state in stateFlow {
self.state = state
}
}
}
}
extension View {
func stateBinding<State> (
_ state: Binding<State>,
_ stateFlow: SkieSwiftStateFlow<State>
) -> some View {
modifier(StateBinding(state: state, stateFlow: stateStream))
}
}

Using a dedicated extension, we can bind a selected Flow from the ViewModel to a specific @State property in the SwiftUI View.

struct ProductListView: View {
let viewModel: ProductListViewModel
@State var products: [Product] = []
var body: View {
VStack {
...
}
.stateBinding($products, viewModel.products)
}
}

Handle parcelable data

During the migration of the presentation layer, we may face a final challenge when dealing with parcelable data. On Android, there is no option to pass full objects as navigation arguments to other screens. Some applications handle this by passing only primitive types like IDs and loading full objects from the data layer. Other applications use a  Parcelable mechanism, which serializes and deserializes objects during navigation.

import android.os.Parcelable
import kotlinx.parcelize.Parcelize
@Parcelize
data class Product(
val id: String,
val name: String,
val description: String,
val price: Double
) : Parcelable

This becomes problematic when we want to use the same approach with our Multiplatform models, as  these Android dependencies cannot be used in the common Kotlin code . One option is to stop passing objects through navigation, but this would require extra refactoring, which might not be worth it in larger projects.

So, let’s say we want to stick to that solution but still keep our models in Multiplatform. This is where the  expect/actual mechanism  comes to the rescue. As a first step, we create our own expected definitions of the Parcelize annotation and Parcelable interface in the commonMain source set.

expect interface Parcelable
@OptIn(ExperimentalMultiplatform::class)
@OptionalExpectation
@Target(AnnotationTarget.CLASS)
@Retention(AnnotationRetention.BINARY)
expect annotation class Parcelize()

Then, in the androidMain source set, we implement these expectations. That way, when our common Kotlin code is compiled to the Android target, it uses the actual Android-specific implementations which we had before in the native app.

actual interface Parcelable : android.os.Parcelable
actual typealias Parcelize = kotlinx.parcelize.Parcelize

For iOS, we don’t need to implement the annotation, as we marked it as @OptionalExpectation. This mechanism is not applicable to interfaces, so we need to provide an actual one. We simply define an empty Parcelable interface in the iosMain source set, which will have no effect after compilation.

actual interface Parcelable

10. Migrate Unit Tests

There is one more part of the codebase that every good application has — Unit Tests. They are present in each layer we discussed earlier and may contain a significant amount of code. For Unit Testing on Android, we usually rely on the  JUnit  framework,  alongside MockK  for mocking, and an assertion library like  Truth ,  AssertJ  or  Kotest Assertions .

Keep using Android specific tools at the beginning

JUnit, MockK, and Truth are Java-specific libraries. Even though some of them, like MockK, are written in Kotlin,  they still rely on JVM mechanisms like reflection . This means we can’t use these tools in the commonTest source set of our Multiplatform module.

An effective option to start with is to  move all the Unit Tests to the androidTest source set  instead of the commonTest. This way, we have full access to all the Android-specific tools, so we don’t have to spend a lot of effort rewriting our Unit Tests with different ones.

Then gradually migrate to Kotlin tools

Later on, we can think about moving our Unit Tests to the commonTest source set, switching Java libraries to Multiplatform solutions. As a replacement for JUnit,  Kotlin offers its own Kotlin Test  framework , which has a very similar syntax but is less feature-rich, especially compared to JUnit5. Its simplicity might be considered a benefit, but if you are looking for a more advanced solution, there is an  open-source Kotest  framework , which was built specifically for Kotlin Multiplatform.

Replacing an assertion library shouldn’t be a problem. For projects which rely on Truth or AssertJ, I recommend trying the AssertK  library . It has almost the same syntax and functions but is implemented in pure Kotlin. If the project uses  Kotest Assertions , we don’t need to switch as this library is already Multiplatform, just like the Kotest Framework.

The hardest part is moving away from  MockK , which has become a very popular and advanced solution in the Android world. There are several open-source mocking libraries that work with Kotlin Multiplatform, but none of them offer as many functionalities as MockK does, so I can’t really recommend them at this moment.

My personal preference in that case is to  think about changing the testing style and moving from using mocks to using fakes as test doubles . Fakes are a recommended testing approach by Google and many other industry leaders. They behave like real implementations, are more reusable, promote the simplification of architecture, and most importantly, don’t require any third-party tool to create them.

Migrate native projects to KMP with Droids On Roids

At  Droids On Roids , our Android and iOS developers collaborate seamlessly to build Kotlin Multiplatform code.  With a comprehensive understanding of both native and cross-platform solutions, we ensure a smooth migration process to KMP.  We know how to overcome common challenges with proven solutions and best practices. Want to team up?  Let’s talk about your project!

If you have a native mobile app and want to improve its development or maintenance, as well as cut costs, you might have considered cross-platform solutions like  Flutter or React Native . This usually involves hiring a new team of developers and completely rewriting the application — a significant and risky investment not suitable for all businesses.

Kotlin Multiplatform is a groundbreaking technology that  bridges the gap between native and cross-platform development.  It is the only cross-platform solution that  seamlessly integrates with existing native applications , making it a much safer option than its competitors.

To  convert to Kotlin Multiplatform , you don’t have to overhaul your tech stack but can  continue using the existing native tools you already employ . All we need to do is  gradually move more and more Kotlin code from the Android application to the Multiplatform module , integrate it into the iOS applicatioon, and remove the corresponding Swift implementation.

The complexity of this process strongly depends on how your application is written, how well it is architected, and how many Java-based tools you are using. Fortunately, for all these challenges, we have proven and battle-tested solutions, which we’ve discuss in this article. So, if you’ve read carefully, you should be well-prepared to start your migration to Kotlin Multiplatform.

Marcin Piekielny  — Android Team Leader and Android Developer with 7 years of experience. He is a great enthusiast of the Kotlin language and its multiplatform use. Passionate about clean software architecture, cutting-edge technologies and building products that are both valuable to business and enjoyable to work for the team. Privately, a fan of video games, cooking and maintaining a healthy lifestyle.

Originally published at  https://www.thedroidsonroids.com  on August 1, 2024.

This article is previously published on proandroiddev.com

YOU MAY BE INTERESTED IN

Swipe to dismiss — jetpack compose, make sure to update your stateflow safely in kotlin, the definitive guide of android ui automator with kotlin, basic drag-n-drop in jetpack compose.

' src=

View all posts

' src=

Leave a Reply Cancel reply

Your email address will not be published. Required fields are marked *

Post Comment

  • Stack Overflow for Teams Where developers & technologists share private knowledge with coworkers
  • Advertising & Talent Reach devs & technologists worldwide about your product, service or employer brand
  • OverflowAI GenAI features for Teams
  • OverflowAPI Train & fine-tune LLMs
  • Labs The future of collective knowledge sharing
  • About the company Visit the blog

Collectives™ on Stack Overflow

Find centralized, trusted content and collaborate around the technologies you use most.

Q&A for work

Connect and share knowledge within a single location that is structured and easy to search.

Get early access and see previews of new features.

What's the difference between a ViewModel and Controller?

What are the responsibilities of one vs the other? What kind of logic should go in one vs the other? Which one hits services and databases? How do I decide if my code should go in the viewmodel or the controller?

For the record, I am using ASP MVC, but since the question is architectural, I do not believe it matters what language or framework I am using. I'm inviting all MVC to respond

  • ruby-on-rails
  • asp.net-mvc
  • model-view-controller

MedicineMan's user avatar

7 Answers 7

The ViewModel is a Pattern used to handle the presentation logic and state of the View and the controller is one of the fundamentals parts of any MVC framework, it responds to any http request and orchestrates all the subsequent actions until the http response.

The ViewModel Pattern: More info

In the ViewModel pattern, the UI and any UI logic are encapsulated in a View. The View observes a ViewModel which encapsulates presentation logic and state. The ViewModel in turn interacts with the Model and acts as an intermediary between it and the View.

The Controllers (Comes from the Front Controller Pattern): More Info

It "provides a centralized entry point for handling requests."

--Plain Differences:--

  • While the ViewModel is an optional pattern the Controller is a must, if you are going the MVC way.
  • The ViewModel encapsulates presentation logic and state, The Controller orchestrates all the Application Flow.

ejohnso49's user avatar

  • The ViewModel can be on the client side as well as server side. Wherever it may be, the sole purpose of viewmodel is to play the presentation data.
  • In MVC architecture Viewmodel is not mandatory but with out controller the request from the client cannot be processed.
  • Controller can be visualised as the main interface between client and server to get any response from the server. It processes the client request, fetches data from repository and then prepares the view data. Viewmodel can be visualised as view data processor/presenter thus an interface to manage the view more eloquently.
  • In the overall context of a web application we can say the controller is the application request handler whereas viewmodel is only the UI handler.

Krishna's user avatar

  • 1 I landed on this question because I was wondering what the difference between MVC and MVVM was, but if I'm correct, according to your illustration, MVVM is a subset of MVC. –  Ogier Schelvis Commented Oct 27, 2016 at 9:36
  • 2 @OgierSchelvis, no, they are different, you can also have MVVMC (a mixture between them both). –  Mohammed Noureldin Commented Dec 3, 2017 at 17:10

The Model-View-Controller (MVC) is an architectural design pattern which exists, primarily, to separate business logic from the presentation. Basically, you don't want your back-end touching your front. It typically looks like this:

The reasons for doing this is because, by separating the back-end and the front, you don't tie your user-interface directly to your data/work. This allows you to put new interfaces onto your business logic without affecting said logic. In addition, it also improves the ease of testing.

A simple example of where MVC comes in handy - let's say you have an application that manages your company's finances. Now, if you are correctly using MVC, you can have a front end that sits at some financier's desk and lets him handle transactions, manage the finances, etc. BUT, because the business logic is separate, you can also provide a front-end to your CEO's Blackberry that lets him see the current status of the business. Because the two front-ends are different, they can do different things while still providing (different types of) access to the data.

Since you updated your question a bit, I'll update my answer. There is no perfect science to the separation of MVC. There are some good rules of thumb, however. For example, if you are talking about GUI components, that is probably a view. (Are you talking about look and feel, usability, etc.) If you are talking about data and the "business" side of the house (databases, logic, etc), you are probably referring to a model. And, anything that controls the interaction between the two is most likely a controller.

In addition, it should be noted that, while Views and Models are typically "physically" separated, a controller can exist with a view when it makes sense.

You are correct when you say the framework (or even language) for MVC doesn't matter. The pattern itself is language agnostic and really describes a way to architect your system.

Hope that helps!

Community's user avatar

  • I like the phrase "language agnostic". –  Thomas Matthews Commented Dec 11, 2009 at 21:41
  • 1 thanks, would it be possible to expand on the difference between view model and controller? –  MedicineMan Commented Dec 11, 2009 at 22:04

I think there's some value to learning received doctrine. But there is also value in understanding how the doctrine came to be the way it is.

Trygve Reenskaug is widely credited with inventing MVC. N. Alex Rupp's article Beyond MVC: A new look at the servelet architecture includes a History of MVC. In a section on Reenskaug's 1978 work at Xerox Palo Alto Research Center, there's a link to his paper Thing-Model-View-Editor: an Example from a planningsystem . There the pieces are described like this.

Something that is of interest to the user. It could be concrete, like a house or an integrated circuit. It could be abstract, like a new idea or opinions about a paper. It could be a whole, like a computer, or a part, like a circuit element.
A Model is an active representation of an abstraction in the form of data in a computing system
To any given Model there is attached one or more Views, each View being capable of showing one or more pictorial representations of the Model on the screen and on hardcopy. A View is also able to perform such operations upon the Model that is reasonabely associated with that View.
An Editor is an interface between a user and one or more views. It provides the user with a suitable command system, for example in the form of menus that may change dynamically according to the current context. It provides the Views with the necessary coordination and command messages.

Rupp identifies Reenskaug's Editor as a Controller or Tool .

MVC Triads emerged in SmallTalk-80. The model was an abstraction of the real-world concept, the view was its visual representation, and the controller was the buttons and slider bars that allowed the user to interact with it (thereby "controlling" the view). All pieces in the triad were interconnected and could communicate with the other two pieces, so there was no layering or abstraction involved. Since then, Reenskaug has "preferred to use the term Tool rather then Controller." According to his notes, these are the terms he has used in later implementations

Ewan Todd's user avatar

Some logic and model should be invoked to generate some data (structured or semi-structured). From this data the returned page/JSON/etc. is created, typically with only rudimentary outlining logic.

The first part (creating the data) is done by the controller (via the model usually). The second part - by the View. The ViewModel is the data structure being passed between controller and view, and usually contains only accessors.

Shachar's user avatar

Model represents your data and how it's manipulated. Thus, model touches the DB.

View is your UI.

Controler is the glue between them.

Wojciech Kaczmarek's user avatar

MVC stands for Model, View, Controller.

Model = Data (Database tables)

View = HTML, CSS, JavaScript, etc

Controller = Main logic, a contract between Model & View.

In simple and graspable terms,

MVC allows you to develop your applications in a way that your business data and presentation data are separated. With this, a developer and designer can work independently on a MVC app without their work clashing. MVC makes your app avail OOP too.

Sarfraz's user avatar

Your Answer

Reminder: Answers generated by artificial intelligence tools are not allowed on Stack Overflow. Learn more

Sign up or log in

Post as a guest.

Required, but never shown

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy .

Not the answer you're looking for? Browse other questions tagged ruby-on-rails asp.net-mvc model-view-controller or ask your own question .

  • The Overflow Blog
  • This developer tool is 40 years old: can it be improved?
  • Unpacking the 2024 Developer Survey results
  • Featured on Meta
  • We've made changes to our Terms of Service & Privacy Policy - July 2024
  • Introducing an accessibility dashboard and some upcoming changes to display...
  • Tag hover experiment wrap-up and next steps

Hot Network Questions

  • Word/phrase for avoiding a task because it has a lot of unknowns
  • Do academic researchers generally not worry about their work infringing on patents? Have there been cases where they wish they had?
  • A simple reusable class for rational numbers
  • How different is Wittgenstein's Language game from Contextuality?
  • What would "doctor shoes" have looked like in "Man on the Moon"?
  • What is so special about JUICE's flyby with Earth and Moon?
  • What's the difference between "Model detail" and "Texture detail" in Portal 1?
  • How to remove Incoming/Outgoing changes graph in VSCode?
  • What happens if your child sells your car?
  • When did software only engines overtake custom hardware?
  • Four Year Old Pushing and Positive Discipline Techniques
  • Closed form of an integral using Mathematica or otherwise
  • Why did all countries converge on the exact same rules for voting (no poll tax, full suffrage, no maximum age, etc)?
  • How to get InverseMatrix for large size Matrix in Mathematica?
  • An English equivalent of the Japanese idiom "be tied with a red string (of destiny)"
  • How could ocean liners survive in a major capacity after large jet airliners become common?
  • A finance broker made me the primary instead of a co signer
  • A convergent, but large, sum of integer reciprocals
  • Are these friction shifters?
  • Does the volume of air in an air tight container affect food shelf life?
  • What is the English word for "tableau" in the context of the theatre?
  • When are these base spaces isomorphic?
  • Why don't charges on surface of current carrying wire move?
  • Running the plot of Final Fantasy X

view model presentation logic

IMAGES

  1. Free Logic Model Template PowerPoint & Google Slides

    view model presentation logic

  2. Logic Model PowerPoint Templates Diagrams

    view model presentation logic

  3. PowerPoint Logic Model Template

    view model presentation logic

  4. Key Elements Of Logic Model

    view model presentation logic

  5. Logic Model Template PowerPoint

    view model presentation logic

  6. Logic Model PowerPoint and Google Slides Template

    view model presentation logic

VIDEO

  1. Mathematical Model Presentation

  2. LARGE STRUCTURE MODEL PRESENTATION PART-1 IN REVIT IN HINDI

  3. Logic Model Presentation

  4. Logic model Presentation 1

  5. Business model presentation

  6. project presentation ( Digital logic)

COMMENTS

  1. c#

    2.View is a viewmodel presentation, viewmodel only needs bare minimum to expose model, the logic thus should be a part of the view. sounds more correct. What belongs to "bare minimum" depends on business logic requirements(e.g. warning must be shown, because of law requirements, such property would belong to VM) and on flair of designer. So ...

  2. Model-View-ViewModel

    The Model-View-ViewModel (MVVM) pattern helps cleanly separate an application's business and presentation logic from its user interface (UI). Maintaining a clean separation between application logic and the UI helps address numerous development issues and makes an application easier to test, maintain, and evolve.

  3. Model-View-ViewModel (MVVM) Explained

    The ViewModel (Our Controller/Presenter) The controller. The viewmodel is a key piece of the triad because it introduces Presentation Separation, or the concept of keeping the nuances of the view separate from the model. Instead of making the model aware of the user's view of a date, so that it converts the date to the display format, the ...

  4. Mastering MVVM: A Comprehensive Guide to the Model-View-ViewModel

    Introduction to MVVM. Model-View-ViewModel (MVVM) is a software architectural pattern that facilitates the separation of the development of the graphical user interface from the business logic or back-end logic (the data model). The View Model in MVVM represents an abstraction of the View, which contains a View's state and behavior.

  5. In MVVM, how much of the business logic should reside in the View Model

    Push as much logic as you can out of the View (code-behind) and into the View Model. Push as much logic as you can out of the View Model into the Model. That's it. The most common mistake I see in large WPF programs is putting too much of the program's logic into the View Models.

  6. WPF Tutorial

    The logic is tightly bound to the view. It's not possible to reuse the logic in an other view; So the idea is to move the whole presentation logic to the view model by using another feature of WPF, namely Commands. Commands can be bound like data and are supported by many elements as buttons, togglebuttons, menuitems, checkboxes and inputbindings.

  7. MVVM

    The advent of Windows Presentation Foundation (WPF) brought the concept of data binding to a whole new level. It has allowed a new design pattern called Model-View-ViewModel (MVVM) to evolve. MVVM lets you separate presentation logic from the actual presentation.

  8. Software Engineering: Model View ViewModel (MVVM)

    The term "Model-View-ViewModel" (MVVM) is a software architecture pattern commonly used in the development of software applications, especially in user interface applications such as web and mobile apps. MVVM is a variant of the Model-View-Controller (MVC) pattern and focuses on separating the presentation logic from the business logic of ...

  9. Presentation Model

    The Presentation Model contains the logic that says that the composer field is only enabled if the check box is checked, ... Presentation Model is a pattern that pulls presentation behavior from a view. As such it's an alternative to to Supervising Controller and Passive View. It's useful for allowing you to test without the UI, support for ...

  10. MVPVM Design Pattern

    Because a User ViewModel will be required in most applications, this is a reusable component. I have to be careful not to pollute it with business logic specific to the demo application. This isn't a problem with MVPVM, because the business logic will be handled by the Presenter, not within the ViewModel (see Figure 6).

  11. MVVM Architecture

    Learn about the significance of software architecture like MVVM, which separates UI from backend, enhancing maintainability. Explore MVVM's components: Model (business logic), View (UI), ViewModel (presentation logic). Implement it in WPF using ICommand, INotifyPropertyChanged for dynamic UI updates.

  12. Model-view-viewmodel

    Model Model refers either to a domain model, which represents real state content (an object-oriented approach), or to the data access layer, which represents content (a data-centric approach). [citation needed]View As in the model-view-controller (MVC) and model-view-presenter (MVP) patterns, the view is the structure, layout, and appearance of what a user sees on the screen.

  13. Our Way to MVVMI and Mistakes We Made When Implementing MVVM

    The purpose of ViewModel is to hold the presentation logic but there is another type of logic — business logic. The question is — Where to place it? When the project is small at the beginning, it makes sense to have it in ViewModel but with the course of the project added functionality and therefore more code creates a problem of a "God ...

  14. Introduction to Model View View Model (MVVM)

    VIEWMODEL: ( Reusable Code - LOGIC ) Link between Model and View OR It Retrieves data from Model and exposes it to the View. This is the model specifically designed for the View. ... View Model reads Model Objects and then facilitates the easy presentation of data on the view. The primary differences between MVVM AND MVC are as follows ...

  15. Model-view-presenter

    Diagram that depicts the model-view-presenter (MVP) GUI design pattern. Model-view-presenter (MVP) is a derivation of the model-view-controller (MVC) architectural pattern, and is used mostly for building user interfaces.. In MVP, the presenter assumes the functionality of the "middle-man". In MVP, all presentation logic is pushed to the presenter.

  16. Convert Your Native Project to Kotlin Multiplatform

    9. Migrate presentation logic. By migrating all the backend, storage, APIs, SDKs, and logic code, you should already be sharing around 50-60% of the code across Android and iOS applications. That is a pretty good number, but we can do even better. Our last step in the KMP migration is the presentation layer.

  17. Does a ViewModel have its own logic?

    The ViewModel should know nothing about your Business Classes, it should only know about the stuff that it needs to display. The main/only logic is then "Display Logic", that is stuff like "if TotalAmount is negative, display it with CSS Class negativeNumber". edited Jan 29, 2010 at 2:55. answered Jan 29, 2010 at 2:50.

  18. What's the difference between a ViewModel and Controller?

    The ViewModel is a Pattern used to handle the presentation logic and state of the View and the controller is one of the fundamentals parts of any MVC framework, it responds to any http request and orchestrates all the subsequent actions until the http response. The ViewModel Pattern: More info