segunda-feira, 26 de janeiro de 2015

Programação orientada a objetos, mas afinal o que diabos é isso?

Hoje eu programo orientado a objetos. Pelo menos eu "acho" isso. Conheci muita gente que dizia que programava orientado a objetos mas na verdade programava de maneira procedural, orientado a evento ou RAD.

Não que as outras metodologias sejam ruins, mas é que muitas vezes elas são a ferramenta errada para se resolver  o problema. Além disso muitos programadores misturam as metodologias combinando o pior das duas em vez de o melhor das duas.

Já vi até programadores dizerem que programam orientado a objeto simplesmente porque a linguagem é orientada a objeto, ou pior ainda, porque a IDE tem "objetos" que você arrasta e solta em uma "form" e que você acessa funções (métodos) destes com seu nome e um ".".

Meu amigo, isso é RAD e não POO. Embora RAD tenha o seu valor para prototipação e aplicações rápidas e sujas, não é um bom ambiente de desenvolvimento a longo prazo. É uma programação orientada a evento degenerada. Além disso, por mais que a linguagem e o framework de uma ferramenta RAD seja orientado a objetos, a literatura e a comunidade, geralmente, não é. Eles incentivam uma forma de programação "copia/cola componentes em uma tela" onde o "programador" geralmente não sabe lhufas do que está fazendo, se é que ele programa alguma linha. Esse tipo de programa tem uma manutenibilidade quase zero.

Vide por exemplo o ambiente Delphi. É uma linguagem orientada a objeto com generics, interfaces, reflexão, sobrecarga de operadores e tudo o que uma linguagem orientada a objeto precisa ter. No entanto a comunidade Delphi é geralmente uma comunidade de "arrastadores de componentes" e "desenhistas de formulários". Não é culpa deles, a literatura disponível da ferramenta incentiva isso.

Eu mesmo fui programador Delphi durante anos e ainda é uma linguagem muito querida para mim, mas eu aprendi a fazer as coisas um pouco diferente. A sugestão que eu dou? Aprenda uma outra linguagem, C# ou Java, para expandir os seus horizontes. Se optar por C#, faça as coisas "no braço" em vez de usar as ferramentas RAD. A longo prazo elas decepcionam.

Por três vezes na minha carreira tive de fazer refactorings brutais em aplicações Delphi para possibilitar alguma expansividade em cima de um legado macarrônico, pois a manutenção era um inferno em vida.

Daí, depois de ler inúmeros artigos e livros sobre POO, DDD, padrões de projeto e outras boas práticas de código verdadeiramente OO, me cai em uma avaliação para processo seletivo o que é POO.

Eu nunca sei  qual é a resposta que os avaliadores esperam com isso porque eu nunca sei o quanto eles sabem de POO ou se eles estão equivocados. Já trabalhei em empresas onde a "crença" local era que POO era herança. Em outra os funcionários e o dono acreditavam piamente que programavam orientado a objeto, quando na verdade era programação macarrônica com método faz tudo.

A última empresa que trabalhei, um dos donos da empresa era, hummm, digamos, "programador", e ditava, ditatorialmente, as regras de como o código deveria ser desenvolvido: uma mistura de cobol não estruturado com asp, onde TODO o código do sistema estava no page_load das páginas.

Aí vem em uma avaliação a pergunta sobre o que é POO, o que é herança, o que é polimorfismo etc ... Eu devo apenas definir? Explicar? Exemplificar?

Compartilho abaixo o enunciado de uma dessas avaliações e as minhas respostas.


Conceitos teóricos

1)      Qual a importância da utilização da programação orientada a objetos? Cite algumas técnicas.

