Capítulo 1 – Análise Orientada a Objetos

Fundamentos da programação orientada a objetos

A Orientação a Objetos e uma tecnologia que enxerga os sistemas como sendo coleção de objetos integrantes. Ela permite melhorar a (re)usabilidade e extensibilidade dos softwares.

A tecnologia orientada a objetos e fundamentada no que, coletivamente, chamamos de modelo de objetos, que engloba os princípios da abstração, hierarquização, encapsulamento, classificação, modularização, relacionamento, simultaneidade e persistência.

“Orientação a Objetos consiste em considerar os sistemas computacionais como coleção de objetos que interagem de maneira organizada.”

O que significa Orientação a Objetos?

Orientação a objeto  é um conceito que esta relacionado com a ideia de classificar, organizar e abstrair coisas. Veja a definição formal:

“O termo orientação a objetos significa organizar  o mundo real como uma coleção de objetos que incorporam estrutura de dados e um conjunto de operações que manipulam estes dados.”

Vamos falar uma linguagem, mas simples para isto vamos para um ambiente que você conhece bem: A sua casa!

Agora vamos olhar a sua estante, o seu guarda-roupa, o seu armário, a sua cozinha. Em todos estes lugares você classificou coisas no seu domínio e, somente de olhar para eles você já sabe relacionar a classificação que utilizou em cada um deles e como classificou as coisas que estão nestes lugares.

Na estante você agrupou e organizou os livros, no guarda roupa suas camisas, calças, meias, ternos, etc. Todos os objetos que você classificou nestes lugares foram organizados baseados em alguma concepção que você possuía sobre eles.

No contexto orientado a objeto a estante, o armário, a cozinha são chamados de “classes”.

No contexto de software podemos dizer que:

  • Uma classe é um gabarito para a definição de objetos. Através da definição de uma classe, descrevem-se as propriedades e atributos  que o objeto terá.
  • Uma classe mantém dois elementos importantes: estrutura e comportamento.
  • Uma estrutura representa os atributos que descrevem a classe.
  • Um comportamento representa os serviços que a classe suporta.

 

Na ‘classe’ do seu guarda-roupa, uma camisa amarela pode ser colocada em outra classe. A ‘classe’ camisa. Cada camisa tem uma estrutura que é: a textura, a cor, o tamanho e o modelo. Cada camisa tem um comportamento que é : ordenar , rasgar , desbotar .

Se você concordar que existe uma classe camisa. Vai concordar que existem diversos tipos de camisas com suas características, ou seja, existem diversos objetos camisas que podem ser criados a partir da classe camisa. Daí temos o conceito de objetos:

O conceito de orientação a objetos é abordado desta mesma maneira sempre. No contexto do software podemos então dizer que:

É através de objetos que (praticamente) todo o processamento ocorre em aplicações desenvolvidas com linguagens de programação orientadas a objetos.

  • Primeiro você classifica e abstrai os elementos no sistema para proporcionar certa ordem, e, ao fazer isto você define uma classe;
  • Feita a definição da classe você pode criar objetos desta classe. (instanciar)

 

Exemplo clássico da planta de uma casa.

  • A Classe seria um gabarito (como uma planta de uma casa)
  • O objeto é concretização do gabarito (casas feitas a partir da mesma planta)

Quando levamos estes conceitos para as linguagens de programação nada se altera.

Existem alguns conceitos básicos que estão vinculados ao conceito de orientação a objetos. São eles:

  • Herança
  • Encapsulamento
  • Polimorfismo

A herança permite implementar a funcionalidade a sua classe de tomar emprestado o resto da estrutura e comportamento de classes de nível mais alto.

Pensemos na classe Carro

Esta classe define os comportamentos e atributos de um carro; E existem atributos que serão comuns a todos os carros.

As rodas e o motor são atributos comuns a qualquer carro. Já uma Ferrari possui atributos que somente ela possui: o seu alto valor por exemplo.

A definição formal seria:

Herança é um mecanismo que permite que características comuns a diversas classes sejam agrupadas em uma classe base, ou superclasse. A partir de uma classe base, outras classes podem ser especificadas. Cada classe derivada ou subclasse apresenta as características (estrutura e métodos) da classe base e acrescenta a elas o que for definido de particularidade para ela.

Encapsular significa “ocultar informações”  ele define que cada objeto contém todos os detalhes de implementação necessários sobre como ele funciona e oculta os detalhes internos sobre como ele executa os serviços.

Quando você acelera um carro você esta enviando uma mensagem ao motor do carro usando o acelerador e o carro sabe que tem que acelerar.

Você não precisa saber como é feita a aceleração no motor você apenas pisa fundo no acelerador, a implementação de como é feita a aceleração esta encapsulada do cliente.

Polimorfismo significa muitas formas, na orientação a objetos você pode enviar uma mesma mensagem para diferentes objetos e fazê-los responder da maneira correta. Você pode enviar a mensagem de dar marcha-ré para cada objeto semelhante a um carro e cada um vai se comportar de maneira diferente para atender a sua solicitação.

Uma definição mais formal diria:

“Polimorfismo é o princípio pelo qual duas ou mais classes derivadas de uma mesma superclasse podem invocar métodos que têm a mesma identificação (assinatura), mas comportamentos distintos, especializados para cada classe derivada, usando para tanto uma referência a um objeto do tipo da superclasse.”

 

Componentes Básicos da Orientação a Objetos

  • Objeto ® Abstração que agrupa características e comportamentos.
  • Classe ® Tipo de Objeto. Define quais características um objeto pode ter e seu comportamento.
  • Instância ® É o Objeto propriamente dito. Possui características próprias
  • Mensagem ® Representa uma ação do objeto ou uma mudança de estado. Define a comunicação entre objetos.
  • Método ® Define a implementação de uma mensagem, ou seja, o comportamento dos objetos de uma classe.
  • Propriedade ® Define uma característica de um objeto.

 

Conceitos Adicionais

  • Protocolo ® Conjunto de mensagens que define o comportamento de um objeto. Interface.
  • Encapsular ® Garantir que os atributos só podem ser alterados por algum método.
  • Construtor ® Método encarregado de criar e estabelecer valores iniciais para um objeto.
  • Destrutor ® Método encarregado de destruir o objeto e fazer a coleta de lixo.

 

Capítulo 2 – Linguagens Orientadas a Objetos

Na literatura existe uma distinção entre linguagens baseadas em objetos e linguagens orientadas a objetos:

  • Uma linguagem é baseada em objetos quando ela fornece apoio somente ao conceito de objetos. Exemplo: Ada e Visual Basic
  • Uma linguagem é orientada a objetos quando ela fornece apoio a objetos, e requer que objetos sejam instâncias de classes. Além disso, um mecanismo de herança deve ser oferecido. Ex: C++, Java e Smalltalk.

Além da distinção entre linguagens baseadas em objetos e linguagens orientadas a objetos, existe outra distinção que classifica as linguagens orientadas a objetos em:

  • Híbridas: São linguagens que originalmente não foram projetadas orientadas a objetos, mas que passaram a incorporar os conceitos deste paradigma. Ex: C++ e Object Pascal
  • Puras: São linguagens que foram projetadas originalmente orientadas a objetos. Ex: Smalltalk e Java.

Podemos identificar similaridades entre a programação procedural (ou imperativa) e a programação orientada a objetos.

Paradigma Procedural

  • Tipos de Dados
  • Variável
  • Função / Procedimento
  • Chamada de Função

Paradigma de Objetos

  • Classes
  • Objeto / Instância
  • Operação / Método Serviço
  • Envio de Mensagem

Evolução das Linguagens para Orientação a Objetos

