MVVM: Organize sua Aplicação com Lógica e Facilidade

Imagine que você está desenvolvendo uma aplicação com interface📜 Interfaces: Contratos que Garantem a Ordem no Universo OOP!📜 Interfaces: Contratos que Garantem a Ordem no Universo OOP!Descubra como as interfaces em C# funcionam como contratos que garantem implementações flexíveis e robustas, facilitando o design e testes de sistemas. gráfica, e toda hora precisa mexer no código que controla a tela e, ao mesmo tempo, ajustar as regras de negócio. Isso pode virar uma bagunça bem rápido! É aí que entra o MVVM (Model-View-ViewModel), um padrão que permite separar a lógica da sua aplicação (regras de negócio) da interface📜 Interfaces: Contratos que Garantem a Ordem no Universo OOP!📜 Interfaces: Contratos que Garantem a Ordem no Universo OOP!Descubra como as interfaces em C# funcionam como contratos que garantem implementações flexíveis e robustas, facilitando o design e testes de sistemas. visual, deixando tudo mais organizado e fácil de dar manutenção.

A seguir, vamos explorar como o MVVM resolve esse problema🤝 GitHub Básico: Versionamento para Iniciantes!🤝 GitHub Básico: Versionamento para Iniciantes!Descubra como o GitHub facilita colaboração, versionamento e organização de código com este tutorial prático e essencial para desenvolvedores iniciantes. e oferecer exemplos práticos de como aplicá-lo no seu dia a dia.

Sumário🔗

1. O que é MVVM?

2. Motivação: Por que Separar Lógica da UI?

3. Estrutura MVVM: Model, View e📊 Behavior-Driven Development: Testes que Todo Mundo Entende!📊 Behavior-Driven Development: Testes que Todo Mundo Entende!Descubra como o BDD transforma testes em linguagens acessíveis. Aprenda a usar SpecFlow em C# para criar testes claros, colaborativos e sem ambiguidades. ViewModel

4. Data Binding📦 Data Binding: Conecte UI e Dados como um Maestro!📦 Data Binding: Conecte UI e Dados como um Maestro!Aprenda a utilizar Data Binding para conectar dados de forma automática entre back-end e interface, criando aplicações reativas e fáceis de manter.: Ligando Tudo sem “Cola”

5. Exemplo Prático📝 Logging com Serilog: Registre Tudo como um Detetive de Bugs!📝 Logging com Serilog: Registre Tudo como um Detetive de Bugs!Aprenda a usar Serilog em .NET para registrar logs estruturados, identificar erros e enriquecer informações, transformando seu código num enigma solucionável.: Formulário de Cadastro Simples

6. Dicas de Boas Práticas🔢 Operadores Aritméticos: Faça Cálculos como uma Calculadora Humana!🔢 Operadores Aritméticos: Faça Cálculos como uma Calculadora Humana!Aprenda a dominar operadores aritméticos em C# com exemplos práticos, técnicas de cálculo e dicas para evitar erros e maximizar resultados.

7. Conclusão

O que é MVVM?🔗

MVVM significa Model-View-ViewModel, um padrão de arquitetura criado para🔄 Loops em C#: Repita Tarefas sem Enlouquecer (Com for e while!)🔄 Loops em C#: Repita Tarefas sem Enlouquecer (Com for e while!)Descubra como automatizar repetições em C# utilizando loops for e while com exemplos práticos que evitam erros e otimizam seu código. Aprenda mais! separar claramente a regra de negócio (Model) da camada de exibição (View) através de um intermediário (ViewModel).

Essa abordagem aumenta a testabilidade, a manutenibilidade e a escalabilidade📡 RESTful 101: Princípios que Todo Dev API Precisa Saber!📡 RESTful 101: Princípios que Todo Dev API Precisa Saber!Descubra os fundamentos do REST e boas práticas para criar APIs simples, escaláveis e eficientes. Domine métodos HTTP e status codes com exemplos práticos. de qualquer aplicação que tenha interface gráfica.

Motivação: Por que Separar Lógica da UI?🔗

Suponha que você desenvolva um aplicativo de vendas. Se todo o código da tela de cadastro de produtos estiver misturado com as regras que calculam impostos, vai ser muito mais complicado fazer modificações ou adicionar📦 List<T>: Dinamismo além dos Arrays!📦 List<T>: Dinamismo além dos Arrays!Descubra como utilizar List<T> em C# de forma eficiente. Aprenda a criar, manipular e otimizar listas para diferentes cenários com exemplos práticos. novas funcionalidades:

Com MVVM, cada parte do sistema fica no seu devido lugar. Assim, você pode testar as regras de negócio sem precisar abrir a interface📜 Interfaces: Contratos que Garantem a Ordem no Universo OOP!📜 Interfaces: Contratos que Garantem a Ordem no Universo OOP!Descubra como as interfaces em C# funcionam como contratos que garantem implementações flexíveis e robustas, facilitando o design e testes de sistemas. gráfica, e a View se torna apenas responsável pela exibição.

Estrutura MVVM: Model, View e ViewModel🔗

Model

O Model mantém os dados e as validações de negócio. Por exemplo, uma classe🏗️ Classes vs. Structs: Quando Usar Cada Uma (e Não Quebrar a Cabeça)!🏗️ Classes vs. Structs: Quando Usar Cada Uma (e Não Quebrar a Cabeça)!Descubra como escolher entre classes e structs em C#. Aprenda sobre alocação de memória, passagem por valor e referência, e performance nesta explicação clara. Produto🔢 Operadores Aritméticos: Faça Cálculos como uma Calculadora Humana!🔢 Operadores Aritméticos: Faça Cálculos como uma Calculadora Humana!Aprenda a dominar operadores aritméticos em C# com exemplos práticos, técnicas de cálculo e dicas para evitar erros e maximizar resultados. com propriedades⚡ Propriedades: Get e Set com Elegância (e sem Campos Privados Bagunçados)!⚡ Propriedades: Get e Set com Elegância (e sem Campos Privados Bagunçados)!Aprenda como utilizar propriedades em C# para encapsular dados, validar informações e manter um código organizado, seguro e de fácil manutenção. como Nome, Preço e métodos🧠 Métodos em C#: Como Criar Funções que Não São Só Enfeites!🧠 Métodos em C#: Como Criar Funções que Não São Só Enfeites!Otimize seu código em C# com métodos inteligentes. Aprenda práticas de reutilização, sobrecarga e escopo para melhorar a clareza e a eficiência. para calcular descontos.

public class Produto
{
    public string Nome { get; set; }
    public decimal Preco { get; set; }
    public decimal CalcularDesconto(decimal percentual)
    {
        return Preco - (Preco * percentual / 100);
    }
}

View

A View é simplesmente a representação📡 RESTful 101: Princípios que Todo Dev API Precisa Saber!📡 RESTful 101: Princípios que Todo Dev API Precisa Saber!Descubra os fundamentos do REST e boas práticas para criar APIs simples, escaláveis e eficientes. Domine métodos HTTP e status codes com exemplos práticos. gráfica, como uma janela ou tela. Nela, você não deve encontrar regras de negócio, mas sim definições de layout - botões, textos e campos.

ViewModel

O ViewModel é a cola entre Model e View. Nele ficam propriedades⚡ Propriedades: Get e Set com Elegância (e sem Campos Privados Bagunçados)!⚡ Propriedades: Get e Set com Elegância (e sem Campos Privados Bagunçados)!Aprenda como utilizar propriedades em C# para encapsular dados, validar informações e manter um código organizado, seguro e de fácil manutenção. que a View vai exibir e métodos (ou comandos) que a View pode acionar. Geralmente, ele implementa o INotifyPropertyChanged📦 Data Binding: Conecte UI e Dados como um Maestro!📦 Data Binding: Conecte UI e Dados como um Maestro!Aprenda a utilizar Data Binding para conectar dados de forma automática entre back-end e interface, criando aplicações reativas e fáceis de manter. para notificar a interface📜 Interfaces: Contratos que Garantem a Ordem no Universo OOP!📜 Interfaces: Contratos que Garantem a Ordem no Universo OOP!Descubra como as interfaces em C# funcionam como contratos que garantem implementações flexíveis e robustas, facilitando o design e testes de sistemas. quando algo muda.

