Sign in Join

Live chat for Free Pascal, Lazarus, Delphi and every Pascal programmer.

Catalog · How the catalog works

Random project

delphi-mvp-clean-architecture

Projeto de referência em Delphi aplicando MVP (Passive View), Clean Architecture, SOLID, Injeção de Dependências (Composition Root), Pool de Conexões nativo FireDAC, DevExpress VCL e Testes Automatizados com DUnitX.

View on GitHub

Anyone may press Interesting, signed in or not. It helps others find this project.

Member rating

No ratings yet.

Sign in to rate this project.

README

🚀 Delphi MVP Clean Architecture Showcase

Projeto de referência corporativo em Delphi aplicando os padrões Model-View-Presenter (MVP) com Passive View, SOLID, Clean Code, Generics & Template Method, Domain Validations (CPF/CNPJ), Injeção de Dependências (Composition Root), Testes Unitários Automatizados (DUnitX) e Connection Pooling nativo com FireDAC.


📌 Visão Geral da Arquitetura

O projeto adota 100% de nomenclatura em Inglês no código-fonte (classes, interfaces, métodos e arquivos), mantendo a interface gráfica e mensagens localizadas em Português via resourcestring:

mermaid
flowchart TD
    subgraph CompositionRoot ["Composition Root & DI"]
        Container["Infrastructure.Container (TServiceContainer)"]
    end

    subgraph UI ["Presentation Layer (View)"]
        BaseForm["View.Base.Crud (TfrmBaseCrud)"]
        Form["View.Customer (TfrmCustomer)"] -->|Visual Inheritance| BaseForm
        Form -->|Implements| IView["ICustomerView : IBaseCrudView<T>"]
        Form -->|Local MemTable| Grid["TcxGrid (DevExpress)"]
    end

    subgraph PresenterLayer ["Presenter & Orchestration Layer"]
        BasePresenter["Presenter.Base.Crud<T, V, R>"]
        Presenter["Presenter.Customer (TCustomerPresenter)"] -->|Inherits| BasePresenter
        Presenter -->|Updates / Notifies| IView
        Presenter -->|Delegates Persistence| IRepo["ICustomerRepository : IBaseRepository<T>"]
        Presenter -->|Manipulates| Domain["Model.Customer (TCustomer, TPhone)"]
        Presenter -->|Validates via| Validator["Commons.Validators (TValidator)"]
    end

    subgraph DataLayer ["Persistence & Infrastructure Layer"]
        IRepo -->|Implemented by| RepoImpl["Repository.Customer.FireDAC"]
        RepoImpl -->|Uses via DI| IConn["IConnection"]
        IConn -->|Implemented by| ConnImpl["Infrastructure.Connection.FireDAC"]
        ConnImpl -->|Acquires from Pool| FactoryImpl["Infrastructure.Factory.FireDAC (IConnectionFactory)"]
        FactoryImpl -->|Manages Pool| FDManager["FireDAC FDManager (PoolFirebird)"]
        FDManager -->|Physical Connection| FB["Firebird 5.0"]
    end

    Container -.->|Builds & Injects| Presenter
    Container -.->|Builds & Injects| RepoImpl
    Container -.->|Builds & Injects| ConnImpl

💎 Padrões de Projeto & Princípios Aplicados