A Orientação a Objetos em computação tem 20 anos apesar de ter surgido fortemente apenas nos últimos sete anos. Surgiu mesmo na área acadêmica.

  • 1967 – Simula (Noruega);
  • 1980 – Small Talk (Xerox) com objetivos comerciais e acadêmicos, Adele Goldberg (autora);
  • 1980,s Objective C (Cox), C++ (Stroustrup), EifelL (Meyer);
  • Anos 70 – época da não estruturada, dados e códigos emaranhados;
  • Anos 80 – época da estruturada, dados separados de códigos (modulares);
  • Anos 90 – época da OO, dados e códigos organizados em objetos.

A partir dos anos 80, as principais linguagens incluíram conceitos de OO. Exemplo: Pascal, C, Lisp, Cobol, depois evoluíram com a inclusão de classes, C++ foi um marco para aplicações em todos os níveis. Surge o visual Object Oriented Cobol (c/win95) e o Visual Basic.

As linguagens mais utilizadas no mundo: 1- Cobol, 2 – Visual Basic (informação do Richard Soley e do Jon Siegel da OMG, Em dezembro 96).

 

Benefícios da Programação Orientada a Objetos

Listaremos a seguir os principais ganhos, para o desenvolvedor, caso este troque a metodologia tradicional pela Orientada ao Objeto.

  1. Exatidão – Devido à característica do desenvolvimento estruturado, onde se elabora um projeto e DEPOIS se faz os programas, podemos ter no final um sistema que não atenda perfeitamente seus objetivos depois de implementado. No desenvolvimento OOP, devido ao fato deste ser feito de maneira quase que interativa com o usuário, este risco e significativamente diminuído. A pouca quantidade de código programável também reduz os problemas inerentes às mudanças das especificações durante o desenvolvimento do projeto.
  1. Potencialidade – Definimos pontecialibidade a forma como o programa reage aos erros imprevistos como uma falha na impressora, ou a um disco cheio. Tanto maior for a potencialidade, maior a capacidade do programa em causar o menor estrago possível aos dados e evitar uma saída drástica do sistema.
  1. Extensibilidade – dizemos que quanto maior for a extensibilidade do software, maior será sua capacidade em adequar-se as especificações definidas pelos analistas.
  1. Reutilização – A capacidade de se otimizar a produtividade do programador depende diretamente da maneira como o software disponibiliza a reutilização do código gerado. De fato, a maioria dos programadores profissionais, já reutilização código anteriormente gerado, porem a perfeita reutilização consiste na utilização COMPLETA de um código gerado para algum sistema SEM qualquer outra adaptação prévia.

Capítulo 4 – Principais diagramas UML

Diagrama de Classes

O diagrama de classes é considerado o mais importante e o mais utilizado diagrama da UML. Seu principal enfoque está em permitir a visualização das classes que irão compor o sistema com seus respectivos atributos e métodos, bem como em demonstrar como as classes do sistema se relacionam se complementam e transmitem informações entre si. Este diagrama apresenta uma visão estática de como as classes estão organizadas, preocupando-se em definir a estrutura lógica das mesmas. O diagrama de classes serve como base para a construção da maior parte dos demais diagramas da UML.

Exemplo 1:
Pág 19 Imagem 1.png

Exemplo 2:

Pág 20 Imagem 1

Diagrama de Caso de Uso

O diagrama de casos de uso é um diagrama da UML cujo objetivo é representar um requisito do sistema que será automatizado. Considere como requisito uma necessidade do sistema.

Simbologia de um caso de uso (requisito que será automatizado):

Pág 20 Imagem 2

Usamos atores para representar as entidades que interagem com o sistema. Podem ser usuários, máquinas, sensores, etc.… Um ator representa um papel no sistema, mas um papel pode ser representando por vários atores.

Simbologia de um ator:

Pág 20 Imagem 3

Exemplo de um diagrama de casos de uso (sistema bancário):

Pág 21 Imagem 1

O ator cliente executará os casos de uso “realizar saque” e “consultar saldo”, enquanto o gerente poderá interagir com os casos de uso “abrir conta” e “vender seguro”.