using System.ComponentModel;
using System.Runtime.CompilerServices;
public class ProdutoViewModel : INotifyPropertyChanged
{
    private Produto _produto;
    private decimal _desconto;
    private decimal _precoComDesconto;
    public ProdutoViewModel()
    {
        _produto = new Produto();
    }
    public string Nome
    {
        get => _produto.Nome;
        set
        {
            _produto.Nome = value;
            NotifyPropertyChanged();
        }
    }
    public decimal Preco
    {
        get => _produto.Preco;
        set
        {
            _produto.Preco = value;
            NotifyPropertyChanged();
        }
    }
    public decimal Desconto
    {
        get => _desconto;
        set
        {
            _desconto = value;
            NotifyPropertyChanged();
        }
    }
    public decimal PrecoComDesconto
    {
        get => _precoComDesconto;
        private set
        {
            _precoComDesconto = value;
            NotifyPropertyChanged();
        }
    }
    public void CalcularDesconto()
    {
        PrecoComDesconto = _produto.CalcularDesconto(_desconto);
    }
    public event PropertyChangedEventHandler PropertyChanged;
    private void NotifyPropertyChanged([CallerMemberName] string propName = null)
    {
        PropertyChanged?.Invoke(this, new PropertyChangedEventArgs(propName));
    }
}

Observe que a ViewModel expõe dados e comportamentos diretamente úteis para a interface📜 Interfaces: Contratos que Garantem a Ordem no Universo OOP!📜 Interfaces: Contratos que Garantem a Ordem no Universo OOP!Descubra como as interfaces em C# funcionam como contratos que garantem implementações flexíveis e robustas, facilitando o design e testes de sistemas. (nome do produto, preço, cálculo de desconto), sem que a View precise conhecer os detalhes internos do Produto🔢 Operadores Aritméticos: Faça Cálculos como uma Calculadora Humana!🔢 Operadores Aritméticos: Faça Cálculos como uma Calculadora Humana!Aprenda a dominar operadores aritméticos em C# com exemplos práticos, técnicas de cálculo e dicas para evitar erros e maximizar resultados..

Data Binding: Ligando Tudo sem “Cola”🔗

No MVVM, o Data Binding📦 Data Binding: Conecte UI e Dados como um Maestro!📦 Data Binding: Conecte UI e Dados como um Maestro!Aprenda a utilizar Data Binding para conectar dados de forma automática entre back-end e interface, criando aplicações reativas e fáceis de manter. é o mecanismo que faz a View “escutar” o ViewModel. Quando o ViewModel atualiza uma propriedade⚡ Propriedades: Get e Set com Elegância (e sem Campos Privados Bagunçados)!⚡ Propriedades: Get e Set com Elegância (e sem Campos Privados Bagunçados)!Aprenda como utilizar propriedades em C# para encapsular dados, validar informações e manter um código organizado, seguro e de fácil manutenção. (como PrecoComDesconto), a tela reflete essa mudança automaticamente, sem precisar de código extra na View.

Da mesma forma, quando o usuário digita algo na tela, o ViewModel recebe esse valor pela ligação de dados. Tudo acontece de forma declarativa🖌️ XAML Básico: Crie Interfaces sem Código C# (Quase)!🖌️ XAML Básico: Crie Interfaces sem Código C# (Quase)!Descubra como usar XAML para criar interfaces atrativas em aplicações .NET. Aprenda conceitos e dicas práticas para iniciar seu projeto., mantendo a separação das camadas.

Exemplo Prático: Formulário de Cadastro Simples🔗

Imagine um formulário de cadastro de produto🔢 Operadores Aritméticos: Faça Cálculos como uma Calculadora Humana!🔢 Operadores Aritméticos: Faça Cálculos como uma Calculadora Humana!Aprenda a dominar operadores aritméticos em C# com exemplos práticos, técnicas de cálculo e dicas para evitar erros e maximizar resultados. que tenha:

O ViewModel expõe esses campos e um método🧠 Métodos em C#: Como Criar Funções que Não São Só Enfeites!🧠 Métodos em C#: Como Criar Funções que Não São Só Enfeites!Otimize seu código em C# com métodos inteligentes. Aprenda práticas de reutilização, sobrecarga e escopo para melhorar a clareza e a eficiência. (CalcularDesconto()). Quando o usuário clica no botão, o desconto é calculado e a tela atualiza automaticamente a propriedade⚡ Propriedades: Get e Set com Elegância (e sem Campos Privados Bagunçados)!⚡ Propriedades: Get e Set com Elegância (e sem Campos Privados Bagunçados)!Aprenda como utilizar propriedades em C# para encapsular dados, validar informações e manter um código organizado, seguro e de fácil manutenção. PrecoComDesconto.

