Um dos temas mais falados no mudo da programação é sobre o paradigma de Programação Orientada a Objetos (POO). Vemos várias pessoas falando sobre o tema, mas, escrever os scripts e ao mesmo tempo pensar no nível de profundidade onde conseguimos identificar partes de um contexto e a relação de troca de mensagens entre essas partes, é uma tarefa um pouco difícil. Me refiro a difícil, não na implementação, me refiro difícil para conceber esse contexto de Objeto de forma mais global. Sem estressarmos nosso entendimento sobre as variáveis que compõem a POO, tendemos a escrever códigos sujos que não atendem aos requisitos de, por exemplo, definir corretamente um objeto ou um conjunto de objetos.
O que é um objeto?
Segundo uma das definições encontradas no dicionário, temos um objeto como: “Coisa material que pode ser percebida pelos sentidos (visão, audição, tato, olfato e paladar)”. Nesse contexto, conseguimos intuir facilmente que uma bola, um relógio, uma cadeira, um celular, trata-se de objetos.
Essa definição nos ajuda a entender um pouco a dificuldade que os programadores, sobretudo os iniciantes, têm em entender o conceito de “Programar Orientado a Objetos”, uma vez que não conseguimos materializar essa ideia através do outros sentidos humanos, como por exemplo audição ou até mesmo tato quando estamos escrevendo nossos códigos.
Como nós, seres humanos, aprendemos a identificar objetos? Quando você olha para um “gato”, como você aprende a identificar que um gato realmente é um gato? Aqui entra em cena um recurso, que nós seres humanos, temos por natureza: a capacidade de abstrair características e comportamentos de coisas. É através da abstração que conseguimos analisar e entender, vamos dizer, algumas “coisas”.
O que é abstração?
Voltando mais uma vez para o nosso querido dicionário, temos a definição de abstração como: “Ação de abstrair, de analisar isoladamente um aspecto, contido num todo, sem ter em consideração sua relação com a realidade”. Só essa definição já nos ajuda a entender sobre abstração, mas esse conceito para se materializar em código e scripts, exigem de nós programadores um esforço maior. É muito mais filosófico!
Recorrendo mais uma vez ao dicionário, na visão da filosofia, abstração é: “operação mental através da qual elementos e aspectos são isolados, somente no pensamento, sendo que (na totalidade) não existem isoladamente; resultado dessa operação”.
Trazendo para um exemplo “vulgar”, quando olhamos para um gato e identificamos que se trata de um gato, estamos olhando suas características e ações. Pegamos essas características e ações deste objeto e conseguimos comparar com outros objetos em busca de variações. Para não ficar muito subjetivo essa definição, vamos exercitar um pouco nossa capacidade de abstração. Pensando nas características de um “objeto do tipo gato” temos:
- Um gato normalmente tem 4 pata;
- Um gato normalmente tem pelos;
- Um gato normalmente tem unhas pontiaguda;
Observe que apenas analisar as características não é suficiente para declararmos “estas características são de um gato”. Quando colocamos as ações que um “objeto gato” pode ter, melhora um pouco o nosso entendimento sobre o objeto em questão.
Ações de um gato:
- Um gato normalmente é um quadrúpede, ou seja, anda sobre as quatro patas;
- Um gato normalmente tem saltos muito altos;
- Um gato usa suas unhas pontiagudas para arranhar coisas;
Continuamos no impasse ao tentar abstrair coisas que nos deem o entendimento sobre o “objeto gato”. Se eu colocasse nas ações “um gato normalmente mia”, aí sim, seria mais contundente para definirmos uma diferença particular que nos faz distinguir um “objeto gato” de um “objeto cachorro”, por exemplo.
E se você fosse pegar essas características até agora e fosse comparar com um “objeto tigre”? Obviamente exigiria um nível de abstração maior. Precisaria de mais detalhes sobre o objeto analisado.
Tendo essa dificuldade entre diferenciar um “objeto gato” de um “objeto tigre”, colocamos objetos em classes. Essas classes agrupam características que nos ajudam na separação dos objetos similares ou até mesmo na formulação de um objeto a partir de outro. Por exemplo, existem vários tipos de felinos que são sutis as características que os compõem, como exemplo a cor, tamanho do pelo, etc… Ou seja, não existe apenas um tipo de gato. Temos por exemplo, gatos domésticos e gatos selvagens. As classes ajudam nessa organização.
O que é uma classe?
Para entender esse conceito de classe, recorremos à Biologia. Na definição temos que uma classe é: “cada uma das grandes divisões de um reino da natureza, as quais se subdividem em ordens”. Com isso em mente, buscamos dentro do estudo da Lógica, complementar esse conceito e termos uma classe como: “parte da teoria que trata das relações entre as classes e das operações sobre as mesmas”.
Dentro do estudo da Lógica, onde literalmente misturamos Filosofia e Matemática, temos axiomas, que são proposições que admitem algo como verdade, mesmo se não for demonstrável e que conseguimos fundamentar teoricamente. Em outras palavras, conseguimos deduzir coisas a partir de outras coisas. Com isso, conseguimos intuir uma classe como “algo que representa intuitivamente uma coleção de objetos com características afins”.
“Proposição: Aquilo que se propõe; sugestão que se faz acerca de alguma coisa; o que se afirma, se diz, se escreve; afirmação.”
Como uma classe define um objeto?
Para fortalecer o seu entendimento, vamos voltar mais uma vez para características e ações abordadas na abstração. Dentro de uma classe, podemos ter métodos e atributos que compõem o que é necessário para criarmos uma instância de um objeto. Os atributos têm relação direta com as características do objeto ou seja ele armazena o estado do objeto. Já os métodos, têm relação direta com as ações. Ou seja, os métodos definem as habilidades de um objeto.
No parágrafo anterior, temos dois termos de suma importância para você se tornar um programador diferenciado. Vale ressaltar antes que, “o ato de programar, é mais filosófico do que prático”. Você vai passar mais tempo pensando sobre possibilidades e considerações do que necessariamente escrevendo códigos. Voltando ao cerne, não negligencie não saber profundamente o que é um estado e o que é uma instância de um objeto.
O que é um estado?
O nosso bom e querido dicionário nos trás uma excelente definição de estado voltado para esse contexto de objeto. “Um estado é a reunião das particularidades ou das características através das quais algo ou alguém pode ser caracterizado(a)”. Como na programação pegamos conceitos externos e transformamos em conceitos lógicos, podemos pegar emprestado da física a definição de estado como: “a condição definida pela reunião de suas propriedades”.
O que é instância?
Para entendermos o que é uma instância, podemos pegar a sua etimologia. O termo instância vem do latim “instantia.ae“, que quer dizer “qualidade do que é próximo, assíduo, veemente, evidência”. Pegamos como último a “evidência”, podemos dizer que “a instância de um classe evidencia a criação de um objeto”. Ou seja, a classe é a abstração estruturada e o objeto é a concretização da ideia do objeto modelado.
Tendo estes pontos bem fundamentados, torna- se fácil compreender a relação da Programação Orientada a Objetos e os mecanismos que compõem a sua concepção.
Quando falamos de Programação Orientada a Objetos estamos reunindo esses elementos, que podemos chamar de entidades, e montar a relação de comunicação entre estas partes de modo a organizar estas relações, de trocas de mensagens e características para criarmos um sistema.
“Uma Entidade é o que pode fazer parte ou constituir alguma coisa real; tudo aquilo que existe ou pode existir. É aquilo que constitui a essência de algo”
“Um Sistema é um conjunto ordenado de elementos que se encontram interligados e que interagem entre si”
Para organizarmos esses fundamentos e termos um parâmetro comum de entendimento sobre como programar orientado a objetos, a POO tem 4 pilares que ajudam nesta definição
Quais são os 4 pilares da Programação Orientada a Objetos?
Os 4 pilares são: Abstração, Encapsulamento, Herança e Polimorfismo.
Sobre a abstração já conceituamos bastante. Não é necessário repetir aqui.
Em relação ao Encapsulamento, no momento em que estamos criando uma abstração sobre algo, temos que pensar sobre como será o comportamento interno do seu estado e como será o acesso às partes do seu código. A esse controle chamamos de Encapsulamento. Como o nome sugere, encapsular é algo como proteger em um cápsula. Nesse sentido, você restringe os acessos indevidos ao estado do seu objeto.
Quando falamos de Herança, o que vem a sua mente? Normalmente, pensamos em alguém herdando algum bem material de outra pessoa. Mas, indo um pouco para a área da genética, temos herança como “conjunto de caracteres hereditários transmitidos pelos genes”. Podemos utilizar esta definição para nos ajudar a entender esse princípio dentro da POO.
Vamos pensar mais uma vez sobre o “objeto gato”. Descendo bem o nível de profundidade de abstração, podemos chegar a conclusão que todo gato é um “animal” e as características que definem um animal são comuns. Você pode dizer que um cachorro ou um elefante é um animal, correto? Já uma pedra, é um animal? Com esse entendimento, na programação Orientada a Objetos, pensamos na herança como características comuns que podem ser reutilizadas ou compartilhadas entre classes. Ou seja, definimos uma classe base(mãe) com características comuns, e as “subclasses”(filhas) podem herdar estas características na sua concepção.
A palavra Polimorfismo já assusta em sua escrita, mas conceitualmente, recorrendo mais uma vez ao nosso grande amigo dicionário, temos o Polimorfismo como: “qualidade do que é capaz de assumir formas diferentes ou do que ocorre de diferentes formas”. Até mesmo a etimologia da palavra já ajuda na sua compreensão. O termo polimorfismo é originário do grego e significa “muitas formas” (poli = muitas, morphos = formas).
Tentando “pegar um gancho” no termo vindo da Biologia, “polimorfismos são variações genéticas que aparecem como consequências de mutações, podendo ter diferentes classificações dependendo da mutação original”, nos dá uma compreensão melhor sobre o termo.
“Note que Programar Orientado a Objetos é uma arte de combinar vários elementos e princípios externos do nosso cotidiano e empregar de forma lógica e representativa em nossos sistemas”
Voltando para o Polimorfismo, lá vamos nós mais uma vez para a Biologia para conceituarmos. Pense em um “Homem”, um “macaco” e um “morcego”. O que esses três atores têm em comum? Todos são mamíferos. Com isso, podemos dizer que todo mamífero tem algumas características e métodos em comuns que são herdadas pelas subclasses, correto? Pensando em comportamentos que podem ser comuns, mas que são executados de forma diferentes, como é o caso da ação de “comunicar-se” ou “locomover-se”. Trazendo para a programação, o ato de “locomover-se” se tornaria um método comum, ou seja, todos os 3 atores teriam esse método com o mesmo nome, porém, internamente ele assume “muitas formas” ou seja ele se torna “polimórfico”. É exatamente esse o comportamento do Polimorfismo dentro da programação Orientada a objetos.
Conclusão
A Programação Orientada a Objetos exige muito mais um esforço intelectual e particular para organização dos nossos códigos em elementos “inter-relacionados” e “reaproveitáveis”, que dependendo do seu agrupamento, pode facilitar muito na organização e controle dos nossos artefatos de sistema. Ou, caso você não utilize corretamente estes conceitos, vai gerar uma confusão tão grande no seu código, que vai ser praticamente impossível mantê-lo.
Uma dica valiosa que queremos que você tenha em mente é: “pense sobre a relação de troca de mensagens entre as entidades. Veja qual o comportamento esperado dos estados dos objetos”. Com isso em mente, você consegue canalizar esforços em garantir outros princípios e padrões que nos ajudam a melhorar nossa qualidade de código. Podemos utilizar outros princípios e padrões como o DRY (Don’t repeat yourself), SOLID (5 princípios super importantes, cunhados pelo Robert C. Martin), KISS(Keep it Simple, Stupid!), YAGNI(You Aren’t Gonna Need It), DDD (Domain Driven Design), TDD (Test Driven Development) e muitos outros além dos padrões de projetos (Design Patterns) que nos ajudam a melhorar cada vez mais os nossos projetos de software.
No passado fiz um artigo de Introdução a Programação Orientada a Objetos onde você pode pegar algumas dicas utilizando códigos e exemplos. E se você quiser melhorar suas habilidades de soft skills, venha conhecer o projeto Let’s Dev Tech.
Confiança Sempre!!!
Seja o primeiro a comentar