Relacionamentos entre casos de uso

Os casos de usos podem se relacionar de duas formas:

  • Include: Quando um caso de uso “A” inclui (include) outro caso de uso “B”. Isto implica que ao executar o caso de uso “A” executa-se também o caso de uso “B”.

Pág 21 Imagem 2

  • Extends: Quando um caso de uso “A” tem um relacionamento do tipo extends com outro caso de uso “B”. Implica que ao executar o caso de uso “A” não necessariamente “B” será executado.

Pág 21 Imagem 3

Exemplo 1:Pág 22 Imagem 1

Exemplo 2:
Pág 23 Imagem 2

Diagrama de Sequência

Diagramas de Sequência mostram a troca de mensagens (isto é chamada de método) entre diversos Objetos, numa situação específica e delimitada no tempo. Objetos são instâncias de classes. Diagramas de Sequência colocam ênfase especial na ordem e nos momentos nos quais mensagens para os objetos são enviadas.

Em Diagramas de Sequência objetos são representados através de linhas verticais tracejadas, com o nome do Objeto no topo. O eixo do tempo é também vertical, aumentando para baixo, de modo que as mensagens são enviadas de um Objeto para outro na forma de setas com a operação e os nomes dos parâmetros.

Exemplo 1:
Pág 24 Imagem 1

Exemplo 2:

Pág 24 Imagem 2

Diagrama de Atividade

O objetivo do diagrama de atividades é mostrar o fluxo de atividades em um único processo. O diagrama mostra como uma atividade depende uma da outra.

Exemplo 1:

Pág 25 Imagem 1

Exemplo 2:

Pág 26 Imagem 2

 

Capítulo 1 – História da Java

A linguagem de programação Java foi criada em 1991 por James Gosling, ela iniciou-se como parte do projeto Green da Sun Microsystems. Inicialmente a linguagem iria chamar-se Oak (Carvalho) em referência a árvore que era visível pela janela de James Gosling. A mudança de nome ocorreu, pois já existia uma linguagem de programação com este nome, então a linguagem foi rebatizada para Java. O termo Java é utilizado, geralmente, quando nos referimos a:

  • Linguagem de programação orientada a objetos;
  • Ambiente de desenvolvimento composto pelo compilador, interpretador, gerador de documentação e etc.;
  • Ambiente de execução que pode ser praticamente qualquer máquina que possua Java Runtime Environment (JRE) instalado;

A linguagem de programação Java é uma linguagem de alto-nível com as seguintes características:

  • Simples: O aprendizado da linguagem de programação Java pode ser feito em um curto período de tempo;
  • Orientada a objetos: Desde o início do seu desenvolvimento esta linguagem foi projetada para ser orientada a objetos;
  • Familiar: A linguagem Java é muito familiar para os programadores C/C++++;
  • Robusta: Ela foi pensada para o desenvolvimento de softwares confiáveis, provendo verificações tanto em tempo de execução quanto compilação, o coletor de lixo responsabiliza-se pela limpeza da memória quando houver necessidade;
  • Segura: Aplicações Java são executadas em ambiente próprio (JRE) o que inviabiliza a intrusão de código malicioso;
  • Portável: Programas desenvolvidos nesta linguagem podem ser executados em praticamente qualquer máquina desde que esta possua o JRE instalado;

 

Fases de um programa Java

As fases pelo qual passam um programa Java relacionam-se da seguinte forma:

1.3

 

Máquina Virtual Java (JVM)

A máquina virtual Java (JVM) é uma máquina imaginária que emula uma aplicação em uma máquina real. É a JVM que permite a portabilidade do código Java, isto ocorre porque todo código Java é compilada para um formato intermediário, bytecode, este formato é então interpretado pela JVM. Existem diversas JVMs cada uma delas destinada a um tipo de sistema operacional (Windows, Linux, Mac e etc.), desta forma sendo o código da aplicação Java, bytecode, um código interpretado pela JVM, podemos desenvolver uma aplicação sem nos preocuparmos onde ela será executada, pois sabemos que existindo a JVM instalada nosso código será executável.

 