Dicas de Boas Práticas🔗

Conclusão🔗

O MVVM é um padrão que traz organização e📊 Behavior-Driven Development: Testes que Todo Mundo Entende!📊 Behavior-Driven Development: Testes que Todo Mundo Entende!Descubra como o BDD transforma testes em linguagens acessíveis. Aprenda a usar SpecFlow em C# para criar testes claros, colaborativos e sem ambiguidades. clareza para aplicações de interface📜 Interfaces: Contratos que Garantem a Ordem no Universo OOP!📜 Interfaces: Contratos que Garantem a Ordem no Universo OOP!Descubra como as interfaces em C# funcionam como contratos que garantem implementações flexíveis e robustas, facilitando o design e testes de sistemas. gráfica, separando adequadamente a lógica do seu Model e📊 Behavior-Driven Development: Testes que Todo Mundo Entende!📊 Behavior-Driven Development: Testes que Todo Mundo Entende!Descubra como o BDD transforma testes em linguagens acessíveis. Aprenda a usar SpecFlow em C# para criar testes claros, colaborativos e sem ambiguidades. ViewModel da camada visual (View). Isso facilita a manutenção, torna o projeto🤝 GitHub Básico: Versionamento para Iniciantes!🤝 GitHub Básico: Versionamento para Iniciantes!Descubra como o GitHub facilita colaboração, versionamento e organização de código com este tutorial prático e essencial para desenvolvedores iniciantes. mais modular e permite testar tudo de forma isolada. Se você está cansado de lidar com telas cheias de regras de negócio embutidas, experimente o MVVM para dar uma bela arrumada no seu código!

🔍 O Problema que o MVVM Resolve🔗

Antes do MVVM, era comum ver código como este (anti-padrão!):

// Exemplo de código acoplado (View diretamente manipula lógica)
public partial class MainWindow : Window
{
    public MainWindow()
    {
        InitializeComponent();
    }
    private void btnCalcular_Click(object sender, RoutedEventArgs e)
    {
        // Lógica de negócio DENTRO da View!
        double peso = Convert.ToDouble(txtPeso.Text);
        double altura = Convert.ToDouble(txtAltura.Text);
        double imc = peso / (altura * altura);
        lblResultado.Content = $"Seu IMC: {imc:F2}";
    }
}

Problemas:

🏛️ Pilares do MVVM🔗

Model (Negócio)

public class CalculadoraIMC
{
    public double Calcular(double peso, double altura)
    {
        if (altura == 0) throw new ArgumentException("Altura não pode ser zero");
        return peso / (altura * altura);
    }
}

ViewModel (Intermediador)

public class MainViewModel : INotifyPropertyChanged
{
    private double _peso;
    private double _altura;
    private double _imc;
    public double Peso
    {
        get => _peso;
        set { _peso = value; OnPropertyChanged(); CalcularIMC(); }
    }
    // Implementação similar para Altura e IMC...
    private void CalcularIMC()
    {
        var calculadora = new CalculadoraIMC();
        IMC = calculadora.Calcular(Peso, Altura);
    }
}

View (Interface)

<!-- XAML da View -->
<TextBox Text="{Binding Peso, UpdateSourceTrigger=PropertyChanged}" />
<TextBox Text="{Binding Altura}" />
<TextBlock Text="{Binding IMC}" />

👩💻 Implementação Prática: Criando uma Calculadora de IMC🔗

Passo 1: Estrutura do Projeto

MyIMCApp/
├── Models/
│   └── CalculadoraIMC.cs
├── ViewModels/
│   └── MainViewModel.cs
└── Views/
    └── MainWindow.xaml

Passo 2: ViewModel Base

public abstract class ViewModelBase : INotifyPropertyChanged
{
    public event PropertyChangedEventHandler? PropertyChanged;
    protected virtual void OnPropertyChanged([CallerMemberName] string? propertyName = null)
    {
        PropertyChanged?.Invoke(this, new PropertyChangedEventArgs(propertyName));
    }
}

🔗 Data Binding e Commands: A Magia do MVVM🔗

Binding Básico

<TextBlock Text="{Binding MensagemBoasVindas}" />

Binding com Commands

// ViewModel
public ICommand CalcularCommand => new RelayCommand(Calcular);
private void Calcular()
{
    // Lógica de cálculo aqui
}
<Button Content="Calcular" Command="{Binding CalcularCommand}" />