R.: A programação orientada a objetos, associada à outras boas práticas de programação, favorece um código mais coeso e menos acoplado, facilitando o reaproveitamento de código e a manutenibilidade do mesmo.Na programação orientada a objetos, dados e ações que pertencem a uma mesma entidade ou unidade lógica são agrupados em uma classe, que é um tipo de objeto.
Uma classe pode ser instanciada, ou seja, ter um objeto de seu tipo criado, e esse objeto conterá os dados da classe e as operações que atuam sobre esses dados.
A programação orientada a objeto, quando bem aplicada, permite código menor, menos repetitivo e mais eficiente, por meio da abstração.Alguns conceitos importantes em POO são herança, polimorfismo, abstração, compósição e agregação.
Herança permite que dados e comportamentos sejam transmitidos de uma classe base para uma derivada sem que código seja reescrito. Polimorfismo permite que haja diferentes implementações de um mesmo método nos diferentes objetos que implementem uma mesma interface (ou tenham um ancestral em comum).  Por exemplo, ao ter uma variável “a” da interface “i” diferente de nulo, quando executamos o método “metodo()”, o código executado será o do objeto instanciado que implemente a mesma assinatura de “metodo()”.Composição é a ligação, através de construtores ou setters, de vários objetos compondo um todo. O todo, nesse caso, é maior do que as partes e não deve existir ou funcionar sem uma de suas partes. Com composição se adiciona novos comportamentos a um objeto por adicionar mais partes que interagem entre si.Agregação é uma interação mais fraca que a composição. Objetos e coleções de objetos podem ser ligados uns aos outros criando um todo com comportamento próprio, mas as partes podem existir separadamente.
Um exemplo de composição é um Carro e suas Rodas, ou aproveitando o exemplo de e-commerce desse teste, o Pedido e seus itens. Embora os produtos podem existir sem nunca serem comprados, um Pedido não existe sem os itens, e um carro não tem propósito sem suas rodas.
Um exemplo de agregação seria um computador, pois CPU e periféricos, embora trabalhem juntos também funcionam separadamente, e o Carrinho e seus itens. Diferentemente do Pedido, um carrinho pode estar vazio, no momento do começo das compras.


  2)      Descreva os princípios SOLID e porque eles são importantes.

R.: SOLID é uma abreviação de outras 5 abreviações. Essas abreviações, em inglês são:SRP (Single responsibility principle),  significa que uma classe deve ter apenas uma responsabilidade e por consequência disso apenas um motivo para                                                                         mudar.OCP (Open/Closed principle), significa que uma classe deve ser fechada para modificação e aberta para extensão. Esse conceito é uma extensão do conceito acima e quer dizer que uma classe não deve ser modificada, mas deve ter seu comportamento extendido através de herança ou composição.
LSP (Liskov substitution principle)  é o príncípio de substituição de liskov, que significa que um objeto esperado pode ser substituido por qualquer objeto de uma classe descendente. Quando uma classe filha altera o comportamento padrão de um método ou omite uma propriedade, então o princípio de liskov está sendo violado.
ISP (Interface segregation principle) prega que de devemo separar nossos objetos em várias interfaces, e que várias interfaces que interagem e trocam mensagens entre si são melhores que um objeto único de proposito geral. Isso permite flexibilidade e reaproveitamento de código através de agregação e composição.
DIP (dependency inversion principle)  diz que um objeto não pode depender da implementação concreta de outro, mas sim de sua interface. Esse princípio nos guia, junto com o principio acima, a programar orientado a interfaces.
Por exemplo, se dois objetos executam a tarefa de enviar um e-mail de confirmação, logo deveríamos ter um terceiro, responsável pelo envio do e-mail. No entanto, se temos vários métodos ou bibliotecas de envio de e-mail e não queremos que um objeto tenha uma dependência rígida com uma implementação específica, então transformamos a classe de envio de e-mail em uma classe de serviço, extraimos sua interface e, aos objetos que necessitam de enviar um e-mail, entregamos uma variável do tipo dessa interfae, com um objeto de envio de e-mail instanciado.


 3)      Cite design patterns e para qual finalidade eles existem.

