Executando verificação de segurança...
1

SOLID - O: Princípio de Aberto/Fechado (Open/Closed Principle)

O - Open-Close Principle

É o segundo princípio do S.O.L.I.D.

O que isso significa?

O Principio do aberto e fechado tem com o objetivo de fazer com que módulos, classes, funções e etc... devem estar aberto para extensão e fechado para modificação.

Como assim extensão e modificação?

A parte da extensão seria a utilização de polimorfismo e/ou herança para poder criar uma "ramificação" de uma funcionalidade.

Já a parte de modificação seria a alteração de código fonte.

Como identificar?

Os if's

O principal sintoma é a utilização do if para fazer ramificações de funcionalidade dentro de uma função por exemplo:

class FinancialReport {
  generateReport(reportTypestring): any {
	if(reportType === "web"){
		// Generate report with graphs, numbers and descriptions
	}
    if(reportType === "mobile"){
	    // Generate report with graphs 
    }
    if(reportType === "print"){
		// Generate report to be printed
    }
  }
}

Para cada novo reportType terá que ser criado um novo if
criando mais uma ramificação, neste exemplo não teve problema de compatibilidade, porem se fosse um exemplo em que fosse muito doloroso de simplesmente adicionar um simples if (Video do Felipe Deschamps com um exemplo desse)

Quebra do Single Responsible Principle

Provavelmente você acabou percebendo que se quebrar esse principio "sem querer" você também quebra o SRP devido a classe, função e etc.. estar fazendo mais de uma coisa.

Mas eu não perco mais tempo pensando nessa solução complexa?

Não, pois em casos que esse principio foi bem implementado ele tende a não necessitar de alterações no código, a não ser que tenha um motivo para a alteração (seguindo o principio anterior do [[S - Single Responsability Principle]]).

Seguindo o exemplo, como eu sigo o OCP?

flowchart LR
FinancialReportBase --> MobileFinancialReport
FinancialReportBase --> WebFinancialReport
FinancialReportBase --> PrintableFinancialReport

Primeiramente teriamos que ter uma classe que define um padrão para os Reports a frente:

export abstract FinancialReportBase {
	report();
}

Depois o que seria cada if teriamos uma classe implementando essa ramificação:

  • Para Mobile:
export MobileFinancialReport extends FinancialReportBase {
	async report(): Promise<MobileReport> {
	  // Gera um relatório para mobile
	}
}
  • Para Web:
export WebFinancialReport extends FinancialReportBase {
	async report(): Promise<WebReport> {
	  // Gera um relatório para web
	}
}
  • Para Impressão:
export PrintableFinancialReport extends FinancialReportBase {
	async report(): Promise<PrintableReport> {
	  // Gera um relatório para impressão
	}
}

Conclusão

Este princípio complementa o SRP e auxilia na manutenção ao longo do tempo evitando de uma classe ou função lidar com muitas coisas "semelhantes" porem ainda diferentes.

Fontes

Carregando publicação patrocinada...