A importância da Programação Orientada a Objetos – Parte I

Atualmente, é comum pessoas terem ideias inovadoras. Porém, esses insights não servem para nada se eles permanecerem somente no campo cerebral. Para começar a ver o valor de determinada percepção intelectual é necessário criar o produto que permita concretizar a ideia. Com a evolução dos computadores ao redor do mundo e a franca expansão destas máquinas, um dos caminhos para “materializar” a ideia é desenvolver software.

O algoritmo – uma sequência de passos finitos com o objetivo de solucionar um problema para desenvolver software – não é único e também não é trivial. É necessário entender de diversos conceitos que permeiam o estudo da computação. Dentre eles, destacam-se: Análise de Requisitos, Diagramas UML, Programação Orientada a Objetos (POO), Padrões de Projeto (Design Patterns), Design de Interface do Usuário (UI) e Experiência do Usuário (UX); e Testes Automatizados. Além disso tudo, é preciso realizar leitura de muito material (maioria em inglês) e atualizar-se quase que permanentemente.

Nesta primeira parte sobre a importância de POO, iremos falar exclusivamente dos principais conceitos deste paradigma de programação.

Existem diversas vantagens de se utilizar da POO para projetar e construir um sistema. As principais são:

  • Esforço pequeno na manutenção/criação de novas funcionalidades: principal vantagem. Pode se tornar uma vantagem competitiva, pois como a única certeza que temos é que os clientes vão requerer mudanças, quanto mais rápido esta mudança for implementada no sistema, mais competente seremos (aos olhos do cliente).
  • Reuso de código: o relacionamento entre classes e interfaces permite que um mesmo código seja utilizado por diversas outras classes.
  • Organização do projeto: como o projeto POO tende a ficar “modularizado”, não é necessário percorrer o projeto todo para prestar manutenções. Basta localizar a(s) classe(s) a ser(em) modificada(s) e trabalhar nelas. Lógico que é necessário tomar cuidado com as dependências.
  • Facilidade para realizar testes unitários: relacionado ao tópico anterior. É possível realizar testes unitários de maneira automatizada. Sendo assim, a qualidade do produto tende a crescer.

A POO está para o desenvolvimento de software atual assim como o verde e o amarelo estão para a bandeira do Brasil. É essencial, por exemplo, saber criar classes e declarar seus atributos e seus métodos/funções; instanciar objetos de determinada classe; entender como se realiza herança entre classes; conhecer sobre interfaces. Isto tudo por causa das vantagens apresentadas anteriormente e porque os Kits de Desenvolvimento de Software (Software Development Kit – SDK) já possuem diversas funcionalidades prontas para serem chamadas (reutilizadas) através do projeto que está em construção.

Outro conceito que está relacionado indiretamente à POO e que também auxilia no desenvolvimento, tornando o código mais legível e organizado, é o CamelCase. Vale lembrar que não são regras, apenas convenções. Tais conceitos básicos são:

  1. O nome da classe deve sempre começar com letra maiúscula. Se a classe for composta por duas ou mais palavras, cada palavra deve começar com letra maiúscula. Por exemplo: Activity, DatePickerDialog.
  2. O nome dos métodos deve sempre iniciar com letra minúsculas. Se o nome do método for formado por duas ou mais palavras, a partir da segunda palavra, deve-se usar letra maiúscula. Por exemplo: init(), onCreate().
  3. O nome das constantes deve ser todo em letra maiúscula. Caso a constante seja constituída por duas palavras, elas são separadas através de underscore/underline. Por exemplo: RELEASE, TOKEN_ERROR.

Exemplificando… (baseado no livro SIERRA, Kathy; BATES, Bert. Use a Cabeça! Java, 2ª edição. Alta Books. ISBN: 9788576081739. 2005.)

\\\"livroJava\\\"

Observe o diagrama de classes a seguir. Ele é fruto de um projeto para um sistema que vai rodar em um zoológico (para fins didáticos, irei considerar apenas classes de modelo. Em um ambiente real, teria classes de serviço, DAO, fachadas e demais).

\\\"Diagrama01\\\"

Verifica-se no diagrama anterior as relações entre as classes:

  1. Cachorro > Canino > Animal
  2. Lobo > Canino > Animal
  3. Gato > Felino > Animal
  4. Leão > Felino > Animal

Para não nos tornamos repetitivos, vamos codificar apenas a relação 1):

classe Animal:

[code language=\\\”java\\\”]
abstract class Animal {
private double tamanho;
private double peso;
private int idade;

public void fazerBarulho() {
// corpo do método fazerBarulho() – classe Animal
}

public void vaguear() {
//corpo do método vaguear() – classe Animal
}

//outros métodos…

//métodos de acesso getters & setters
}
[/code]

classe Canino:

[code language=\\\”java\\\”]
abstract class Canino extends Animal {
void vaguear() {
//corpo do método vaguear() – classe Canino
}
}
[/code]

classe Cachorro:

[code language=\\\”java\\\”]
class Cachorro extends Canino {
public void fazerBarulho() {
// corpo do método fazerBarulho() – classe Cachorro
}

public void comer() {
//corpo do método comer() – classe Cachorro
}
}
[/code]

 

As classes Animal e Canino estão declaradas com a palavra reservada abstract: isto informa à Máquina Virtual Java (JVM) que estas classes não podem ser instanciadas, ou seja, não é possível criar objeto das mesmas. Por que isto? Imagine se fosse possível instanciar um objeto da classe Canino, qual formato este Canino teria? Não seria nem cachorro, nem lobo, nem qualquer outro canino da natureza. Portanto, por motivos de segurança, é importante vetar a utilização desta classe para criar objetos. O código a seguir geraria erro.

[code language=\\\”java\\\”]
class Programa {
public static void main(String args[]) {
Animal a1 = new Animal();
}
}
[/code]

Os atributos da classe Animal estão declarados como privados (private): esta prática estabelece o encapsulamento dos atributos da class. Isto significa que eles não podem ser acessados diretamente por outras classes clientes, e sim através dos métodos de configuração do tipo set() e get(). Tal prática torna a classe mais segura, já que podemos implementar regras no método set() para assegurar que nenhum valor estranho possa ser guardado em um atributo. Já pensou se um programador descuidado igualasse o atributo peso a zero? O código a seguir geraria erro, pois não é possível acessar atributos diretamente.

[code language=\\\”java\\\”]
class Programa {
public static void main(String args[]) {
Cachorro c1 = new Cachorro();
c1.idade = 3; //ferindo o encapsulamento…
}
}
[/code]

A palavra reservada extends indica relação de herança entre as classes. Isto quer dizer que tudo o que for público em uma classe pai pode ser acessado pela classe filha. O exemplo a seguir mostra o acesso do método setIdade() da classe Animal através de um objeto da classe Cachorro. Isto também pode ser feito através das classes Leão, Gato e Lobo. Percebe a reutilização de código? Outra reflexão a respeito da herança: se outro animal surgisse, seria só declarar a classe respectiva e herdar das classes corretas. Percebe a facilidade na manutenção do projeto?

[code language=\\\”java\\\”]
class Programa {
public static void main(String args[]) {
Cachorro c1 = new Cachorro();
c1.setIdade( 3 );
}
}
[/code]

Os métodos vaguear() fazem parte da classe Canino e da classe Animal. Os métodos fazerBarulho() e comer() fazem parte da classe Cachorro e Animal. Isto está sendo realmente reutilizado? Sim, pois cada animal, isto é, cada classe, faz barulho e come de forma diferente: um cachorro late e um gato mia. O nome deste princípio da POO é conhecido como sobrescrita (do inglês, override). Isto ajuda a organizar o projeto.

No próximo post iremos abordar o conceito de interface. Até lá!


Comentários