R.:  São padrões de projeto. Um conjunto de abstrações encontradas em vários projetos que se repetem, pois visam reslver problemas específicos.
No livro “Padrões de Projeto”, do grupo “Gang of Four”, existe um catálogo de padrões de projeto identificados  e descritos por ele, como exemplos. Mas este livro não é a única fonte. Há também o livro “Patterns of Enterprise Application Development” de Martin Fowler.
Dentre os padrões de projeto podemos citar os criacionais factory method, que é um método que instancia um objeto inicializando-o e devolve-o para o chamador, abstract factory, que é uma classe abstrata com factory methods que, valendo-se de polimorfismo, delega a criação de objetos concretos à suas própria implementações concretas, singleton, que cria uma instância de um objeto e permite que apenas um seja criado. Podemos citar também o padrão strategy, que permite que uma dentre várias ações diferentes possam ser escolhidas dependendo do objeto instanciado e o padrão iterator, usado para se navegar em uma coleção de objetos.Escrevi 4 artigos para a revista Clube Delphi sobre padrões de projeto, 3 sobre factory method e abstract factory e um sobre singleton, seguem links abaixo: http://www.devmedia.com.br/websys.4/webreader.asp?cat=3&revista=clubedelphi_122#a-2883http://www.devmedia.com.br/websys.4/webreader.asp?cat=3&revista=clubedelphi_123#a-2969http://www.devmedia.com.br/websys.4/webreader.asp?cat=3&revista=clubedelphi_124#a-3081http://www.devmedia.com.br/websys.4/webreader.asp?cat=3&revista=clubedelphi_133#a-3902 Design patterns não significam “Normas” de projeto, e sim “padrões” de projeto. Padrões aqui no sentido matemático: uma forma que se repete.

  4)       Quais os principais conceitos que compõe o DDD.

R.: O principal conceito do DDD é o domínio, ou seja, as regras de negócio. O foco do DDD é no domínio e as classes da camada de negócio devem ser o core do sistema.
Como apoio a essa técnica DDD preconiza que o time de desenvolvimento deve adotar o vocabulário, termo se jargões próprios do domínio e criar um vocabulário padrão para toda a equipe.
DDD desencoraja um desenvolvimento em um número muit o grande de camadas (por exemplo usando WCF entre a camada de aplicação e a GUI) porque o uso de DTO’s  não é natural à DDD. Nessa metodologia, tudo que foge ao negócio como glue code e plumbing code, é considerado parte da infraestrutura. A esse conceito dá-se o nome de linguagem ubíqua.
Outros conceitos importantes em DDD é o conceito de Entidade (objetos com ID e ciclo de vida, que são persistidos e têm existência por si só) e sua distinção de objetos de valor (simples contêineres para valores sem ciclo de vida ou identidade própria).  Também são conceitos da DDD agregados, serviços e repositórios.DDD também é associado à outras boas práticas como TDD e a separação do sistema em 4 camadas: Interface de usuário, Aplicação, Dominio (entidades e objetos de valor ficam aqui) e Infra-estrutura (repositórios, serviços e outras classes de apoio).


Será que me estendi demais? Tenho esse costume, e tenho o costume de fugir do assunto também, parece que minha mente não funciona muito linearmente, tampouco objetivamente. No entanto, o que você escreveria de memória, sem consultar seus livros anotações revistas e sites?

Nenhum comentário:

Postar um comentário

Postagens populares

Marcadores

delphi (60) C# (31) poo (21) Lazarus (19) Site aos Pedaços (15) sql (13) Reflexões (10) .Net (9) Humor (9) javascript (9) ASp.Net (8) api (8) Básico (6) Programação (6) ms sql server (5) Web (4) banco de dados (4) HTML (3) PHP (3) Python (3) design patterns (3) jQuery (3) livros (3) metaprogramação (3) Ajax (2) Debug (2) Dicas Básicas Windows (2) Pascal (2) games (2) linguagem (2) música (2) singleton (2) tecnologia (2) Anime (1) Api do Windows (1) Assembly (1) Eventos (1) Experts (1) GNU (1) Inglês (1) JSON (1) SO (1) datas (1) developers (1) dicas (1) easter egg (1) firebird (1) interfaces (1) introspecção (1) memo (1) oracle (1) reflexão (1)