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?
Comentários
Postar um comentário