8 respostas para “A importância da Programação Orientada a Objetos – Parte I”

  1. Avatar de Marcelo Pereira
    Marcelo Pereira

    Existe um problema, do meu ponto de vista, na maioria das abordagens para ensinar POO. O próprio artigo mostra um diagrama de classes e fala que tal modelo será utilizado num sistema de zoológico. Mas, a gente sabe que não existe tal sistema de zoológico onde eu clico num botão e faço um leão fazer barulho, ou envio uma requisição SOAP pedindo para um hipopótamo comer. É muito comum ver profissionais que conhecem POO de um ponto de vista lúdico, mas têm dificuldade em aplicar na vida real, pois eles nunca exercitaram a modelagem de elementos reais de um sistema. Por exemplo, um sistema de zoológico real possui um cadastro de funcionários, animais, horários de alimentação, controle do estoque da comida, ou algo assim. Além disso, existem outros elementos da arquitetura como interface de webservices, persistência, entre outros. Não discuto aqui a importância da POO, sendo inclusive um forte defensor do paradigma. Também não discuto aqui o conhecimento do autor e nem estou dizendo que ele foi o primeiro a utilizar a abordagem dos mamíferos pra ensinar POO. Esta abordagem é muito conhecida, porém acredito ser ineficiente. Exemplos reais mostrariam com muita mais eficácia a importância deste paradigma.

  2. Avatar de Ramon Rabello
    Ramon Rabello

    Marcelo, se você perceber, a categoria do post está como iniciante. Creio que o autor preferiu esse exemplo por causa da didática e por ser um exemplo bem conhecido na área. Principalmente para quem é universitário ou está começando no ramo de desenvolvimento de software, muitos desses termos como webservices, SOAP, MVC, beans, REST, micro-serviços, facades e outros padrões de projetos ainda são novidades e vai mais confundir do que ajudar.

  3. Avatar de Marcelo Pereira
    Marcelo Pereira

    Ramon, eu não me enganei com relação à categoria do post. Cito o início do meu comentário: \”Existe um problema, do meu ponto de vista, na maioria das abordagens para ensinar (se ensina um iniciante) POO\”. Citei em um trecho específico as palavras SOAP e Webservices, mas o ponto central da discussão é que num sistema de zoológico os animais não fazem barulho e nem comem. Entendo que o propósito não foi modelar um sistema real, mas sim apresentar os conceitos básicos. Porém, do meu ponto de vista essa abordagem é ingênua, pois não ensina a identificar as fronteiras de um sistema real e isso, sim, é algo que um iniciante deve aprender.
    Quando estive no início do mestrado tínhamos que fazer algumas monitorias em disciplinas para ganhar créditos. Às vezes tínhamos que corrigir algumas provas. Tinha essa questão relacionada a um sistema de bilhetagem eletrônica nos ônibus de Belém e um dos alunos modelou a classe Pessoa com os métodos \’esperar na parada de ônibus\’, \’subir no ônibus\’ e \’fazer sinal\’. Todas estas são ações que uma pessoa pratica, mas que estão fora da fronteira do sistema. O que ele me disse foi: \”é apenas uma modelagem pra entender o problema, na hora de construir um sistema de verdade a gente escreve código\”. Ou seja, existe um abismo entre o ensino de OO e a sua aplicação.
    Muitos aqui devem conhecer o processo de seleção da ThoughtWorks. Em uma etapa específica eles propõem que você escreva um programa para resolver um problema simples, destes que vemos no início do nosso aprendizado de programação, estrutura de dados e etc. Pode ser: caixeiro viajante, conversão de algarismos romanos ou escrever numerais por extenso. Um dos quesitos avaliados é domínio de OO. Por que não ensinar POO utilizando exemplos reais como estes?
    Em resumo, Alan, parabéns pelo artigo, entendo o seu ponto de vista, não estou colocando em questão aqui a sua expertise em POO. Meu comentário é uma questão que trago para o debate na comunidade e não uma crítica destrutiva ao seu trabalho. Existe um livro chamado \”Aprenda Em 24 Horas C++\” de Jesse Liberty. Neste livro, ele mostra o conceito de herança e polimorfismo na construção de uma lista encadeada. É um exemplo fantástico porque poucos autores mostram estes conceitos na prática. Você poderia utilizá-lo na parte II do seu artigo.

    1. Avatar de Ramon Rabello
      Ramon Rabello

      Legal, Marcelo. Que tal escreveres um post aqui no blog explicando exatamente esse abismo, compartilhando tua expertise e dicas para quem está começando ou tem pouca experiencia em Java? 🙂 #ficaDica

  4. Marcelo, obrigado pelo seu feedback. Eu lembro que logo que saí da faculdade, nem o exemplo do zoológico eu sabia abstrair, mesmo lendo livros ou fazendo os exercícios/projetos propostos pelo professor. Comecei a entender realmente POO quando iniciei como programador de sistemas. O contato com pessoas mais experientes e com o próprio sistema, na grande maioria das vezes já pronto, permitiram que eu entendesse diversos conceitos que outrora não compreendia. Concordo que o exemplo do zoológico é algo banal e não se aplicaria de fato em sistema, na prática. Entretanto, a minha intenção maior – e acredito que seja a mesma do livro citado no artigo – é conceituar a POO e não ensinar na prática ou propor abordagens utilizando este paradigma. A parte II do artigo vai trazer conceito de interface, como é uma continuação do zoológico, penso que fica complicado mudar a abordagem.
    Sem querer ser irascível (muito pelo contrário), proponho que você escreva um artigo mostrando um exemplo mais prático utilizando o poder da POO. Poderia até conter uma comparação entre a abordagem estruturada e a abordagem orientada a objetos.
    Saudações!

  5. Avatar de Marcelo Pereira
    Marcelo Pereira

    Alan e Ramon, é uma boa dica. Pensei em escrever um artigo utilizando o exemplo do livro de C++ de que falei, mas não quis parecer como se tivesse tomando a palavra do Alan. Já que ele fez a deixa eu vou mostrar este exemplo. Também, pra não ficarem comentando que eu só fico polemizado os posts. =P

  6. Avatar de Marcus Java
    Marcus Java

    – Não pode repetir atributos (Ex: existe Vaguear,fazer Barulho e comer repetidas vezes em várias classes)…

  7. Avatar de Gilberto Fernandes
    Gilberto Fernandes

    Muito bom. Obrigado pelas dicas

Deixe um comentário

O seu endereço de e-mail não será publicado. Campos obrigatórios são marcados com *