|
| O que é o Padrão Builder? |
| Iniciado por Boller, jul., 25 2025 6:11 AM - 5 respostas |
| |
| | | |
|
| |
Membro registado 4.618 mensagems |
|
| Publicado em julho, 25 2025 - 6:11 AM |
**O Padrão Builder** é um padrão de design criacional que separa a construção de um objeto complexo de sua representação , permitindo criar objetos de forma estruturada e flexível.
### Características principais:
1. **Construção Step-by-Step**: Permite construir objetos complexos passo a passo 1. **Flexibilidade**: O mesmo processo de construção pode criar diferentes representações 1. **Legibilidade**: Oferece uma interface fluente que permite encadear métodos, tornando o código mais intuitivo e legível 1. **Validação**: Garante que todos os parâmetros obrigatórios sejam definidos antes do objeto ser construído
### Principais vantagens:
- **Evita construtores complexos** com muitos parâmetros - **Permite validação** antes da criação do objeto - **Facilita criação de objetos imutáveis** - **Melhora a legibilidade** do código
O exemplo que criei mostra como implementar este padrão em WinDev para um sistema de criação de relatórios, demonstrando a sintaxe fluente e as validações típicas do padrão Builder.
# Padrão Builder em WinDev (Builder Design Pattern)
## O que é o Padrão Builder?
O **Padrão Builder** é um padrão de design criacional que permite construir objetos complexos passo a passo. Ele separa a construção de um objeto complexo de sua representação, permitindo que o mesmo processo de construção possa criar diferentes representações do objeto.
### Principais características:
- **Construção Step-by-Step**: Permite criar objetos em etapas - **Flexibilidade**: Mesmo processo pode criar diferentes representações - **Legibilidade**: Código mais claro e intuitivo - **Validação**: Permite validar o objeto antes da criação
## Exemplo em WinDev (Português)
### Cenário: Sistema de Criação de Relatórios
```windev // Classe principal - Relatório Relatorio é uma Classe PRIVADO m_titulo é cadeia m_subtitulo é cadeia m_dados é array de cadeia m_formato é cadeia m_orientacao é cadeia FIM // Getters PROPRIEDADE Titulo() RESULTADO m_titulo FIM PROPRIEDADE Subtitulo() RESULTADO m_subtitulo FIM PROPRIEDADE Dados() RESULTADO m_dados FIM FIM
// Classe Builder RelatorioBuilder é uma Classe PRIVADO m_relatorio é Relatorio FIM // Construtor PROCEDIMENTO Construtor() m_relatorio = novo Relatorio() FIM // Métodos de construção PROCEDIMENTO ComTitulo(titulo é cadeia) m_relatorio.m_titulo = titulo RESULTADO Este FIM PROCEDIMENTO ComSubtitulo(subtitulo é cadeia) m_relatorio.m_subtitulo = subtitulo RESULTADO Este FIM PROCEDIMENTO AdicionarDados(dados é cadeia) m_relatorio.m_dados.Adicionar(dados) RESULTADO Este FIM PROCEDIMENTO ComFormato(formato é cadeia) m_relatorio.m_formato = formato RESULTADO Este FIM PROCEDIMENTO ComOrientacao(orientacao é cadeia) m_relatorio.m_orientacao = orientacao RESULTADO Este FIM // Método final de construção PROCEDIMENTO Construir() // Validações antes de criar o objeto SE m_relatorio.m_titulo = "" ENTÃO RESULTADO Nulo FIM relatorio_final é Relatorio = m_relatorio m_relatorio = novo Relatorio() // Reset para próximo uso RESULTADO relatorio_final FIM FIM
// Uso do Builder PROCEDIMENTO CriarRelatorio() builder é RelatorioBuilder = novo RelatorioBuilder() relatorio é Relatorio = builder.ComTitulo("Relatório de Vendas") .ComSubtitulo("Janeiro 2025") .AdicionarDados("Vendas: R$ 150.000") .AdicionarDados("Meta: R$ 120.000") .ComFormato("PDF") .ComOrientacao("Retrato") .Construir() SE relatorio <> Nulo ENTÃO Info("Relatório criado: " + relatorio.Titulo()) SENÃO Erro("Erro ao criar relatório - dados obrigatórios não informados") FIM FIM ```
## Example in WinDev (English)
### Scenario: Report Creation System
```windev // Main class - Report Report IS a Class PRIVATE m_title is string m_subtitle is string m_data is array of string m_format is string m_orientation is string END // Getters PROPERTY Title() RESULT m_title END PROPERTY Subtitle() RESULT m_subtitle END PROPERTY Data() RESULT m_data END END
// Builder class ReportBuilder IS a Class PRIVATE m_report is Report END // Constructor PROCEDURE Constructor() m_report = new Report() END // Construction methods PROCEDURE WithTitle(title is string) m_report.m_title = title RESULT This END PROCEDURE WithSubtitle(subtitle is string) m_report.m_subtitle = subtitle RESULT This END PROCEDURE AddData(data is string) m_report.m_data.Add(data) RESULT This END PROCEDURE WithFormat(format is string) m_report.m_format = format RESULT This END PROCEDURE WithOrientation(orientation is string) m_report.m_orientation = orientation RESULT This END // Final construction method PROCEDURE Build() // Validations before creating the object IF m_report.m_title = "" THEN RESULT Null END final_report is Report = m_report m_report = new Report() // Reset for next use RESULT final_report END END
// Using the Builder PROCEDURE CreateReport() builder is ReportBuilder = new ReportBuilder() report is Report = builder.WithTitle("Sales Report") .WithSubtitle("January 2025") .AddData("Sales: $150,000") .AddData("Target: $120,000") .WithFormat("PDF") .WithOrientation("Portrait") .Build() IF report <> Null THEN Info("Report created: " + report.Title()) ELSE Error("Error creating report - required data not provided") END END ```
## Vantagens do Padrão Builder
### 1. **Legibilidade do Código**
O código fica mais claro e auto-documentado, mostrando exatamente como o objeto está sendo construído.
### 2. **Flexibilidade**
Permite criar diferentes tipos de objetos usando o mesmo processo de construção.
### 3. **Validação**
Pode validar os dados antes de criar o objeto final, garantindo consistência.
### 4. **Method Chaining**
Permite encadear métodos para uma sintaxe mais fluente.
### 5. **Objetos Imutáveis**
Facilita a criação de objetos imutáveis e thread-safe.
## Quando Usar o Padrão Builder
- **Objetos complexos** com muitos parâmetros opcionais - **Construção passo a passo** é necessária - **Diferentes representações** do mesmo objeto - **Validação complexa** antes da criação - **Evitar construtores** com muitos parâmetros
## Advantages of Builder Pattern
### 1. **Code Readability**
The code becomes clearer and self-documenting, showing exactly how the object is being constructed.
### 2. **Flexibility**
Allows creating different types of objects using the same construction process.
### 3. **Validation**
Can validate data before creating the final object, ensuring consistency.
### 4. **Method Chaining**
Enables method chaining for more fluent syntax.
### 5. **Immutable Objects**
Facilitates creation of immutable and thread-safe objects.
## When to Use Builder Pattern
- **Complex objects** with many optional parameters - **Step-by-step construction** is needed - **Different representations** of the same object - **Complex validation** before creation - **Avoid constructors** with many parameters
-- Adriano José Boller ______________________________________________ Consultor e Representante Oficial da PcSoft no Brasil +55 (41) 99949 1800 adrianoboller@gmail.com skype: adrianoboller http://wxinformatica.com.br/ |
| |
| |
| | | |
|
| | |
| |
Membro registado 4.618 mensagems |
|
| Publicado em julho, 25 2025 - 6:12 AM |
Desculpe pela confusão! Abaixo, apresento uma explicação revisada do padrão Builder com exemplos em WLangage (linguagem usada no ambiente WinDev da PCSoft), conforme mencionado no post de Issam Ouzali. Vou fornecer um exemplo em português e outro em inglês, mantendo a estrutura do padrão Builder e adaptando ao contexto do WinDev.
Explicação do Padrão Builder em WLangage O padrão Builder em WLangage é útil para criar objetos complexos de forma estruturada, especialmente quando se trabalha com registros, estruturas ou classes no WinDev. Como WLangage é a linguagem nativa do WinDev, usaremos uma classe para representar o produto e um Builder interno para construir o objeto passo a passo. Isso evita construtores complexos e melhora a legibilidade do código, como destacado no post. Por que usar o Builder em WLangage? • Permite configurar objetos com muitos parâmetros opcionais de forma clara. • Facilita a manutenção e a reutilização do código. • É ideal para criar registros ou objetos com configurações variadas, como em formulários ou relatórios no WinDev. Estrutura no WinDev: • Classe Produto: Representa o objeto final (por exemplo, um carro ou uma casa). • Classe Builder: Uma classe interna ou auxiliar que define métodos para configurar os atributos. • Método de Construção: Finaliza a criação do objeto com base nas configurações definidas.
Exemplo em Português (WLangage) Contexto Vamos criar uma classe Carro com atributos como modelo, cor, motor e ano. O Builder será implementado como uma classe interna para configurar o objeto de forma fluida. // Classe Carro (Produto) CLASS Carro PUBLIC modelo IS string cor IS string motor IS string ano IS int END
// Procedimento para exibir o objeto (equivalente a toString) PROCEDURE Carro::toString() IS string RESULT "Carro [modelo=" + modelo + ", cor=" + cor + ", motor=" + motor + ", ano=" + ano + "]"
// Classe Builder interna CLASS Carro::Builder PRIVATE carro IS Carro // Instância do objeto a ser construído PUBLIC PROCEDURE Builder(modelo IS string) carro IS Carro carro..modelo = modelo // Atributo obrigatório END
PROCEDURE comCor(cor IS string) IS Builder carro..cor = cor RESULT THIS END
PROCEDURE comMotor(motor IS string) IS Builder carro..motor = motor RESULT THIS END
PROCEDURE comAno(ano IS int) IS Builder carro..ano = ano RESULT THIS END
PROCEDURE build() IS Carro RESULT carro END END
// Exemplo de uso PROCEDURE Main() meuCarro IS Carro meuCarro = Carro::Builder("Fusca")::comCor("Azul")::comMotor("1.6")::comAno(1970)::build() Info(meuCarro..toString()) END Saída no WinDev: Carro [modelo=Fusca, cor=Azul, motor=1.6, ano=1970] Explicação do Código em Português • A classe Carro define os atributos do objeto (modelo, cor, motor, ano). • A classe interna Builder gerencia a construção do objeto Carro. • O método Builder inicializa o objeto com o atributo obrigatório modelo. • Métodos como comCor, comMotor e comAno configuram os atributos opcionais e retornam THIS para encadeamento. • O método build retorna o objeto Carro configurado. • O procedimento Main demonstra como criar um objeto usando o Builder de forma fluida.
Exemplo em Inglês (WLangage) Context We will create a House class with attributes like type, color, floors, and garden. The Builder will be implemented as an inner class to configure the object step-by-step. // Class House (Product) CLASS House PUBLIC type IS string color IS string floors IS int hasGarden IS boolean END
// Procedure to display the object (equivalent to toString) PROCEDURE House::toString() IS string RESULT "House [type=" + type + ", color=" + color + ", floors=" + floors + ", hasGarden=" + hasGarden + "]"
// Inner Builder class CLASS House::Builder PRIVATE house IS House // Instance of the object to be built PUBLIC PROCEDURE Builder(type IS string) house IS House house..type = type // Mandatory attribute END
PROCEDURE withColor(color IS string) IS Builder house..color = color RESULT THIS END
PROCEDURE withFloors(floors IS int) IS Builder house..floors = floors RESULT THIS END
PROCEDURE withGarden(hasGarden IS boolean) IS Builder house..hasGarden = hasGarden RESULT THIS END
PROCEDURE build() IS House RESULT house END END
// Example usage PROCEDURE Main() myHouse IS House myHouse = House::Builder("Cottage")::withColor("White")::withFloors(2)::withGarden(True)::build() Info(myHouse..toString()) END Output in WinDev: House [type=Cottage, color=White, floors=2, hasGarden=True] Explanation of the Code in English • The House class defines the attributes of the object (type, color, floors, hasGarden). • The inner Builder class manages the construction of the House object. • The Builder procedure initializes the object with the mandatory type attribute. • Methods like withColor, withFloors, and withGarden configure optional attributes and return THIS for method chaining. • The build method returns the configured House object. • The Main procedure demonstrates how to create a House object using the Builder fluently.
Observações • WLangage e WinDev: O código usa a sintaxe específica do WLangage, como IS, PROCEDURE, e THIS, que são características do ambiente WinDev. A função Info exibe a saída no WinDev. • Builder Interno: Seguindo a sugestão de Issam Ouzali no post, implementei um Builder interno estático (adaptado para WLangage, que não usa static explicitamente, mas a classe interna funciona de forma semelhante). • Contexto do Post: O post enfatiza o uso do Builder para melhorar a legibilidade e manutenibilidade, o que é especialmente relevante em projetos WinDev, onde objetos complexos (como formulários ou relatórios) podem ter muitas configurações. Se precisar de mais detalhes, como a integração com formulários ou relatórios no WinDev, ou ajustes no código, é só avisar!
-- Adriano José Boller ______________________________________________ Consultor e Representante Oficial da PcSoft no Brasil +55 (41) 99949 1800 adrianoboller@gmail.com skype: adrianoboller http://wxinformatica.com.br/ |
| |
| |
| | | |
|
| | |
| |
Membro registado 4.618 mensagems |
|
| Publicado em julho, 25 2025 - 6:13 AM |
Abaixo, apresento novos exemplos do padrão Builder em WLangage (usado no ambiente WinDev), conforme solicitado, com um exemplo em português e outro em inglês. Os exemplos são diferentes dos anteriores, com novos contextos, mantendo a essência do padrão Builder e a sintaxe do WLangage. Cada exemplo inclui explicações detalhadas e está alinhado com o post de Issam Ouzali, que destaca a criação de objetos complexos de forma clara e manutenível.
Exemplo em Português (WLangage) Contexto Vamos criar uma classe Pedido para representar um pedido em um sistema de e-commerce. O pedido pode ter atributos como número do pedido (obrigatório), cliente, valor total e status de entrega. O Builder será usado para configurar o objeto de forma fluida. // Classe Pedido (Produto) CLASS Pedido PUBLIC numeroPedido IS string cliente IS string valorTotal IS real statusEntrega IS string END
// Procedimento para exibir o objeto PROCEDURE Pedido::toString() IS string RESULT "Pedido [numero=" + numeroPedido + ", cliente=" + cliente + ", valor=" + valorTotal + ", status=" + statusEntrega + "]"
// Classe Builder interna CLASS Pedido::Builder PRIVATE pedido IS Pedido // Instância do objeto a ser construído PUBLIC PROCEDURE Builder(numero IS string) pedido IS Pedido pedido..numeroPedido = numero // Atributo obrigatório END
PROCEDURE comCliente(cliente IS string) IS Builder pedido..cliente = cliente RESULT THIS END
PROCEDURE comValor(valor IS real) IS Builder pedido..valorTotal = valor RESULT THIS END
PROCEDURE comStatus(status IS string) IS Builder pedido..statusEntrega = status RESULT THIS END
PROCEDURE build() IS Pedido RESULT pedido END END
// Exemplo de uso PROCEDURE Main() meuPedido IS Pedido meuPedido = Pedido::Builder("PED123")::comCliente("João Silva")::comValor(150.75)::comStatus("Em trânsito")::build() Info(meuPedido..toString()) END Saída no WinDev: Pedido [numero=PED123, cliente=João Silva, valor=150.75, status=Em trânsito] Explicação do Código em Português • Classe Pedido: Representa o produto final com atributos como numeroPedido (obrigatório), cliente, valorTotal e statusEntrega. • Classe Builder: Uma classe interna que gerencia a construção do objeto. O procedimento Builder inicializa o objeto com o número do pedido. • Métodos de Configuração: comCliente, comValor e comStatus configuram os atributos opcionais e retornam THIS para encadeamento. • Método build: Retorna o objeto Pedido configurado. • Uso no Main: Demonstra a criação fluida de um pedido, configurando apenas os atributos desejados. • Contexto no WinDev: Este exemplo é útil em sistemas de e-commerce ou ERP no WinDev, onde pedidos podem ter várias configurações (por exemplo, em formulários ou relatórios).
Exemplo em Inglês (WLangage) Context We will create a Computer class to represent a computer system in an inventory application. The computer has attributes like serial number (mandatory), processor, ram, and storage. The Builder pattern will allow flexible configuration. // Class Computer (Product) CLASS Computer PUBLIC serialNumber IS string processor IS string ram IS int storage IS string END
// Procedure to display the object PROCEDURE Computer::toString() IS string RESULT "Computer [serial=" + serialNumber + ", processor=" + processor + ", ram=" + ram + ", storage=" + storage + "]"
// Inner Builder class CLASS Computer::Builder PRIVATE computer IS Computer // Instance of the object to be built PUBLIC PROCEDURE Builder(serial IS string) computer IS Computer computer..serialNumber = serial // Mandatory attribute END
PROCEDURE withProcessor(processor IS string) IS Builder computer..processor = processor RESULT THIS END
PROCEDURE withRam(ram IS int) IS Builder computer..ram = ram RESULT THIS END
PROCEDURE withStorage(storage IS string) IS Builder computer..storage = storage RESULT THIS END
PROCEDURE build() IS Computer RESULT computer END END
// Example usage PROCEDURE Main() myComputer IS Computer myComputer = Computer::Builder("SN789")::withProcessor("Intel i7")::withRam(16)::withStorage("1TB SSD")::build() Info(myComputer..toString()) END Output in WinDev: Computer [serial=SN789, processor=Intel i7, ram=16, storage=1TB SSD] Explanation of the Code in English • Class Computer: Represents the final product with attributes like serialNumber (mandatory), processor, ram, and storage. • Class Builder: An inner class that manages the construction of the Computer object. The Builder procedure initializes the object with the serial number. • Configuration Methods: withProcessor, withRam, and withStorage set optional attributes and return THIS for method chaining. • Method build: Returns the configured Computer object. • Usage in Main: Shows how to create a Computer object fluently, configuring only the desired attributes. • Context in WinDev: This example is relevant for inventory or hardware management systems in WinDev, where computers may have varying configurations.
Observações • WLangage no WinDev: Os exemplos usam a sintaxe do WLangage, com IS, PROCEDURE, e THIS, que são padrão no WinDev. A função Info exibe a saída no ambiente WinDev. • Builder Interno: Conforme sugerido por Issam Ouzali, o Builder é implementado como uma classe interna, simplificando a criação de objetos complexos sem construtores extensos. • Contexto do Post: Os exemplos refletem o uso do Builder para melhorar a legibilidade e manutenibilidade, como destacado no post, sendo aplicáveis a sistemas complexos no WinDev, como gerenciamento de pedidos ou inventário. • Flexibilidade: Os atributos opcionais podem ser omitidos, demonstrando a flexibilidade do padrão Builder. Se precisar de mais exemplos, ajustes no código (por exemplo, integração com formulários ou relatórios no WinDev), ou explicações adicionais, é só informar!
-- Adriano José Boller ______________________________________________ Consultor e Representante Oficial da PcSoft no Brasil +55 (41) 99949 1800 adrianoboller@gmail.com skype: adrianoboller http://wxinformatica.com.br/ |
| |
| |
| | | |
|
| | |
| |
Membro registado 4.618 mensagems |
|
| Publicado em julho, 25 2025 - 6:13 AM |
Vamos criar uma classe Evento para representar um evento em um sistema de gestão de eventos. O evento terá atributos como ID do evento (obrigatório), nome, data e local. O Builder será usado para configurar o objeto de forma fluida, ideal para sistemas de agendamento no WinDev. // Classe Evento (Produto) CLASS Evento PUBLIC idEvento IS string nome IS string data IS date local IS string END
// Procedimento para exibir o objeto PROCEDURE Evento::toString() IS string RESULT "Evento [id=" + idEvento + ", nome=" + nome + ", data=" + DateToString(data, "DD/MM/YYYY") + ", local=" + local + "]"
// Classe Builder interna CLASS Evento::Builder PRIVATE evento IS Evento // Instância do objeto a ser construído PUBLIC PROCEDURE Builder(id IS string) evento IS Evento evento..idEvento = id // Atributo obrigatório END
PROCEDURE comNome(nome IS string) IS Builder evento..nome = nome RESULT THIS END
PROCEDURE comData(data IS date) IS Builder evento..data = data RESULT THIS END
PROCEDURE comLocal(local IS string) IS Builder evento..local = local RESULT THIS END
PROCEDURE build() IS Evento RESULT evento END END
// Exemplo de uso PROCEDURE Main() meuEvento IS Evento meuEvento = Evento::Builder("EVT001")::comNome("Conferência Tech")::comData("20251015")::comLocal("Centro de Convenções")::build() Info(meuEvento..toString()) END Saída no WinDev: Evento [id=EVT001, nome=Conferência Tech, data=15/10/2025, local=Centro de Convenções] Explicação do Código em Português • Classe Evento: Representa o produto final com atributos como idEvento (obrigatório), nome, data e local. • Classe Builder: Uma classe interna que gerencia a construção do objeto Evento. O procedimento Builder inicializa o objeto com o ID do evento. • Métodos de Configuração: comNome, comData e comLocal configuram os atributos opcionais e retornam THIS para encadeamento. • Método build: Retorna o objeto Evento configurado. • Uso no Main: Demonstra a criação fluida de um evento, configurando apenas os atributos desejados. • Contexto no WinDev: Este exemplo é útil em sistemas de gestão de eventos ou agendas no WinDev, onde eventos podem ter várias configurações (por exemplo, em formulários de cadastro).
Exemplo em Inglês (WLangage) Context We will create a Book class to represent a book in a library management system. The book has attributes like ISBN (mandatory), title, author, and publication year. The Builder pattern will allow flexible configuration. // Class Book (Product) CLASS Book PUBLIC isbn IS string title IS string author IS string pubYear IS int END
// Procedure to display the object PROCEDURE Book::toString() IS string RESULT "Book [isbn=" + isbn + ", title=" + title + ", author=" + author + ", pubYear=" + pubYear + "]"
// Inner Builder class CLASS Book::Builder PRIVATE book IS Book // Instance of the object to be built PUBLIC PROCEDURE Builder(isbn IS string) book IS Book book..isbn = isbn // Mandatory attribute END
PROCEDURE withTitle(title IS string) IS Builder book..title = title RESULT THIS END
PROCEDURE withAuthor(author IS string) IS Builder book..author = author RESULT THIS END
PROCEDURE withPubYear(year IS int) IS Builder book..pubYear = year RESULT THIS END
PROCEDURE build() IS Book RESULT book END END
// Example usage PROCEDURE Main() myBook IS Book myBook = Book::Builder("978-3-16-148410-0")::withTitle("The Future of AI")::withAuthor("Jane Doe")::withPubYear(2025)::build() Info(myBook..toString()) END Output in WinDev: Book [isbn=978-3-16-148410-0, title=The Future of AI, author=Jane Doe, pubYear=2025] Explanation of the Code in English • Class Book: Represents the final product with attributes like isbn (mandatory), title, author, and pubYear. • Class Builder: An inner class that manages the construction of the Book object. The Builder procedure initializes the object with the ISBN. • Configuration Methods: withTitle, withAuthor, and withPubYear set optional attributes and return THIS for method chaining. • Method build: Returns the configured Book object. • Usage in Main: Shows how to create a Book object fluently, configuring only the desired attributes. • Context in WinDev: This example is relevant for library or bookstore management systems in WinDev, where books may have varying attributes.
Observações • WLangage no WinDev: Os exemplos usam a sintaxe do WLangage, com IS, PROCEDURE, e THIS, compatíveis com o ambiente WinDev. A função Info exibe a saída. • Builder Interno: Alinhado com o post de Issam Ouzali, o Builder é implementado como uma classe interna, simplificando a criação de objetos complexos. • Contexto do Post: Os exemplos reforçam a ideia de legibilidade e manutenibilidade, sendo aplicáveis a sistemas WinDev como gestão de eventos ou bibliotecas. • Flexibilidade: O Builder permite omitir atributos opcionais, facilitando a criação de objetos com configurações variadas.
-- Adriano José Boller ______________________________________________ Consultor e Representante Oficial da PcSoft no Brasil +55 (41) 99949 1800 adrianoboller@gmail.com skype: adrianoboller http://wxinformatica.com.br/Mensagem modificada, julho, 25 2025 - 6:20 AM |
| |
| |
| | | |
|
| | |
| |
Membro registado 4.618 mensagems |
|
| Publicado em julho, 25 2025 - 6:14 AM |
Vamos criar uma classe Fatura para representar uma fatura eletrônica em um sistema de faturamento, inspirado no comentário de Olivier Dawson no post, que menciona o uso do padrão Builder para implementar faturamento eletrônico. A fatura terá atributos como número da fatura (obrigatório), cliente, valor total e data de emissão. O Builder será interno, como sugerido no post, para simplificar a construção. // Classe Fatura (Produto) // Representa uma fatura eletrônica com atributos configuráveis CLASS Fatura PUBLIC numeroFatura IS string // Número único da fatura (obrigatório) cliente IS string // Nome do cliente valorTotal IS real // Valor total da fatura dataEmissao IS date // Data de emissão da fatura END
// Procedimento para exibir os dados da fatura // Retorna uma string com os detalhes da fatura para exibição PROCEDURE Fatura::toString() IS string RESULT "Fatura [numero=" + numeroFatura + ", cliente=" + cliente + ", valor=" + valorTotal + ", data=" + DateToString(dataEmissao, "DD/MM/YYYY") + "]"
// Classe Builder interna // Gerencia a construção passo a passo do objeto Fatura CLASS Fatura::Builder PRIVATE fatura IS Fatura // Instância da fatura sendo construída PUBLIC // Construtor do Builder // Recebe o número da fatura (obrigatório) e inicializa o objeto PROCEDURE Builder(numero IS string) fatura IS Fatura fatura..numeroFatura = numero END
// Configura o cliente da fatura // Retorna THIS para permitir encadeamento PROCEDURE comCliente(cliente IS string) IS Builder fatura..cliente = cliente RESULT THIS END
// Configura o valor total da fatura // Retorna THIS para permitir encadeamento PROCEDURE comValor(valor IS real) IS Builder fatura..valorTotal = valor RESULT THIS END
// Configura a data de emissão da fatura // Retorna THIS para permitir encadeamento PROCEDURE comDataEmissao(data IS date) IS Builder fatura..dataEmissao = data RESULT THIS END
// Finaliza a construção e retorna o objeto Fatura PROCEDURE build() IS Fatura RESULT fatura END END
// Procedimento principal para demonstrar o uso do Builder PROCEDURE Main() // Cria uma fatura usando o Builder minhaFatura IS Fatura minhaFatura = Fatura::Builder("FAT2025-001")::comCliente("Empresa XYZ")::comValor(2500.99)::comDataEmissao("20250725")::build() // Exibe os detalhes da fatura Info(minhaFatura..toString()) END Saída no WinDev: Fatura [numero=FAT2025-001, cliente=Empresa XYZ, valor=2500.99, data=25/07/2025] Explicação do Código em Português • Classe Fatura: Define o objeto final (produto) com atributos relevantes para uma fatura eletrônica, como numeroFatura (obrigatório), cliente, valorTotal e dataEmissao. • Procedimento toString: Formata os dados da fatura para exibição, usando DateToString para a data no formato brasileiro. • Classe Builder: Uma classe interna que gerencia a construção da fatura. O procedimento Builder inicializa o objeto com o atributo obrigatório numeroFatura. • Métodos de Configuração: comCliente, comValor e comDataEmissao configuram os atributos opcionais e retornam THIS para encadeamento fluido, conforme sugerido no post para melhorar a legibilidade. • Método build: Retorna o objeto Fatura configurado. • Procedimento Main: Demonstra a criação fluida de uma fatura, configurando apenas os atributos desejados. • Contexto no WinDev: Este exemplo é diretamente inspirado no comentário de Olivier Dawson sobre faturamento eletrônico, sendo útil em sistemas de gestão financeira ou ERP no WinDev, onde faturas têm configurações variadas (por exemplo, integração com HFSQL ou relatórios).
Exemplo em Inglês (WLangage) Context We will create a Product class to represent a product in an inventory management system. The product has attributes like product code (mandatory), name, price, and category. The Builder pattern will be implemented as an inner class, as suggested in the original post, to ensure clear and maintainable object creation. // Class Product (Product) // Represents a product in an inventory system with configurable attributes CLASS Product PUBLIC productCode IS string // Unique product code (mandatory) name IS string // Product name price IS real // Product price category IS string // Product category END
// Procedure to display the product details // Returns a string with the product information for display PROCEDURE Product::toString() IS string RESULT "Product [code=" + productCode + ", name=" + name + ", price=" + price + ", category=" + category + "]"
// Inner Builder class // Manages the step-by-step construction of the Product object CLASS Product::Builder PRIVATE product IS Product // Instance of the product being built PUBLIC // Builder constructor // Takes the product code (mandatory) and initializes the object PROCEDURE Builder(code IS string) product IS Product product..productCode = code END
// Sets the product name // Returns THIS to enable method chaining PROCEDURE withName(name IS string) IS Builder product..name = name RESULT THIS END
// Sets the product price // Returns THIS to enable method chaining PROCEDURE withPrice(price IS real) IS Builder product..price = price RESULT THIS END
// Sets the product category // Returns THIS to enable method chaining PROCEDURE withCategory(category IS string) IS Builder product..category = category RESULT THIS END
// Completes the construction and returns the Product object PROCEDURE build() IS Product RESULT product END END
// Main procedure to demonstrate the Builder usage PROCEDURE Main() // Creates a product using the Builder myProduct IS Product myProduct = Product::Builder("PROD123")::withName("Laptop")::withPrice(999.99)::withCategory("Electronics")::build() // Displays the product details Info(myProduct..toString()) END Output in WinDev: Product [code=PROD123, name=Laptop, price=999.99, category=Electronics] Explanation of the Code in English • Class Product: Defines the final product with attributes like productCode (mandatory), name, price, and category. • Procedure toString: Formats the product details for display, suitable for WinDev’s Info function. • Class Builder: An inner class that manages the construction of the Product object. The Builder procedure initializes the object with the mandatory productCode. • Configuration Methods: withName, withPrice, and withCategory set optional attributes and return THIS for fluent method chaining, aligning with the post’s emphasis on readability. • Method build: Returns the configured Product object. • Procedure Main: Demonstrates fluent creation of a product, configuring only the desired attributes. • Context in WinDev: This example is suitable for inventory or e-commerce systems in WinDev, where products have varying attributes and may be integrated with HFSQL databases or UI forms.
Observações • WLangage no WinDev: Os exemplos usam a sintaxe nativa do WLangage (IS, PROCEDURE, THIS) e a função Info para exibir a saída, compatível com o ambiente WinDev. • Builder Interno: Conforme sugerido no post de Issam Ouzali, o Builder é implementado como uma classe interna, simplificando a construção de objetos complexos e evitando construtores extensos. • Contexto do Post: O exemplo em português reflete diretamente o comentário de Olivier Dawson sobre faturamento eletrônico, enquanto o exemplo em inglês é aplicável a sistemas de inventário, ambos alinhados com a ideia de melhorar legibilidade e manutenibilidade. • Flexibilidade: O padrão Builder permite omitir atributos opcionais, facilitando a criação de objetos com diferentes configurações. • Integração com WinDev: Esses exemplos podem ser facilmente adaptados para integrar com bancos HFSQL, formulários ou relatórios no WinDev, como seria comum em aplicações práticas mencionadas no post. Se precisar de mais exemplos, ajustes específicos (como integração com HFSQL, formulários, ou relatórios), ou quiser que eu foque em outro aspecto do post, por favor, detalhe!
-- Adriano José Boller ______________________________________________ Consultor e Representante Oficial da PcSoft no Brasil +55 (41) 99949 1800 adrianoboller@gmail.com skype: adrianoboller http://wxinformatica.com.br/Mensagem modificada, julho, 25 2025 - 6:19 AM |
| |
| |
| | | |
|
| | |
| |
Membro registado 4.618 mensagems |
|
| Publicado em julho, 25 2025 - 6:15 AM |
Esses exemplos serão mais detalhados, incluindo integração com o ambiente WinDev (como uso de HFSQL para persistência de dados e formulários), refletindo cenários práticos mencionados no post, como faturamento eletrônico (citado por Olivier Dawson) e a ênfase em legibilidade e manutenibilidade. Também conectarei os exemplos diretamente ao post, explicando como eles se alinham com os benefícios destacados (evitar construtores longos, clarificar lógica, etc.).
Explicação Aprofundada do Padrão Builder no Contexto do Post O post de Issam Ouzali destaca o padrão Builder como uma solução para construir objetos complexos de forma clara e manutenível, especialmente em WinDev com WLangage. Ele menciona que o Builder é útil quando: • A criação de um objeto envolve várias etapas que variam por classe, mas seguem uma ordem fixa. • Um construtor se torna longo e difícil de ler (problema do “construtor telescópico”). • É necessário criar objetos com configurações diferentes. Benefícios no Contexto do WinDev (conforme o post): • Evitar construtores longos: Em WinDev, objetos como registros em bancos HFSQL ou dados de formulários podem ter muitos campos opcionais. O Builder simplifica a inicialização. • Clarificar a lógica de construção: Separa a lógica de criação do objeto, facilitando a manutenção em projetos complexos, como sistemas ERP ou de faturamento. • Facilitar configurações diferentes: Permite criar objetos com variações (ex.: faturas com ou sem descontos). • Melhorar legibilidade e manutenibilidade: O código em WLangage fica mais fluido e fácil de entender, especialmente em formulários ou relatórios. Integração com WinDev: • HFSQL: O Builder pode ser usado para criar objetos que serão persistidos em um banco HFSQL, garantindo que apenas os campos necessários sejam configurados. • Formulários: O padrão é ideal para coletar dados de formulários no WinDev, onde o usuário pode preencher campos opcionais de forma dinâmica. • Relatórios: Objetos criados com Builder podem ser usados diretamente em relatórios, com atributos formatados adequadamente. Contexto do Post: O comentário de Olivier Dawson sobre faturamento eletrônico sugere um caso prático onde o Builder pode ser aplicado para configurar faturas com campos opcionais (ex.: impostos, descontos). Além disso, Issam menciona um “Builder interno estático” (adaptado aqui como uma classe interna, já que WLangage não usa static explicitamente).
Exemplo em Português (WLangage com Integração HFSQL) Contexto Vamos criar uma classe FaturaEletronica para um sistema de faturamento, inspirada no comentário de Olivier Dawson. A fatura terá atributos como número da fatura (obrigatório), cliente, valor base, desconto e data de emissão. O Builder será usado para configurar a fatura, que será persistida em um banco HFSQL. O exemplo inclui integração com um formulário WinDev e comentários detalhados. // Definição do arquivo HFSQL para armazenar faturas // Arquivo: FaturasEletronicas // Campos: NumeroFatura (string), Cliente (string), ValorBase (real), Desconto (real), DataEmissao (date) HDeclare("FaturasEletronicas")
// Classe FaturaEletronica (Produto) // Representa uma fatura eletrônica com atributos configuráveis CLASS FaturaEletronica PUBLIC numeroFatura IS string // Número único da fatura (obrigatório) cliente IS string // Nome do cliente valorBase IS real // Valor base da fatura desconto IS real // Desconto aplicado (opcional) dataEmissao IS date // Data de emissão da fatura END
// Procedimento para exibir os dados da fatura // Formata os dados para exibição em formulários ou relatórios PROCEDURE FaturaEletronica::toString() IS string RESULT "Fatura [numero=" + numeroFatura + ", cliente=" + cliente + ", valorBase=" + valorBase + ", desconto=" + desconto + ", data=" + DateToString(dataEmissao, "DD/MM/YYYY") + "]"
// Procedimento para salvar a fatura no banco HFSQL // Persiste os dados no arquivo FaturasEletronicas PROCEDURE FaturaEletronica::salvarHFSQL() HReset("FaturasEletronicas") FaturasEletronicas.NumeroFatura = numeroFatura FaturasEletronicas.Cliente = cliente FaturasEletronicas.ValorBase = valorBase FaturasEletronicas.Desconto = desconto FaturasEletronicas.DataEmissao = dataEmissao HAdd("FaturasEletronicas") IF HError() THEN Error("Erro ao salvar fatura: " + HErrorInfo()) ELSE Info("Fatura salva com sucesso!") END END
// Classe Builder interna // Gerencia a construção passo a passo da fatura CLASS FaturaEletronica::Builder PRIVATE fatura IS FaturaEletronica // Instância da fatura sendo construída PUBLIC // Construtor do Builder // Inicializa a fatura com o número (obrigatório) PROCEDURE Builder(numero IS string) fatura IS FaturaEletronica fatura..numeroFatura = numero END
// Configura o cliente da fatura // Retorna THIS para encadeamento fluido PROCEDURE comCliente(cliente IS string) IS Builder fatura..cliente = cliente RESULT THIS END
// Configura o valor base da fatura // Retorna THIS para encadeamento fluido PROCEDURE comValorBase(valor IS real) IS Builder fatura..valorBase = valor RESULT THIS END
// Configura o desconto da fatura (opcional) // Retorna THIS para encadeamento fluido PROCEDURE comDesconto(desconto IS real) IS Builder fatura..desconto = desconto RESULT THIS END
// Configura a data de emissão da fatura // Retorna THIS para encadeamento fluido PROCEDURE comDataEmissao(data IS date) IS Builder fatura..dataEmissao = data RESULT THIS END
// Finaliza a construção e retorna a fatura PROCEDURE build() IS FaturaEletronica RESULT fatura END END
// Procedimento para criar uma fatura a partir de um formulário // Simula um formulário WinDev com campos preenchidos pelo usuário PROCEDURE CriarFaturaFormulario() // Suponha que os dados vêm de campos de um formulário numero IS string = EDT_NumeroFatura // Campo do formulário cliente IS string = EDT_Cliente valor IS real = EDT_ValorBase desconto IS real = EDT_Desconto data IS date = EDT_DataEmissao
// Cria a fatura usando o Builder minhaFatura IS FaturaEletronica minhaFatura = FaturaEletronica::Builder(numero) IF cliente <> "" THEN minhaFatura::comCliente(cliente) IF valor > 0 THEN minhaFatura::comValorBase(valor) IF desconto > 0 THEN minhaFatura::comDesconto(desconto) IF data <> "" THEN minhaFatura::comDataEmissao(data) minhaFatura = minhaFatura::build()
// Salva no banco HFSQL minhaFatura..salvarHFSQL() // Exibe os detalhes no formulário Info(minhaFatura..toString()) END
// Procedimento principal para teste PROCEDURE Main() // Exemplo de criação direta minhaFatura IS FaturaEletronica minhaFatura = FaturaEletronica::Builder("FAT2025-002")::comCliente("Acme Corp")::comValorBase(5000.00)::comDesconto(200.00)::comDataEmissao("20250725")::build() minhaFatura..salvarHFSQL() Info(minhaFatura..toString()) END Saída no WinDev: Fatura salva com sucesso! Fatura [numero=FAT2025-002, cliente=Acme Corp, valorBase=5000, desconto=200, data=25/07/2025] Explicação Detalhada em Português • Classe FaturaEletronica: Representa uma fatura eletrônica, com atributos como numeroFatura (obrigatório), cliente, valorBase, desconto e dataEmissao. • Procedimento toString: Formata os dados para exibição, útil para formulários ou relatórios no WinDev. • Procedimento salvarHFSQL: Persiste a fatura em um arquivo HFSQL, simulando integração com o banco de dados do WinDev. • Classe Builder: Uma classe interna que inicializa a fatura com numeroFatura e permite configurar os outros atributos de forma fluida, conforme sugerido no post de Issam Ouzali. • Procedimento CriarFaturaFormulario: Simula a criação de uma fatura a partir de um formulário WinDev, verificando campos opcionais antes de configurá-los, demonstrando a flexibilidade do Builder. • Procedimento Main: Mostra a criação direta de uma fatura, com salvamento no HFSQL e exibição dos detalhes. • Conexão com o Post: O exemplo reflete o caso de uso de faturamento eletrônico (mencionado por Olivier Dawson), evita construtores longos (problema destacado por Issam) e melhora a legibilidade com métodos encadeados. • Integração com WinDev: A persistência no HFSQL e o uso em formulários mostram como o Builder se integra a aplicações reais no WinDev, como sistemas de faturamento ou ERP.
Exemplo em Inglês (WLangage with Form Integration) Context We will create a Reservation class for a restaurant reservation system. The reservation has attributes like reservation ID (mandatory), customer name, date, and number of guests. The Builder will be an inner class, and the object will be used in a WinDev form, aligning with the post’s focus on clean code and maintainability. // Class Reservation (Product) // Represents a restaurant reservation with configurable attributes CLASS Reservation PUBLIC reservationID IS string // Unique reservation ID (mandatory) customerName IS string // Name of the customer reservationDate IS date // Date of the reservation guests IS int // Number of guests END
// Procedure to display the reservation details // Formats the data for display in forms or reports PROCEDURE Reservation::toString() IS string RESULT "Reservation [ID=" + reservationID + ", customer=" + customerName + ", date=" + DateToString(reservationDate, "MM/DD/YYYY") + ", guests=" + guests + "]"
// Inner Builder class // Manages the step-by-step construction of the Reservation object CLASS Reservation::Builder PRIVATE reservation IS Reservation // Instance of the reservation being built PUBLIC // Builder constructor // Initializes the reservation with the ID (mandatory) PROCEDURE Builder(id IS string) reservation IS Reservation reservation..reservationID = id END
// Sets the customer name // Returns THIS for method chaining PROCEDURE withCustomerName(name IS string) IS Builder reservation..customerName = name RESULT THIS END
// Sets the reservation date // Returns THIS for method chaining PROCEDURE withDate(date IS date) IS Builder reservation..reservationDate = date RESULT THIS END
// Sets the number of guests // Returns THIS for method chaining PROCEDURE withGuests(guests IS int) IS Builder reservation..guests = guests RESULT THIS END
// Completes the construction and returns the Reservation object PROCEDURE build() IS Reservation RESULT reservation END END
// Procedure to create a reservation from a WinDev form // Simulates a form where users input reservation details PROCEDURE CreateReservationFromForm() // Assume data comes from form fields id IS string = EDT_ReservationID // Form field customer IS string = EDT_CustomerName date IS date = EDT_ReservationDate guests IS int = EDT_Guests
// Create the reservation using the Builder myReservation IS Reservation myReservation = Reservation::Builder(id) IF customer <> "" THEN myReservation::withCustomerName(customer) IF date <> "" THEN myReservation::withDate(date) IF guests > 0 THEN myReservation::withGuests(guests) myReservation = myReservation::build()
// Display the reservation details Info(myReservation..toString()) END
// Main procedure for testing PROCEDURE Main() // Example of direct reservation creation myReservation IS Reservation myReservation = Reservation::Builder("RES2025-001")::withCustomerName("John Doe")::withDate("20250725")::withGuests(4)::build() Info(myReservation..toString()) END Output in WinDev: Reservation [ID=RES2025-001, customer=John Doe, date=07/25/2025, guests=4] Detailed Explanation in English • Class Reservation: Represents a restaurant reservation with attributes like reservationID (mandatory), customerName, reservationDate, and guests. • Procedure toString: Formats the reservation details for display, using a US date format (MM/DD/YYYY). • Class Builder: An inner class that initializes the reservation with reservationID and allows fluent configuration of optional attributes, aligning with the post’s focus on readability. • Procedure CreateReservationFromForm: Simulates a WinDev form where users input reservation details, checking for optional fields before setting them, demonstrating the Builder’s flexibility. • Procedure Main: Shows direct creation of a reservation with fluent method chaining. • Connection to the Post: The example avoids long constructors, clarifies construction logic, and supports different configurations, as emphasized by Issam Ouzali. It’s suitable for a restaurant management system in WinDev. • WinDev Integration: The form integration shows how the Builder can be used in real WinDev applications, such as reservation systems with UI components.
Conexão com o Post de Issam Ouzali • Faturamento Eletrônico: O exemplo em português atende diretamente ao comentário de Olivier Dawson, aplicando o Builder a um sistema de faturas eletrônicas, com integração ao HFSQL para persistência, refletindo cenários reais de ERP no WinDev. • Builder Interno: Ambos os exemplos usam uma classe interna, como sugerido por Issam para casos mais simples, evitando a necessidade de classes externas e mantendo o código organizado. • Benefícios do Post: Os exemplos demonstram como o Builder: ◦ Evita construtores longos: Sem Builder, a classe FaturaEletronica ou Reservation exigiria múltiplos construtores ou parâmetros opcionais confusos. ◦ Clarifica a lógica: A construção passo a passo é clara e fluida, especialmente em formulários. ◦ Facilita configurações diferentes: Atributos como desconto ou guests podem ser omitidos. ◦ Melhora a legibilidade: O encadeamento de métodos (comCliente, withGuests) torna o código mais intuitivo. • WinDev e WLangage: Os exemplos usam a sintaxe do WLangage (IS, PROCEDURE, THIS) e recursos do WinDev (HFSQL, formulários), mostrando como o Builder se integra a projetos reais.
Possíveis Extensões • Relatórios no WinDev: A classe FaturaEletronica ou Reservation pode ser usada em relatórios WinDev, com o método toString formatando dados para exibição. • Validações: Adicionar validações no Builder (ex.: verificar se valorBase é positivo) para robustez. • Formulários Avançados: Integrar com controles de formulário WinDev (ex.: combos, grids) para preencher dados dinamicamente. • HFSQL Avançado: Adicionar consultas HFSQL para recuperar faturas ou reservas criadas com o Builder. Se precisar de mais detalhes, como implementação de relatórios, validações, ou outro cenário (ex.: integração com WebDev ou WinDev Mobile), ou quiser exemplos adicionais com outros contextos, é só especificar!
-- Adriano José Boller ______________________________________________ Consultor e Representante Oficial da PcSoft no Brasil +55 (41) 99949 1800 adrianoboller@gmail.com skype: adrianoboller http://wxinformatica.com.br/Mensagem modificada, julho, 25 2025 - 6:17 AM |
| |
| |
| | | |
|
| | | | |
| | |
|