Padrão / Princípio Como é Aplicado no Projeto
Model-View-Presenter (MVP) A View é passiva e 100% desacoplada de SQL/banco. O Presenter orquestra todas as regras de tela e validações.
Generics & Template Method O fluxo de CRUD (OnSearch, OnNew, OnSave, OnDelete, OnCancel) foi escrito uma única vez no TBaseCrudPresenter<TEntity, TView, TRepo>.
Composition Root & DI Inversão de controle total: Infrastructure.Container orquestra a criação e injeção do Presenter, Repositório e Conexão. 📖 Ver Guia Detalhado
Automated Unit Testing Suíte de testes com DUnitX e Mocks em MVPCliente/Tests/, validando todas as regras e fluxos de tela em memória em milissegundos sem necessidade de banco de dados.
Domain Validation (DDD) Algoritmos de cálculo de dígito verificador de CPF e CNPJ e sanitização em Commons.Validators.pas com exceções de domínio tipadas (EValidationException).
Notification Pattern & Visual Highlighting Validação cumulativa destacando simultaneamente todos os campos com inconsistências em vermelho suave com tooltips e auto-foco no primeiro campo inválido.
Smart StatusBar & TTaskDialog Rodapé com barra de status dinâmica (TStatusBar) exibindo feedbacks de gravação temporários, estado em tempo real (Navegando / Inserindo / Editando) e diálogos nativos modernos com TTaskDialog.
Dirty State Protection O formulário base detecta alterações pendentes no FormCloseQuery e questiona o usuário antes de fechar a janela.
Connection Pooling Thread-Safe Conexões FireDAC isoladas por instância obtidas via IConnectionFactory configurada no FDManager, sem DataModules globais e sem Singletons.
Visual Form Inheritance TfrmBaseCrud padroniza painéis, botões e atalhos de teclado (F2, F3, F5, Esc) para todas as telas do sistema.
Clean Code & i18n Zero Magic Strings. Centralização de mensagens em Commons.Messages.pas usando resourcestring (tabela RT_STRING do Windows).
Zero Memory Leaks Ciclo de vida estrito com try .. finally Free; end;, TObjectList<T>.Create(True) e interfaces com contagem de referência.

🛠️ Stack Tecnológica & Versões dos Componentes

Categoria Tecnologia / Componente Versão / Padrão Finalidade no Projeto
IDE / Ferramenta Embarcadero RAD Studio / Delphi 10.1 Berlin / 10.4 Sydney / 11.x Alexandria (v22.0) / 12 Athens Ambiente de desenvolvimento integrado e compilador Object Pascal.
Compilador DCC32 / DCC64 Win32 / Win64 (Unicode) Compilação nativa com suporte completo a encoding UTF-8 com BOM (0xEF 0xBB 0xBF).
Acesso a Dados Embarcadero FireDAC Nativo do Delphi (v22.0+) Camada de persistência de alta performance com TFDConnection, TFDQuery, TFDTransaction.
Connection Pooling FireDAC FDManager Thread-Safe Pool (PoolMaximumItems = 50) Gerenciamento e reuso de conexões por demanda sem singletons ou DataModules globais.
Banco de Dados Firebird RDBMS Firebird 5.0 (compatível com 3.0 / 4.0) Banco relacional corporativo com Sequences, Triggers e Integridade Referencial (ON DELETE CASCADE).
Datasets em Memória TFDMemTable FireDAC in-memory dataset Desacoplamento das Views (mtPhones, mtCustomers) isolando os dados visuais do banco físico.
Grid Suite DevExpress ExpressQuantumGrid DevExpress VCL Suite (v20.x / v21.x / v22.x+) Grid corporativa avançada (TcxGrid, TcxGridDBTableView) com AutoFilterRow, FindPanel e IncSearch.
Controles de Edição DevExpress ExpressEditors DevExpress VCL Suite (v20.x / v21.x / v22.x+) Componentes de edição (TcxTextEdit, TcxGridDBColumn, cxLookAndFeels) com styling de validação em tempo real.
Diálogos Modernos TaskMessageDlg / Windows TaskDialog Windows 10 / 11 Native API Diálogos modernos integrados ao sistema operacional substituindo caixas modais legadas.
Barra de Status TStatusBar & TTimer VCL (Vcl.ComCtrls, Vcl.ExtCtrls) Rodapé inteligente com feedbacks temporários de gravação e indicador de estado (Navegando / Inserindo / Editando).
Testes Unitários DUnitX Testing Framework Nativo do RAD Studio Framework de testes automatizados com execução em memória de suítes de teste com Mocks.

📂 Estrutura de Pastas

