C# 
- O padrão Humble Object
    
    ![]()  | 
    Hoje vou apresentar o padrão Humble Object. (Humble Object Pattern) | 
O Humble Object Pattern é um padrão de design de software que visa facilitar a testabilidade de componentes complexos. Ele ajuda a isolar a lógica de negócios de um componente dos detalhes de implementação que podem ser difíceis de testar, como dependências externas, serviços de infraestrutura ou APIs externas.
O padrão Humble Object envolve a criação de uma interface humilde (humble interface) que define a funcionalidade principal do componente. Essa interface define os métodos e propriedades que representam as principais operações do componente.
Em seguida, o componente é dividido em duas partes:
A ideia por trás do Humble Object Pattern é que a parte humilde do componente é mais fácil de testar, pois não possui dependências externas complexas. Os testes de unidade podem ser escritos facilmente para a parte humilde, sem a necessidade de lidar com configurações complexas ou interações com recursos externos.
Assim, quando criamos programas, eles geralmente precisam se 
comunicar com outras partes do computador ou com o mundo externo, como um banco 
de dados ou serviço de Internet. Mas quando queremos testar nossos programas 
para garantir que funcionem corretamente, pode ser difícil conversar com essas 
outras partes.
Para resolver esse problema, podemos usar o Humble Object 
Pattern para separar as partes do nosso programa que precisam se 
comunicar com outras partes do computador ou com o mundo exterior das partes do 
programa que não precisam. As partes do programa que não precisam falar com o 
mundo exterior são muito mais fáceis de testar porque podemos testá-las 
isoladamente sem nos preocuparmos com outras coisas.
No C#, você pode implementar o Humble Object Pattern utilizando 
interfaces para definir a interface humilde e separar a lógica de negócios dos 
detalhes de implementação. A injeção de dependência é frequentemente usada para 
fornecer as dependências externas para o objeto humilde.
A seguir vamos dar um exemplo para ilustrar o uso deste padrão.
Usando o padrão Humble Object
Imagine que você tenha um componente chamado
OrderProcessor responsável por 
processar os pedidos dos clientes. Esse componente precisa interagir com um 
serviço externo de pagamento para autorizar os pagamentos dos pedidos. 
Vamos criar um projeto console no VS 2022 usando o .NET 7.0 e criar 3 classes para definir o modelo de domínio (vamos usar uma abordagem simplificada):
1- Order
| 
		public
		class
		Order { public int OrderId { get; set; } public string CustomerName { get; set; } public List<Product> Products { get; set; } public Payment Payment { get; set; } public Order(int orderId, string customerName, List<Product> products, Payment payment) { OrderId = orderId; CustomerName = customerName; Products = products; Payment = payment; } }  | 
	
2- Product
| 
		public
		class
		Product { public int ProductId { get; set; } public string Name { get; set; } public decimal Price { get; set; } public Product(int productId, string name, decimal price) { ProductId = productId; Name = name; Price = price; } }  | 
	
3- Payment
| 
		public
		class
		Payment { public string PaymentMethod { get; set; } public decimal Amount { get; set; } public Payment(string paymentMethod, decimal amount) { PaymentMethod = paymentMethod; Amount = amount; } }  | 
	
Definindo o serviço externo de pagamento usando a interface IPaymentService:
| 
		public
		interface
		
		IPaymentService { void AuthorizePayment(Payment payment); void CapturePayment(Payment payment); }  | 
	
A implementação seria feita na classe PaymentService que não irei mostrar para simplificar o código.
Vamos aplicar o Humble Object Pattern nesse caso.
1- Definindo a interface humilde (Humble)
| 
		public
		interface
		
		IOrderProcessor { void ProcessOrder(Order order); }  | 
	
2- Implementando o objeto humilde
| 
		public
		class
		
		OrderProcessor : 
		IOrderProcessor { private readonly IPaymentService _paymentService; public OrderProcessor(IPaymentService paymentService) { _paymentService = paymentService; } public void ProcessOrder(Order order) { // Lógica de negócio para processar o pedido // Chama o serviço de pagamento para autorizar o pagamento _paymentService.AuthorizePayment(order.Payment); // Mais lógica de processamento do pedido } }  | 
	
No exemplo acima, o OrderProcessor 
é o objeto humilde que implementa a interface 
IOrderProcessor. Ele possui uma dependência no
IPaymentService, que representa o 
serviço externo de pagamento.
Implementando o suporte do objeto:
| 
		public
		class
		
		PaymentService : 
		IPaymentService { public void AuthorizePayment(Payment payment) { throw new NotImplementedException(); } public void CapturePayment(Payment payment) { throw new NotImplementedException(); } }  | 
	
O PaymentService representa a 
implementação do serviço de pagamento externo. Ele lida com as interações reais 
com o serviço de pagamento.
Usando o Humble Object Pattern:
		
		 | 
	
No código acima, você registra as implementações das interfaces
IOrderProcessor e IPaymentService 
na configuração da injeção de dependência do ASP.NET Core. Dessa forma, sempre 
que um componente precisar do IOrderProcessor 
ou do IPaymentService, o framework fornecerá as instâncias 
corretas.
Ao utilizar o Humble Object Pattern nesse exemplo, você pode testar o
OrderProcessor facilmente, isolando-o 
das interações com o serviço de pagamento externo. Nos testes de unidade, você 
pode fornecer uma implementação simulada ou um mock do 
IPaymentService para verificar o comportamento do 
OrderProcessor sem depender de recursos externos ou interações complexas.
Essa abordagem torna os testes de unidade mais simples, mais rápidos e mais 
confiáveis, pois se concentram apenas na lógica de negócio do
OrderProcessor, sem se preocupar com o 
serviço de pagamento real.
Ao mesmo tempo, a implementação real do 
PaymentService pode ser testada em níveis de teste mais 
abrangentes, como testes de integração ou testes de sistema, garantindo que as 
interações com o serviço de pagamento funcionem corretamente.
Essa separação entre o objeto humilde e o suporte do objeto ajuda a manter um código mais organizado, modular e de fácil manutenção. Além disso, o Humble Object Pattern facilita a implementação de testes automatizados e aumenta a testabilidade do seu código.
E estamos conversados.
![]()
"Jesus dizia, pois, aos judeus que criam nele: Se 
vós permanecerdes na minha palavra, verdadeiramente sereis meus discípulos; E 
conhecereis a verdade, e a verdade vos libertará."
João 8:31-32
Referências: