{"id":3100,"date":"2021-02-11T15:50:34","date_gmt":"2021-02-11T18:50:34","guid":{"rendered":"http:\/\/www.55bet-pro.com\/pet\/sistemas-de-informacao\/?p=3100"},"modified":"2025-09-02T14:15:32","modified_gmt":"2025-09-02T17:15:32","slug":"principios-da-programacao-orientada-a-objetos","status":"publish","type":"post","link":"http:\/\/www.55bet-pro.com\/pet\/sistemas-de-informacao\/2021\/02\/11\/principios-da-programacao-orientada-a-objetos","title":{"rendered":"SOLID"},"content":{"rendered":"\n
\n
\n
\n
\n
\n
\n
\n
\n
\n
\n

SOLID \u00e9 um acr\u00f4nimo dos cinco primeiros princ\u00edpios da programa\u00e7\u00e3o orientada a objetos e design de c\u00f3digo identificados por Robert C. Martin<\/a> (ou Uncle Bob) por volta do ano 2000. O acr\u00f4nimo SOLID foi introduzido por Michael Feathers<\/a>, ap\u00f3s observar que os cinco princ\u00edpios poderiam se encaixar nesta palavra, as siglas significam:<\/p>\n

\u00a0<\/div>\n
S – Single Responsibility Principle <\/strong>(Princ\u00edpio da Responsabilidade \u00danica)<\/strong><\/div>\n

Este princ\u00edpio nos diz que \u201cuma classe deve ter um, e somente um, motivo para mudar”, por\u00e9m pode ser aplicado a fun\u00e7\u00f5es, componentes, entidades, etc. Esse princ\u00edpio declara que uma classe deve ser especializada em um \u00fanico assunto e possuir apenas uma responsabilidade dentro do software, ou seja, a classe deve ter uma \u00fanica tarefa ou a\u00e7\u00e3o para executar. Comumente quando estamos programando orientado a objetos, acabam violando este princ\u00edpio e muitas vezes criamos classes que fazem de tudo, chamadas na literatura de \u201cGod Class\u201d, inicialmente tudo deve funcionar bem, por\u00e9m quando for necess\u00e1rio realizar uma altera\u00e7\u00e3o nessa classe, ser\u00e1 dif\u00edcil modificar umas de suas funcionalidades sem comprometer outras partes do sistema.<\/p>\n

Abaixo temos um exemplo de c\u00f3digo que n\u00e3o usa o princ\u00edpio da responsabilidade \u00fanica, quando olhamos inicialmente o c\u00f3digo n\u00e3o encontramos nenhum problema, j\u00e1 que o m\u00e9todo \u201cUsuarioValido\u201d trata algo relacionado ao usu\u00e1rio, o m\u00e9todo \u201ctemCargo\u201d trata do cargo de um usu\u00e1rio, por\u00e9m vamos imaginar que ocorra um problema no m\u00e9todo \u201ctemCargo\u201d, n\u00e3o s\u00f3 os usu\u00e1rios n\u00e3o v\u00e3o conseguir realizar o login no sistema, como todas as funcionalidade relacionada a este m\u00e9todo ir\u00e3o parar de funcionar, e o mesmo ocorre com o m\u00e9todo \u201cusuarioValido\u201d. Para este c\u00f3digo pode-se dizer que a classe usu\u00e1rio tem pelo menos tr\u00eas motivos para mudar seus atributos getters e setters, o m\u00e9todo \u201cusuarioValido\u201d e o m\u00e9todo \u201ctemCargo\u201d, ferindo o princ\u00edpio da responsabilidade \u00fanica, deixando a classe menos coesa e com um n\u00edvel alto de acoplamento.<\/p>\n<\/div>\n<\/div>\n<\/div>\n<\/div>\n<\/div>\n<\/div>\n<\/div>\n<\/div>\n<\/div>\n<\/section>\n

\n
\u00a0<\/div>\n
\n
\n
\n
\n
\u00a0<\/div>\n<\/div>\n<\/div>\n
\n
\n
\n
\n
\n
\n
\n
\"\"<\/div>\n<\/div>\n<\/div>\n<\/div>\n<\/div>\n<\/div>\n<\/div>\n<\/div>\n
\n
\n
\u00a0<\/div>\n<\/div>\n<\/div>\n<\/div>\n<\/div>\n<\/section>\n
\n
\u00a0<\/div>\n
\n
\n
\n
\n
\u00a0<\/div>\n<\/div>\n<\/div>\n
\n
\n
\n
\n
\n
\n
\n
\"\"<\/div>\n<\/div>\n<\/div>\n<\/div>\n<\/div>\n<\/div>\n<\/div>\n<\/div>\n
\n
\n
\u00a0<\/div>\n<\/div>\n<\/div>\n<\/div>\n<\/div>\n<\/section>\n
\n
\u00a0<\/div>\n
\n
\n
\n
\n
\n
\n
\n
\n
\n

Uma poss\u00edvel solu\u00e7\u00e3o para o problema acima \u00e9:<\/p>\n<\/div>\n<\/div>\n<\/div>\n<\/div>\n<\/div>\n<\/div>\n<\/div>\n<\/div>\n<\/div>\n<\/section>\n

\n
\n
\n
\n
\n
\u00a0<\/div>\n<\/div>\n<\/div>\n
\n
\n
\n
\n
\n
\n
\n
\"\"<\/div>\n<\/div>\n<\/div>\n<\/div>\n<\/div>\n<\/div>\n<\/div>\n<\/div>\n
\n
\n
\u00a0<\/div>\n<\/div>\n<\/div>\n<\/div>\n<\/div>\n<\/section>\n
\n
\u00a0<\/div>\n
\n
\n
\n
\n
\u00a0<\/div>\n<\/div>\n<\/div>\n
\n
\n
\n
\n
\n
\n
\n
\"\"<\/div>\n<\/div>\n<\/div>\n<\/div>\n<\/div>\n<\/div>\n<\/div>\n<\/div>\n
\n
\n
\u00a0<\/div>\n<\/div>\n<\/div>\n<\/div>\n<\/div>\n<\/section>\n
\n
\u00a0<\/div>\n
\n
\n
\n
\n
\n
\n
\n
\n
\n

Note que agora cada responsabilidade foi separada em uma classe, pois se um problema ocorre em algumas destas partes, o problema n\u00e3o ir\u00e1 se espalhar pelo sistema, deste modo facilitando os testes, descobrimento de novos bugs e deixando a aplica\u00e7\u00e3o mais coesa e menos acoplada.<\/p>\n

\n
\n
\n
\u00a0<\/div>\n<\/div>\n<\/div>\nO – Open Close Principle (Princ\u00edpio Aberto Fechado)<\/strong><\/div>\n

Este princ\u00edpio nos diz que \u201cObjetos ou entidades devem estar abertos para extens\u00e3o, mas fechados para modifica\u00e7\u00e3o\u201d, ou seja, quando novos comportamentos e recursos precisam ser adicionados no software, devemos estender e n\u00e3o alterar o c\u00f3digo fonte original. Abaixo temos um exemplo de classes que representam contratos de funcion\u00e1rios.<\/p>\n<\/div>\n<\/div>\n<\/div>\n<\/div>\n<\/div>\n<\/div>\n<\/div>\n<\/div>\n<\/div>\n<\/section>\n

\n
\u00a0<\/div>\n
\n
\n
\n
\n
\n
\n
\n
\n
\n
\"\"<\/div>\n<\/div>\n<\/div>\n<\/div>\n<\/div>\n<\/div>\n<\/div>\n<\/div>\n
\n
\n
\u00a0<\/div>\n<\/div>\n<\/div>\n<\/div>\n<\/div>\n<\/section>\n
\n
\n
\n
\n
\n
\n
\n
\n
\n
\n

A classe \u201cFolhaDePagamento\u201d precisa verificar o funcion\u00e1rio para aplicar a regra de neg\u00f3cio correta na hora do pagamento. Supondo que a empresa cresceu e resolveu trabalhar com funcion\u00e1rios PJ, obviamente seria necess\u00e1rio modificar essa classe e consequentemente o princ\u00edpio Open-Closed do SOLID seria quebrado. A modifica\u00e7\u00e3o mais comum seria adicionar um IF <\/strong>e verificar o novo tipo de funcion\u00e1rio PJ, aplicando as regras para essa nova funcionalidade, mas \u00e9 exatamente este o problema, ao alterar uma classe j\u00e1 existente para adicionar um novo comportamento, corremos um s\u00e9rio risco de introduzir bugs em algo que j\u00e1 estava funcionando. Abaixo temos uma poss\u00edvel solu\u00e7\u00e3o para este problema.<\/p>\n<\/div>\n<\/div>\n<\/div>\n<\/div>\n<\/div>\n<\/div>\n<\/div>\n<\/div>\n<\/div>\n<\/section>\n

\n
\n
\n
\n
\n
\u00a0<\/div>\n<\/div>\n<\/div>\n
\n
\n
\n
\n
\n
\n
\n
\"\"<\/div>\n<\/div>\n<\/div>\n<\/div>\n<\/div>\n<\/div>\n<\/div>\n<\/div>\n
\n
\n
\u00a0<\/div>\n<\/div>\n<\/div>\n<\/div>\n<\/div>\n<\/section>\n
\n
\n
\n
\n
\n
\n
\n
\n
\n
\n

Agora a classe \u201cFolhaDePagamento\u201d n\u00e3o precisa mais saber quais m\u00e9todos chamar para calcular. Ela ser\u00e1 capaz de calcular o pagamento corretamente de qualquer novo tipo de funcion\u00e1rio que seja criado no futuro,desde que ele implemente a interface “Remuneravel\u201d , sem qualquer necessidade de altera\u00e7\u00e3o do seu c\u00f3digo fonte. Este princ\u00edpio \u00e9 base para um dos design patterns mais conhecidos, o Strategy.<\/p>\n

\n
\n
\n
\u00a0<\/div>\n<\/div>\n<\/div>\nL – Liskov Substitution Principle (Princ\u00edpio da substitui\u00e7\u00e3o de Liskov)<\/strong><\/div>\n

Este princ\u00edpio nos diz que \u201cUma classe derivada deve ser substitu\u00edvel por sua classe base\u201d, ou de maneira mais simples, se um objeto B \u00e9 um subtipo de um outro objeto A, este objeto A pode substituir B em qualquer lugar no c\u00f3digo, sem que este c\u00f3digo pare de funcionar, veja o exemplo abaixo:<\/p>\n<\/div>\n<\/div>\n<\/div>\n<\/div>\n<\/div>\n<\/div>\n<\/div>\n<\/div>\n<\/div>\n<\/section>\n

\n
\n
\n
\n
\n
\u00a0<\/div>\n<\/div>\n<\/div>\n
\n
\n
\n
\n
\n
\n
\n
\"\"<\/div>\n<\/div>\n<\/div>\n<\/div>\n<\/div>\n<\/div>\n<\/div>\n<\/div>\n
\n
\n
\u00a0<\/div>\n<\/div>\n<\/div>\n<\/div>\n<\/div>\n<\/section>\n
\n
\n
\n
\n
\n
\n
\n
\n
\n
\n

Estamos passando como par\u00e2metro tanto a classe pai como a classe derivada e (entretanto) o c\u00f3digo continua funcionando da forma esperada. Alguns exemplos de viola\u00e7\u00e3o do princ\u00edpio de Liskov s\u00e3o: sobrescrever\/implementar um m\u00e9todo que n\u00e3o faz nada, lan\u00e7ar uma exce\u00e7\u00e3o inesperada ou retornar valores de tipos diferentes da classe base. Para n\u00e3o violar o Liskov Substitution Principle, al\u00e9m de estruturar muito bem as suas abstra\u00e7\u00f5es, em alguns casos, voc\u00ea precisar\u00e1 usar a inje\u00e7\u00e3o de depend\u00eancia e tamb\u00e9m usar outros princ\u00edpios do SOLID, como por exemplo, o Princ\u00edpio Aberto Fechado e o Princ\u00edpio da Segrega\u00e7\u00e3o da Interface, ser\u00e1 abordado no pr\u00f3ximo t\u00f3pico.<\/p>\n

Seguir o LSP nos permite usar o polimorfismo com mais confian\u00e7a. Podemos chamar nossas classes derivadas referindo-se \u00e0 sua classe base sem preocupa\u00e7\u00f5es com resultados inesperados.<\/p>\n

\n
\n
\n
\u00a0<\/div>\n<\/div>\n<\/div>\nI – Interface Segregation Principle (Princ\u00edpio da Segrega\u00e7\u00e3o da Interface)<\/strong><\/div>\n

O princ\u00edpio da segrega\u00e7\u00e3o da interface nos diz que \u201cuma classe n\u00e3o deve ser for\u00e7ada a implementar interfaces e m\u00e9todos que n\u00e3o ir\u00e1 utilizar\u201d. Esse princ\u00edpio basicamente diz que \u00e9 melhor criar interfaces mais espec\u00edficas ao inv\u00e9s de termos uma \u00fanica interface gen\u00e9rica. O exemplo abaixo mostra como algumas aves s\u00e3o tratadas dentro de um jogo.<\/p>\n<\/div>\n<\/div>\n<\/div>\n<\/div>\n<\/div>\n<\/div>\n<\/div>\n<\/div>\n<\/div>\n<\/section>\n

\n
\n
\n
\n
\n
\u00a0<\/div>\n<\/div>\n<\/div>\n
\n
\n
\n
\n
\n
\n
\n
\"\"<\/div>\n<\/div>\n<\/div>\n<\/div>\n<\/div>\n<\/div>\n<\/div>\n<\/div>\n
\n
\n
\u00a0<\/div>\n<\/div>\n<\/div>\n<\/div>\n<\/div>\n<\/section>\n
\n
\n
\n
\n
\n
\n
\n
\n
\n
\n

Percebam que ao criar a interface Aves, atribu\u00edmos comportamentos gen\u00e9ricos e isso acabou for\u00e7ando a classe Pinguim implementar o m\u00e9todo \u201csetAltitude\u201d, do qual ela n\u00e3o deveria ter, j\u00e1 que pinguins n\u00e3o voam. A solu\u00e7\u00e3o recomendada ent\u00e3o \u00e9 criar uma interface mais espec\u00edfica.<\/p>\n<\/div>\n<\/div>\n<\/div>\n<\/div>\n<\/div>\n<\/div>\n<\/div>\n<\/div>\n<\/div>\n<\/section>\n

\n
\n
\n
\n
\n
\u00a0<\/div>\n<\/div>\n<\/div>\n
\n
\n
\n
\n
\n
\n
\n
\"\"<\/div>\n<\/div>\n<\/div>\n<\/div>\n<\/div>\n<\/div>\n<\/div>\n<\/div>\n
\n
\n
\u00a0<\/div>\n<\/div>\n<\/div>\n<\/div>\n<\/div>\n<\/section>\n
\n
\n
\n
\n
\n
\n
\n
\n
\n
\n

No exemplo acima, retiramos o m\u00e9todo \u201csetAltitude\u201d da interface Aves e adicionamos em uma interface derivada \u201cAvesQueVoam\u201d.<\/em> Isso nos permitiu isolar os comportamentos das aves de maneira correta dentro do jogo.<\/p>\n

\n
\n
\n
\u00a0<\/div>\n<\/div>\n<\/div>\nD – Dependency Inversion Principle (Princ\u00edpio da Invers\u00e3o de depend\u00eancia)<\/strong><\/div>\n

Antes de tudo, vale lembrar que o termo invers\u00e3o de depend\u00eancia n\u00e3o deve ser confundido com o padr\u00e3o de projeto inje\u00e7\u00e3o de depend\u00eancia.<\/p>\n

O princ\u00edpio da invers\u00e3o de depend\u00eancia nos diz que devemos \u201cDepender de abstra\u00e7\u00f5es e n\u00e3o de implementa\u00e7\u00f5es\u201c, Uncle Bob ainda fala que \u201cm\u00f3dulos de alto n\u00edvel n\u00e3o devem depender de m\u00f3dulos de baixo n\u00edvel. Ambos devem depender da abstra\u00e7\u00e3o e abstra\u00e7\u00f5es n\u00e3o devem depender de detalhes, detalhes devem depender de abstra\u00e7\u00f5es\u201d. O exemplo abaixo demonstra o princ\u00edpio da invers\u00e3o de depend\u00eancia sendo quebrado.<\/p>\n<\/div>\n<\/div>\n<\/div>\n<\/div>\n<\/div>\n<\/div>\n<\/div>\n<\/div>\n<\/div>\n<\/section>\n

\n
\n
\n
\n
\n
\u00a0<\/div>\n<\/div>\n<\/div>\n
\n
\n
\n
\n
\n
\n
\n
\"\"<\/div>\n<\/div>\n<\/div>\n<\/div>\n<\/div>\n<\/div>\n<\/div>\n<\/div>\n
\n
\n
\u00a0<\/div>\n<\/div>\n<\/div>\n<\/div>\n<\/div>\n<\/section>\n
\n
\n
\n
\n
\n
\n
\n
\n
\n
\n

No exemplo acima, podemos perceber que al\u00e9m de quebrar outros princ\u00edpios do SOLID, a classe concreta Interruptor depende de uma outra classe concreta (Ventilador). O interruptor deveria ser capaz de acionar qualquer dispositivo independente de ser um ventilador, uma l\u00e2mpada ou at\u00e9 mesmo um carro. Uma poss\u00edvel solu\u00e7\u00e3o para este problema seria:<\/p>\n<\/div>\n<\/div>\n<\/div>\n<\/div>\n<\/div>\n<\/div>\n<\/div>\n<\/div>\n<\/div>\n<\/section>\n

\n
\n
\n
\n
\n
\u00a0<\/div>\n<\/div>\n<\/div>\n
\n
\n
\n
\n
\n
\n
\n
\"\"<\/div>\n<\/div>\n<\/div>\n<\/div>\n<\/div>\n<\/div>\n<\/div>\n<\/div>\n
\n
\n
\u00a0<\/div>\n<\/div>\n<\/div>\n<\/div>\n<\/div>\n<\/section>\n
\n
\n
\n
\n
\n
\n
\n
\n
\n
\n

Percebam que agora a classe concreta Interruptor depende da abstra\u00e7\u00e3o de um \u201cIDispositivo\u201d e n\u00e3o mais de uma classe concreta.<\/p>\n

\n
\n
\n
\u00a0<\/div>\n<\/div>\n<\/div>\nProblemas comuns que o SOLID pode evitar:<\/strong><\/div>\n