⚡ INotifyPropertyChanged: Notificando Mudanças como um Chef🔗

Implementação inteligente:

public class SmartViewModel : ViewModelBase
{
    private string _nome;
    public string Nome
    {
        get => _nome;
        set => SetField(ref _nome, value);
    }
    protected bool SetField<T>(ref T field, T value, [CallerMemberName] string propertyName = "")
    {
        if (EqualityComparer<T>.Default.Equals(field, value)) return false;
        field = value;
        OnPropertyChanged(propertyName);
        return true;
    }
}

🆚 MVVM vs. MVC vs. MVP: Qual Escolher?🔗

CaracterísticaMVVMMVCMVP
AcoplamentoBaixo (Data Binding)ModeradoModerado
TestabilidadeAlta (ViewModel)Média (Controller)Alta (Presenter)
Uso TípicoWPF, MAUIWeb (ASP.NET)Windows Forms
ResponsabilidadeSeparação claraController mediaPresenter media

🎯 Desafio Prático: Crie um Contador de Palavras com MVVM🔗

Requisitos:

1. Campo de texto📝 Strings em C#: Manipule Textos como um Mestre dos Caracteres!📝 Strings em C#: Manipule Textos como um Mestre dos Caracteres!Aprenda a dominar os segredos das strings em C# com técnicas de manipulação, concatenação, interpolação e boas práticas, impulsionando sua performance. para entrada

2. Exibição do número de palavras

3. Botão "Limpar"

4. Validação: Não permitir texto📝 Strings em C#: Manipule Textos como um Mestre dos Caracteres!📝 Strings em C#: Manipule Textos como um Mestre dos Caracteres!Aprenda a dominar os segredos das strings em C# com técnicas de manipulação, concatenação, interpolação e boas práticas, impulsionando sua performance. vazio

Dica de Implementação:

// ViewModel
public class WordCounterViewModel : ViewModelBase
{
    private string _texto;
    public string Texto
    {
        get => _texto;
        set
        {
            SetField(ref _texto, value);
            ContagemPalavras = _texto.Split(new[] {' '}, StringSplitOptions.RemoveEmptyEntries).Length;
        }
    }
    private int _contagem;
    public int ContagemPalavras
    {
        get => _contagem;
        private set => SetField(ref _contagem, value);
    }
    public ICommand LimparCommand => new RelayCommand(() => Texto = string.Empty);
}

Conclusão🔗

O MVVM não é só um padrão, é uma filosofia de desenvolvimento que:

Para🔄 Loops em C#: Repita Tarefas sem Enlouquecer (Com for e while!)🔄 Loops em C#: Repita Tarefas sem Enlouquecer (Com for e while!)Descubra como automatizar repetições em C# utilizando loops for e while com exemplos práticos que evitam erros e otimizam seu código. Aprenda mais! Product Managers e QAs: entender essa estrutura ajuda a comunicar melhor com devs, sabendo exatamente onde propor mudanças (View para UX, ViewModel para fluxos, Model para🔄 Loops em C#: Repita Tarefas sem Enlouquecer (Com for e while!)🔄 Loops em C#: Repita Tarefas sem Enlouquecer (Com for e while!)Descubra como automatizar repetições em C# utilizando loops for e while com exemplos práticos que evitam erros e otimizam seu código. Aprenda mais! regras).

Próximo passo? Experimente implementar o desafio e📊 Behavior-Driven Development: Testes que Todo Mundo Entende!📊 Behavior-Driven Development: Testes que Todo Mundo Entende!Descubra como o BDD transforma testes em linguagens acessíveis. Aprenda a usar SpecFlow em C# para criar testes claros, colaborativos e sem ambiguidades. explore frameworks como MVVM Toolkit ou Prism para recursos📡 RESTful 101: Princípios que Todo Dev API Precisa Saber!📡 RESTful 101: Princípios que Todo Dev API Precisa Saber!Descubra os fundamentos do REST e boas práticas para criar APIs simples, escaláveis e eficientes. Domine métodos HTTP e status codes com exemplos práticos. avançados!

Autor: Marcelo V. Souza - Engenheiro de Sistemas e Entusiasta em IoT e Desenvolvimento de Software, com foco em inovação tecnológica.

Referências🔗

Compartilhar artigo