Hotspot

Hotspot é a máquina virtual Java, ela provê algumas funcionalidades muito importantes. Ao contrário de outras aplicações, que são compiladas diretamente para código da máquina em que serão executadas, em Java estas somente são transformadas em código de máquina em tempo de execução quando necessário. No princípio esta abordagem trouxe problemas de sobrecarga e lentidão dos sistemas, no entanto, a JVM vem se aprimorando e, em muitas situações, as aplicações Java tem desempenho similar às aplicações que são previamente compiladas.

 

 

Este desempenho vem melhorando muito devido à otimização que a máquina virtual consegue fazer à medida que o código é executado. Perceba que quando programamos em C, por exemplo, o código fonte é transformado em código de máquina imediatamente.

Em princípio podemos pensar que o fato do programa não precisar passar por uma etapa a mais, interpretação, irá torná-lo mais eficiente, mas muitas vezes a compilação estática não consegue prever situações que irão ocorrer durante a execução do código: trechos da aplicação mais utilizados, carga do sistema, quantidade de usuários simultâneos, memória disponível e etc.. Estas informações, relativas ao ambiente no qual a aplicação está sendo executada, são utilizadas pela JVM para fazer otimizações em tempo de execução e havendo necessidade o código que está sendo interpretado é transformado em instruções nativas do sistema operacional (código de máquina) em um processo de compilação dinâmica. Esta transformação em tempo de execução é realizada pelo JIT, Just-in-time compiler.

O fato do código (bytecode) ser transformado, em tempo de execução, em código de máquina permite que a JVM mude a estratégia de compilação em busca de um melhor desempenho, em um ciclo de “aprendizado” contínuo.

 

Coletor de Lixo – Garbage Collection

Muitas linguagens de programação nos permitem alocar espaço na memória em tempo de execução, uma vez encerrado o programa deve haver uma maneira de liberar este espaço para que outras aplicações possam utilizá-lo. Em muitas das linguagens de programação, inclusive C e C++, a responsabilidade pela liberação do espaço que não mais será utilizado é do programador, no entanto, nem sempre é fácil gerenciar o que está e o que não está sendo utilizado, a má gerência da memória ocasiona muitas vezes o estouro de pilha (stack overflow) entre outros problemas. Na linguagem de programação Java a responsabilidade pela gerência da memória é do Coletor de lixo (Garbage Collector), desta forma, programadores Java ficam livres da preocupação de alocação e desalocação da memória. O Coletor de lixo é um processo que roda em segundo plano e é responsável pela liberação de memória alocada por variáveis que não mais serão utilizadas pela aplicação.

 

 

JRE e JDK

  • JRE: O Java Runtime Environment contém tudo aquilo que um usuário comum precisa para executar uma aplicação Java (JVM e bibliotecas), como o próprio nome diz é o “Ambiente de execução Java”;
  • JDK: O Java Development Kit é composto pelo JRE e um conjunto de ferramentas úteis ao desenvolvedor Java.

 

Estrutura básica de um programa

O desenvolvimento de aplicações Java sempre é feito através de classes. A definição de uma classe Java deve respeitar a seguinte sintaxe:

1.2

Exemplo 1:

 

1.1

Princípios Básicos da Linguagem

  • Java é case-sensitive;
  • As classes, métodos ou blocos de código sempre estarão delimitados por um abrir ( { ) e fechar ( } ) de chaves;
  • Um comando deve sempre ser finalizado por um ponto e vírgula ( ; ) ;
  • Dois tipos de comentário: ( // ) Comentário de uma linha e ( /* ) Comentário de Várias ( */ );
  • Nomes de variáveis, classes e métodos devem sempre começar por letras, ( $ ) ou ( _ ).