Uma vez em uma aula de literatura, um professor perguntou para mim
o que pensava quando olhava para uma cadeira, respondi que pensava em que
seu material é feito, de onde veio, qual parafuso usa, material do tecido
e outras coisas que continuei a falar por algum tempo, ele fez
uma cara de “Hmm” e perguntou para outra pessoa na sala que respondeu o que
ele queria “Penso em me sentar”.
As aulas dele eram demais, mas acredito que ele não gostou muito de minha
resposta, porém a origem do meu pensamento sobre a cadeira não é algo
sem fundamento, muitas pessoas perdem com o passar do tempo esse modo de
ver as coisas, porém tudo pode ser modulado/fracionado/atomizado.
Fritjof Capra discorda e concordo em sua discordância, porém é o
pensamento cartesiano (Descartes: fundador da filosofia moderna) que desenha
a forma como compreendemos as coisas ou de como são impossíveis de serem
compreendidas, isso possibilitou a gente a
fazer fusão de átomos, acredito que prove algo, não é mesmo?
Por que orientado a objeto?
O mercado foi tomado pela Programação Orientada a Objeto
(POO) e muitos odeiam esse paradigma, assim como existe o POO
que tem seus pilares e modo de ver o mundo, existem também outros, como
procedural e funcional. Mas a maior força de POO reside no reúso do software,
imagine só que triste, você é uma pessoa desenvolvedora e cria um codigo que faz
uma cadeira verde, depois cria outro código copiando e colando…uma cadeira
azul, depois você cria outro, mas nesse as mudanças são tantas que você recria
a cadeira do jeito que o cliente quer…ou pior ainda, é desejada uma cadeira
com acessórios adicionais, como porta copo, propulsor à base de neutrinos e
um ajustador de medidas…nesse momento você já deve ter desistido do projeto.
Tudo isso pode ser feito com POO, a flexibilidade do código é absurda e se
você quer adicionar algo no projeto, basta fazer o que é chamado de herança,
fazendo com que a classe resultante da classe origem tenha mais recursos que
a anterior, é a evolução em ação! Para você pensar se você precisa de OOP
ou quaisquer boas práticas em relação à produção de software, veja esse trecho
do livro de Wilson de Pádua “Engenharia de Software - Fundamentos, Métodos e
Padrões”:
“A Engenharia de Software se preocupa com o software enquanto produto. Estão fora de seu escopo
programas que são feitos unicamente para diversão do programador. Estão fora de seu escopo também
pequenos programas descartáveis, feitos por alguém exclusivamente como meio para resolver um
problema, e que não serão utilizados por outros.”
Abstraindo uma cadeira
Pensemos em uma cadeira, ela tem características, certo? Mas apenas as
realmente essenciais, não tem parafuso, porque tem cadeira que é peça única ;)
Vamos listar algumas:
Depois de pegarmos todas essas características, temos que identificar o tipo
da variável, por exemplo:
Altura do assento é do tipo float, que são os números quebrados, por exemplo
1.556, agora sobre material…são coisas que devemos conhecer previamente,
nesse caso é interessante fazermos uma enumeração.
A estrutura que permite esse tipo de declaração tem em C, Python e Java,
sendo assim podemos enumerar as cores, materiais ou qualquer coisa que
quisermos listar e associar um número a isso.
Mas também podemos ter o tipo string, que é uma cadeia de caracteres, no caso
seria a Marca. Já o atributo Ocupada, é um booleano, permitindo verdadeiro
ou falso.
Criando a classe
Depois de termos esse pequeno exercício de abstrair uma cadeira, podemos criar
uma classe que crie cadeiras para nós!
Em Python
Via de regra, esta é uma classe em python que cria uma cadeira, com seus
atributos definidos, porém a principal ideia de uma classe é que sirva de
template(forma) para a instanciação (criação) de objetos, da forma que está,
temos um objeto que não é exatamente uma template, porque ele é fixo, para
alterar as propriedades da cadeira, temos que obrigatoriamente nesse caso
alterar o código contido na classe e isso joga no lixo o conceito de
programação orientada a objetos, um template deve ser ajustável!
Em Java
Seguindo a mesma ideia anterior:
Fazendo um objeto mais flexível
Em Python
Para podermos ter uma template de um objeto que possa ser moldado e não
rígido como os anteriores, precisamos de construtores! Eles basicamente são
métodos(pode-se entender método como função pertencente a uma classe)
que são executadas por padrão quando a classe está sendo instanciada
(se transformando em objeto), sendo assim, não precisamos alterar nada dentro
da classe para criar nosso objeto dinâmico.
Este exemplo em Python carrega um punhado de informações novas, primeiro vamos
observar o __init__, ele é o método construtor da nossa função, observe que
ele recebe como parâmetro todos os dados necessários para a instanciação do
nosso objeto.
Outro elemento novo aqui é o self, muitos programadores iniciantes se perdem
nele, mas o conceito aqui é mais ou menos assim: Imagine uma distribuidora de
cargas, o nome da distribuidora é SELF e ela distribui água pelo SELF.AGUA,
suco pelo SELF.SUCO e coisa do gênero, então o self é um unificador de
atribuitos da classe onde os mesmos podem ser acessados em qualquer método.
Um detalhe pequeno, mas não menos importante, é o underlines (_)
existente depois do self, isso não é capricho para deixar o nome mais legível,
quando utilizamos _ no self, tornamos aquele atributo protegido, mas ainda é
acessível fora da classe. Se usarmos dois __ como é o caso do nosso programa,
a situação muda! O atributo é acessível por outro nome!
depois de instanciar a classe Teste, podemos alterar o atributo teste2 assim:
Mas o atributo teste não é acessível desse modo. Temos que fazer:
Mas se o atributo é protegido, por que temos acesso e podemos alterá-lo? Isso é
uma questão filosófica da linguagem, seu criador não queria que existisse pedaços
inacessíveis, então em Python tudo é acessível de algum modo.
Objeto flexível em Java
O this em Java é o self do Python, note que em java a gente pode explicitar no
código de forma verborrágica que um atributo ou um método é protegido, público, privado ou estático.
Desse modo, podemos definir diversas configurações possíveis para nossa cadeira,
sem precisar alterar nada dentro da classe, o que dificulta a manutenção do
programa com o passar do tempo e também a sua extenção.
Fragmentando as classes - criando peça por peça
Vamos fatiar nossa classe em três: pés, assento, encosto. Assim podemos criar
cadeiras de todo tipo, inclusive banquinhos (que não tem encosto) e juntar tudo
na classe cadeira, que poderá nos retornar tudo.
Python - fragmentado e flexível
Isso é uma composição, é um padrão de desenvolvimento bem básico,
existem outros muito interessantes como singleton, factory, observer…
cada um tem um propósito de existência.
Java - fragmentado e flexível
Para fazer o código mais ou menos equivalente em Java, vamos precisar
criar 5 arquivos, cada qual com o nome da classe correspondente no arquivo.
Arquivo Cadeira.java:
Arquivo Assento.java
Arquivo Encosto.java
Arquivo Estofado.java
Arquivo Pe.java
Desse modo nossa composição em Java para construir uma cadeira já está pronta! O
ideal é que realizemos, em qualquer linguagem, composição ao invés de herança
pois melhora a flexibilidade do código.
Conclusão :D
Programação Orientada a Objetos não é melhor ou pior do que os outros
paradigmas, é uma forma de ver o mundo, que pode beneficiar ou não
a solução de problemas. A principal vantagem desse paradigma, é o reaproveitamento
de código, imagine só ter que reescrever uma classe de um programa que faz
determinada tarefa…isso é desperdício, para isso sim utilizamos algum tipo de
polimorfismo (ou poliformismo, como alguns dizem).