text
Docs/
└── CompositionRoot_DI.md                # 📖 Guia arquitetural de Injeção de Dependências e Composition Root
MVPCliente/
├── Bin/                                 # Executáveis compilados (Win32/Release/Debug)
├── DCU/                                 # DCUs unificadas e isoladas dos fontes
├── Database/
│   ├── Script_Firebird5.sql             # DDL (Sequences, Tabelas, ON DELETE CASCADE)
│   └── mvp_delphi.fdb                   # Banco de dados Firebird de exemplo
├── Source/
│   ├── Commons/
│   │   ├── Commons.Exceptions.pas       # Exceções de Domínio (EDomainException, EValidationException)
│   │   ├── Commons.Validators.pas       # Validador de CPF, CNPJ e Sanitizadores
│   │   └── Commons.Messages.pas         # Strings de recurso com resourcestring
│   ├── Model/
│   │   └── Model.Customer.pas           # Entidades POO puras (TCustomer, TPhone)
│   ├── Infrastructure/
│   │   ├── Infrastructure.Connection.Interfaces.pas # Interface IConnection
│   │   ├── Infrastructure.Connection.FireDAC.pas    # Implementação FireDAC
│   │   ├── Infrastructure.Factory.Interfaces.pas    # Interface IConnectionFactory
│   │   ├── Infrastructure.Factory.FireDAC.pas       # Pool no FDManager + Config.ini
│   │   └── Infrastructure.Container.pas             # Composition Root / DI Factory
│   ├── Repository/
│   │   ├── Repository.Base.Interfaces.pas           # IBaseRepository<T>
│   │   ├── Repository.Customer.Interfaces.pas       # ICustomerRepository
│   │   └── Repository.Customer.FireDAC.pas          # Repositório FireDAC transacional
│   ├── Presenter/
│   │   ├── Presenter.Base.Crud.pas                  # Base Presenter genérico CRUD com IsDirty
│   │   ├── Presenter.Customer.pas                   # Presenter especializado com validações
│   │   └── Presenter.Customer.Search.pas            # Presenter de Pesquisa de Clientes
│   └── View/
│       ├── View.Base.Interfaces.pas                 # IBaseCrudView<T>
│       ├── View.Base.Crud.pas / .dfm                # Form base visual com Dirty State (CloseQuery)
│       ├── View.Customer.Interfaces.pas             # ICustomerView
│       ├── View.Customer.pas / .dfm                 # Form cliente com cxGrid DevExpress
│       ├── View.Customer.Search.Interfaces.pas      # ICustomerSearchView
│       └── View.Customer.Search.pas / .dfm          # Form de pesquisa com cxGrid, AutoFilter e FindPanel
├── Tests/                               # 🧪 Suíte de Testes Unitários Automatizados
│   ├── MVPClienteTests.dpr              # DUnitX Console Test Runner
│   ├── MVPClienteTests.dproj            # Projeto de Testes Delphi
│   ├── Test.Presenter.Customer.pas      # Testes com Mocks para TCustomerPresenter
│   └── Test.Presenter.Customer.Search.pas # Testes com Mocks para TCustomerSearchPresenter
├── Config.ini                           # Parâmetros de conexão editáveis
├── MVPCliente_Icon.ico                  # Ícone moderno da aplicação
└── MVPCliente.dpr                       # Ponto de entrada da aplicação

🧪 Como Executar os Testes Unitários (DUnitX)

  1. Abra o projeto MVPCliente/Tests/MVPClienteTests.dproj no Delphi.
  2. Compile e execute (F9).
  3. O console executará todos os testes com saída formatada:
    • Validações de CPF/CNPJ inválidos;
    • Campos obrigatórios (Nome, Documento, Telefones);
    • Fluxos de Inserção, Pesquisa, Salvamento, Exclusão e Cancelamento;
    • Proteção de Dirty State.

⚙️ Como Executar a Aplicação Principal

1. Pré-requisitos

  • Embarcadero Delphi 10.1 Berlin ou superior.
  • Firebird 5.0 instalado (porta padrão 3050).
  • Componentes DevExpress VCL instalados.

2. Configurar o Banco de Dados

  1. Execute o script MVPCliente/Database/Script_Firebird5.sql no seu Firebird ou utilize o arquivo MVPCliente/Database/mvp_delphi.fdb.
  2. Ajuste o caminho do banco no arquivo MVPCliente/Config.ini:
ini
[Database]
Path=[SEU_PATH]\mvp_delphi.fdb
Server=[IP_ADDRESS]
Port=[PORTA]
User_Name=[USER]
Password=[SENHA]
Pooled=True
PoolMaximumItems=[MAX_POOL]

3. Compilar e Executar

Abra o projeto MVPCliente/MVPCliente.dpr no Delphi e pressione F9 (ou Shift + F9 para Build).


👨‍💻 Autor & Contato

Desenvolvido como projeto de demonstração e boas práticas de arquitetura de software em Delphi.


Licença MIT - Sinta-se livre para usar como modelo em seus projetos.