• Nenhum resultado encontrado

Naked Objects

N/A
N/A
Protected

Academic year: 2022

Share "Naked Objects"

Copied!
131
0
0

Texto

(1)

Naked Objects

Introdução

Osvaldo Kotaro Takai João Eduardo Ferreira (takai,jef)@ime.usp.br

Mini-curso SBBD/SBES – out-2004

(2)

Completeza Comportamental

‡

As pessoas acham que estão usando a OO para projetar e desenvolver sistemas; mas não estão.

‡

Elas ignoram o princípio mais fundamental da OO que é a completeza comportamental:

„ um objeto deve modelar, por completo, o

comportamento das coisas que ele representa.

‡

A completeza comportamental é essencial porque ela é a chave para obter o principal benefício da orientação a objetos:

„ a habilidade de lidar com as mudanças inesperadas nos requisitos.

(3)

Separação dos Dados e Processos

‡

Ao invés disso, elas projetam sistemas que separam o

processo de seus dados, embora revestidos com

linguagens e tecnologias OO.

‡

A separação dos processos de seus dados pode estar

relacionada principalmente a inércia:

„ Isto é, as pessoas aprenderam a projetar sistemas dessa forma e têm dificuldades de pensar de outra maneira.

Objeto Dado

Objeto Processo

Objeto Inércia

(4)

Separação dos Dados e Processos

‡

A inércia individual é reforçada por práticas organizacionais que forçam a separação dos

processos de seus dados, mesmo que o projetista de software queira adotar uma abordagem mais pura de OO:

„ Orientação a processos de negócio.

„ Interfaces de usuário otimizadas a tarefas.

„ Métodos orientados a use-cases.

„ O padrão Model-View-Controller.

„ Desenvolvimento de software baseado em componentes.

Objeto Dado

Objeto Processo

Objeto Práticas Organizacionais

(5)

Separação dos Dados e Processos

‡

Essas cinco forças são consideradas as melhores práticas da OO.

‡

Não se pode simplesmente descartá-las, pois:

„ São práticas conscientes que claramente geram benefícios.

„ Foram projetadas para reduzir riscos conhecidos no processo de desenvolvimento.

‡

Porém, essas práticas provocam um efeito colateral:

„ desencorajam o projeto de objetos comportamentalmente completos.

(6)

Abordagem alternativa para projetar sistemas

‡

A alternativa é projetar sistemas que tratem os usuários como solucionadores de problemas.

‡

Muitos negócios já possuem alguns sistemas que são, por natureza, problemas a serem resolvidos.

„ Todos os programas de desenho, do PowerPoint aos sistemas CAD/CAE, são desse tipo, assim como as planilhas eletrônicas.

‡

No entanto, na maioria dos negócios, esses

sistemas não são considerados ‘tradicionais’.

(7)

Abordagem alternativa para projetar sistemas

‡

Os sistemas tradicionais estão normalmente

preocupados com o processamento padronizado das transações de negócio, e são otimizados para um conjunto de tarefas, os quais são quase

sempre implementados como processos

seqüenciais.

(8)

The Incredible Machine

‡

The Incredible Machine (www.sierra.com) é um grande exemplo de um sistema de problema a ser resolvido, e que claramente revela sua

estrutura orientada a objetos ao usuário.

(9)

The Incredible Machine

‡ É apresentado ao usuário um problema a ser resolvido – neste caso um balão de prata que tem que ser

estourado ...

(10)

The Incredible Machine

‡ ... usando algumas das

peças disponíveis (objetos), sendo que cada um

pode ser

inspecionado

para revelar suas propriedades

físicas e seus

comportamentos:

(11)

The Incredible Machine

‡ Inicialmente, nós usamos uma

almofada

antigravitacional e um bloco de madeira para desviar a bola sobre o êmbolo.

(12)

The Incredible Machine

‡ … a qual irá detonar o TNT por controle

remoto. Usando uma corda e duas polias e um

contrapeso, nós ligamos o balde tal que ele pegue a bola:

(13)

The Incredible Machine

‡ O contra-peso é um balde furado, e quando uma quantidade

suficiente de água vazar, o balde e a bola caem sobre a tesoura, liberando o balão, o qual irá estourar quando encostar no

alfinete acima:

(14)

As ‘melhores práticas’ no projeto de sistemas de negócio contemporâneos dividem uma aplicação em quatro camadas principais

Apresentação

Aplicação, Processo ou Controlador de Use-Case

Modelo de objetos de domínio

Persistência

(15)

Apresentação

Aplicação, Processo ou Controlador de Use-Case

Modelo de objetos de domínio

Persistência

O Padrão Naked Objects elimina a camada

controlador encapsulando todas as funcionalidades

de negócio nos objetos entidade

(16)

E tem uma camada de apresentação genérica que automaticamente reflete o modelo de objetos de domínio como uma interface de usuário orientada a objetos

Apresentação

Aplicação, Processo ou Controlador de Use-Case

Modelo de objetos de domínio

Persistência

(17)

Para um sistema standalone, ou para prototipação, é também possível autogerar a persistência a partir do

mesmo modelo de domínio

Presentation

Aplicação, Processo ou Controlador de Use-Case

Modelo de objetos de domínio

Persistência

(18)

Naked Objects

Introdução ao Framework

Naked Objects

(19)

O que é?

‡

O framework Naked Objects é uma pacote de

software open-source que facilita a construção

completa de aplicações de negócio a partir de

naked objects (objetos comportamentalmente

completos).

(20)

O que o pacote contém?

‡

Um conjunto de classes Java. A mais

importante classe desse conjunto é NakedObject, da qual você deriva subclasses para definir cada uma das classes de objetos de negócio (tal como Cliente). As outras classes do pacote fornecem funcionalidades a serem usadas dentro dos

objetos de negócio.

(21)

O que o pacote contém?

‡

Um ambiente de execução, que inclui:

„ Um mecanismo de visualização que cria, em tempo real, uma representação manipulável pelo usuário de qualquer naked object que o usuário precisar acessar.

„ Um mecanismo de persistência, o qual torna o naked objects persistente via uma classe de persistência específica. O

framework já vem com uma classe de persistência que armazena cada naked object como um arquivo XML. Isso é bom para realizar a prototipação rápida, mas não é escalável.

Classes de persistência mais sofisticadas devem ser escritas em sistemas reais.

(22)

O que o pacote contém?

‡

Ambos os mecanismos funcionam de forma

autônoma: eles usam um mecanismo comum de reflexão para inspecionar suas definições de

objetos de negócio quando necessários.

‡

O programador não precisa se preocupar

diretamente com os mecanismos de visualização ou de persistência.

‡

O ambiente de execução também fornece

interface entre os naked objects e outros serviços de infra-estrutura tais como para segurança e

autorização.

(23)

O que o pacote contém?

‡

Um conjunto de frameworks de teste. O framework de testes unitários é uma simples extensão do popular framework JUnit, tratando as capacidades específicas dos naked objects.

Existe um framework separado para testes de aceitação, o qual facilita a confecção dos testes de aceitação antes de escrever as funcionalidades (como defende a Extreme Programming). Como a maioria desses cenários de teste representam

tarefas comuns executadas pelos usuários, este

framework tem a vantagem adicional de poder

gerar a documentação do usuário dessas tarefas

diretamente a partir da definição dos testes.

(24)

O que é necessário para a execução?

‡

O Naked Objects precisa do Java versão 1.1 ou superior para a sua execução. Para desenvolver aplicações, será necessário uma IDE ou um JDK.

‡

Para executar exemplos, somente o JRE é necessário.

‡

É importante assegurar que o Java esteja instalado apropriadamente e que o seguinte

comando funcione (digite o comando abaixo na janela comandos do DOS):

„ java -version

(25)

O que é necessário para a execução?

‡

Após pressionar <enter>, os detalhes da versão Java deverá aparecer:

java version "1.4.1_02"

Java(TM) 2 Runtime Environment, Standard Edition (build 1.4.1_02-b06) Java HotSpot(TM) Client VM (build 1.4.1_02-b06, mixed mode)

‡

Se nada aparecer ou se uma mensagem de erro aparecer, então será necessário instalar ou

reinstalar o JDK adequado para o SO em uso.

(26)

O que é preciso baixar?

‡

Para executar um exemplo para ver como

trabalha uma aplicação Naked Objects, baixe o seguinte programa:

http://www.nakedobjects.org/downloads/ecs-demo.zip

‡

Para desenvolver uma aplicação Naked Objects, é necessário baixar o framework NakedObjects:

http://www.nakedobjects.org/downloads/nakedobjects1_0_2.zip

.

„ Desempacote o arquivo no diretório c:\

„ Para facilitar o desenvolvimento, é interessante utilizar algum ambiente de desenvolvimento Java. No caso, sugere-se o IDE Eclipse.

(27)

A idéia básica

‡

A tela a seguir exibe uma aplicação Naked Object típica em uso.

‡

É um sistema de declaração de despesas que permite aos empregados preparar e gerenciar a manutenção das despesas.

‡

Cada ícone da tela representa um objeto onde os

maiores, à esquerda, representam as classes ou

tipo de objetos disponíveis no sistema.

(28)

A idéia básica

(29)

A idéia básica

‡

As classes de objetos com as quais o usuário pode iniciar o trabalho (criar novas

instâncias, encontrar

instâncias existentes, etc.) é exibido na janela de classes.

‡

Cada ícone representa uma

classe.

(30)

A idéia básica

‡

Novas instâncias de um objeto podem ser criadas arrastando-se a classe para a área de trabalho.

‡

Ou através do menu pop-up acessado com o botão direito do

mouse.

(31)

A idéia básica

‡

Cada objeto criado está disponível ao usuário e quando exibidos aparecem na área

restante da

tela.

(32)

A idéia básica

‡

Cada objeto pode ser visualizado de formas diferentes – coleções pode ser visualizadas como tabelas e listas, Empregados como

formulários, etc.

Tabela Lista

Formulário Texto

(33)

A idéia básica

‡

Cada objeto de

negócio também tem um menu que é usado para acessar as

capacidades desse objeto.

‡

Esse menu pode ser acessado

pressionando-se o botão direito sobre o título do objeto.

Título

(34)

A idéia básica

‡

Os objetos de valor – texto, número, datas – que um objeto de negócio possui,

podem ser editados usando o teclado e o mouse.

Texto

Número (Moeda) Data

(35)

A idéia básica

‡

Os objetos de negócio podem também ser arrastados e soltos sobre outros objetos de

negócio ou dentro de campos que permitem esse

tipo de objeto (indicado em cor verde).

(36)

A idéia básica

‡

Para construir sistemas com base no Naked Objects, o importante é se concentrar nos

objetos de negócio – Cliente, Chamada, Pedido, Fatura, Vôo, Aeroporto, Avião, Equipe, etc. – e deixar a interface e persistência para o

framework.

‡

Esses objetos são definidos como classes Java seguindo um pequeno número de convenções de codificação.

‡

A implementação da interface é fornecida pelo

Naked Objects.

(37)

Exemplo 1

A idéia básica

(38)

Exemplo 1

‡

Vamos supor que temos a missão de construir uma aplicação que gerencie os papéis existentes em um projeto (Programador,

Analista, Líder de Projeto, etc.), bem como os

empregados que exercem esses papéis.

‡

O diagrama de classes em

UML é apresentado ao lado:

Empregadonom e

Projeto

nome criaLíder()

Papel

nome 0..*

0..1 0..*

0..1 0..*

0..*

0..*

0..*

Objetos da classe Projeto

referenciam objetos da classe Papel.

Objetos da classe Papel referenciam objetos da

classe Empregado.

(39)

Exemplo 1

‡

A aparência da

aplicação é exibida ao

lado:

(40)

Exemplo 1

‡

Posso criar um novo projeto (instância ou objeto da classe

Projeto),

simplesmente

arrastando-o para

uma área livre:

(41)

Exemplo 1

‡

Agora posso digitar o nome do projeto.

Vamos chamá-lo de

“River Fisher”.

River Fisher

(42)

Exemplo 1

‡

Com o cursor do

mouse sobre o objeto, agora chamado “River Fisher”, pressiono o botão direito do

mouse para visualizar

o menu pop-up.

River Fisher

(43)

Exemplo 1

‡

Seleciono a opção

“Criar Lider”, para criar um novo objeto da

classe Papel.

‡

Por default, essa opção irá, automaticamente, preencher o atributo Nome desse novo

objeto com a String:

“Líder de Projeto”.

River Fisher

(44)

Exemplo 1

‡

Quero agora associar um empregado ao

papel “Líder de Projeto”.

‡

Para isso, arrasto o ícone da classe

Empregado para o

campo Empregado do objeto Líder de Projeto

„ essa é uma forma

abreviada de criar um objeto.

„ Note que o campo fica esverdeado.

River Fisher

(45)

Exemplo 1

‡

Para dar um nome ao objeto Empregado

recém criado posso, dar um duplo-clique sobre o ícone do

objeto Empregado que aparece no campo

Empregado do objeto

“Líder de Projeto”.

‡

E então, digitar o nome: “Jef”.

River Fisher

(46)

Exemplo 1

‡

A fim de verificar se o objeto Jef foi de fato criado, basta

pressionar o botão

direito do mouse sobre o ícone da classe

Empregado e

selecionar a opção

Empregados do menu pop-up.

„ Isso fará com que todos os objetos pertencentes à classe Empregado

sejam mostrados.

River Fisher

(47)

Exemplo 1

‡

Antes de prosseguir, exercite este

exemplo no seu computador e assegure- se de que tenha entendido a metáfora da interface:

„

“arrastar e soltar”

„

bem como a forma de acessar o menu pop-up.

‡

Para tanto, execute o arquivo:

„

ExecutarExemplo1.bat

(48)

O Código da Classe Empregado

Exemplo 1

(49)

O Código da Classe Empregado

‡ Começando pelo mais simples, vamos criar a classe Empregado.

Empregado

nom e

Projeto

nome criaLíder()

Papel

nome 0..*

0..1 0..*

0..1 0..*

0..*

0..*

0..*

(50)

O Código da Classe Empregado

‡ A classe Empregado possui apenas um atributo: nome, supondo que isso seja o

suficiente para distinguí-lo.

‡ O código completo da classe Empregado que

utiliza o framework Naked Objects é exibido ao lado:

Empregado

nom e

importorg.nakedobjects.object.AbstractNakedObject;

importorg.nakedobjects.object.Title;

importorg.nakedobjects.object.value.TextString;

public classEmpregadoextendsAbstractNakedObject { private finalTextStringnome= newTextString();

publicTextString getNome() { returnnome;

}

publicTitle title() { returnnome.title();

} }

(51)

O Código da Classe Empregado

‡ A indicação de que a classe Empregado é um naked

object é realizada

estendendo-se a classe Empregado da classe AbstractNakedObject.

‡ A classe

AbstractNakedObject está definida no pacote

importado:

org.nakedobjects.object.AbstractNakedObject.

importorg.nakedobjects.object.AbstractNakedObject;

importorg.nakedobjects.object.Title;

importorg.nakedobjects.object.value.TextString;

public classEmpregado extendsAbstractNakedObject{ private finalTextString nome = newTextString();

publicTextString getNome() { returnnome;

}

publicTitle title() { returnnome.title();

} }

AbstractNakedObject

Empregado

nome

(52)

O Código da Classe Empregado

‡ O atributo nome é do tipo TextString e é utilizado para armazenar

informações textuais simples.

‡ A definição do tipo

TextString está definido no pacote:

org.nakedobjects.object.value.TextString.

‡ Note que todo atributo de um objeto naked object é exibido pela interface

gerada pelo framework Naked Object como um

campo, no caso Nome com N maiúsculo.

importorg.nakedobjects.object.AbstractNakedObject;

importorg.nakedobjects.object.Title;

importorg.nakedobjects.object.value.TextString;

public classEmpregado extendsAbstractNakedObject { private finalTextStringnome= newTextString();

publicTextString getNome() { returnnome;

}

publicTitle title() { returnnome.title();

} }

Atributo Campo

(53)

O Código da Classe Empregado

‡ O atributo nome é

declarado como private final para indicar que ele deve ser inicializado antes de ser usado e que não pode ser diretamente alterado.

‡ A alteração somente é permitida pela interface fornecida pelo Naked Objects.

importorg.nakedobjects.object.AbstractNakedObject;

importorg.nakedobjects.object.Title;

importorg.nakedobjects.object.value.TextString;

public classEmpregado extendsAbstractNakedObject { private finalTextStringnome= newTextString();

publicTextString getNome() { returnnome;

}

publicTitle title() { returnnome.title();

} }

Interface

(54)

O Código da Classe Empregado

‡ getNome() é um método public o qual permite que outras classes consultem o conteúdo do atributo

nome; no caso Jef.

importorg.nakedobjects.object.AbstractNakedObject;

importorg.nakedobjects.object.Title;

importorg.nakedobjects.object.value.TextString;

public classEmpregado extendsAbstractNakedObject { private finalTextStringnome= newTextString();

publicTextStringgetNome() { returnnome;

}

publicTitle title() { returnnome.title();

} }

(55)

O Código da Classe Empregado

‡ title() é um método public o qual permite que outras classes consultem o título do objeto.

‡ Neste exemplo, o título do objeto é igual ao valor do atributo nome convertido para o tipo Title, que no caso é Jef.

‡ Note que o método title retorna um objeto do tipo Title, o qual está

especificado em:

org.nakedobjects.object.Title.

importorg.nakedobjects.object.AbstractNakedObject;

importorg.nakedobjects.object.Title;

importorg.nakedobjects.object.value.TextString;

public classEmpregado extendsAbstractNakedObject { private finalTextStringnome= newTextString();

publicTextString getNome() { returnnome;

}

publicTitle title() { returnnome.title();

} }

Título

Conversão de TextString para Title Título

(56)

O Código da Classe Empregado

‡ Para poder testar (ou explorar) essa classe naked object, crie uma classe chamada Run

(poderia ter outro nome), como ilustra o código ao lado.

‡ Note que a classe Run

estende a classe do Naked Objects Exploration que está definida em:

org.nakedobjects.Exploration.

import org.nakedobjects.Exploration;

import org.nakedobjects.object.NakedClassList;

public class RunextendsExploration{ public static void main(String args[]) {

newRun();

}

public void classSet(NakedClassList classes) { classes.addClass(Empregado.class);

} }

(57)

O Código da Classe Empregado

‡ A classe Run possui um método chamado main;

isso indica ao JVM que o início da execução do programa começa nessa classe.

‡ Quando o método main é executado, ele cria uma instância de sua própria classe: um objeto Run.

import org.nakedobjects.Exploration;

import org.nakedobjects.object.NakedClassList;

public class RunextendsExploration { public static void main(String args[]) {

newRun();

}

public void classSet(NakedClassList classes) { classes.addClass(Empregado.class);

} }

(58)

O Código da Classe Empregado

‡ Agora que o objeto Run foi criado, o framework pode, então, chamar o método classSet, o qual adiciona a classe Empregado

(addClass) na lista de classes que será

disponibilizado ao usuário.

‡ No caso foi acrescentado apenas uma classe:

Empregado.

import org.nakedobjects.Exploration;

import org.nakedobjects.object.NakedClassList;

public class RunextendsExploration { public static void main(String args[]) {

newRun();

}

public void classSet(NakedClassList classes) { classes.addClass(Empregado.class);

} }

(59)

O Código da Classe Empregado

‡ Pode-se notar que, embora a classe se chame

Empregado, o nome apresentado na lista de classes é Empregados (plural).

„ O framework sempre faz isso.

„ Por default o framework adiciona

automaticamente um ‘s’

no final de todos os nomes de classe.

„ Veremos como mudar isso posteriormente.

import org.nakedobjects.Exploration;

import org.nakedobjects.object.NakedClassList;

public class RunextendsExploration { public static void main(String args[]) {

newRun();

}

public void classSet(NakedClassList classes) { classes.addClass(Empregado.class);

} }

Plural

Singular

(60)

O Código da Classe Empregado

‡ Copie o código da classe Empregado (ao lado) num arquivo com o nome

Empregado.java.

„ Para isso, utilize um editor de textos, por exemplo, o Noteped (Bloco de Notas).

„ O nome do arquivo tem que ser exatamente esse:

Empregado.java e não empregrado.java.

‡ Salve o arquivo

Empregado.java dentro de um diretório, por exemplo, c:\exemplo1.

import org.nakedobjects.object.AbstractNakedObject;

import org.nakedobjects.object.Title;

import org.nakedobjects.object.value.TextString;

public class Empregado extendsAbstractNakedObject {

private finalTextString nome = newTextString();

publicTextString getNome() { returnnome;

}

publicTitle title() { returnnome.title();

} }

(61)

O Código da Classe Empregado

‡ Faça o mesmo com a classe Run:

„ Copie o código da classe Run (ao lado) num arquivo com o nome Run.java.

„ E salve o arquivo Run.java dentro do mesmo diretório onde está

Empregado.java, por exemplo, c:\exemplo1.

import org.nakedobjects.Exploration;

import org.nakedobjects.object.NakedClassList;

public class RunextendsExploration { public static void main(String args[]) {

newRun();

}

public void classSet(NakedClassList classes) { classes.addClass(Empregado.class);

} }

(62)

O Código da Classe Empregado

‡ Crie agora um diretório chamado images.

(63)

O Código da Classe Empregado

‡ Copie do diretório generic- large-icons do framework Naked Objects, o arquivo CallCentreAgent32.gif.

(64)

O Código da Classe Empregado

‡ E cole o arquivo

CallCentreAgent32.gif no diretório images.

(65)

O Código da Classe Empregado

‡ Copie agora, do

diretório generic-small- icons, o arquivo

CallCentreAgent16.gif.

‡ E cole-o no diretório images.

(66)

O Código da Classe Empregado

‡

Renomeie os arquivos:

„ CallCentreAgent32.gif para Empregado32.gif

„ CallCentreAgent16.gif para Empregado16.gif

‡ Isso fará com que o framework associe os ícones à classe

Empregado.

(67)

O Código da Classe Empregado

‡

Para compilar, digite a seguinte linha de comando na janela DOS e pressione enter.

„ Isso irá gerar os arquivos:

‡ Empregado.class

‡ Run.class

(68)

O Código da Classe Empregado

‡ Para executar, digite a seguinte linha de comando e pressione enter.

(69)

O Código da Classe Empregado

‡ Após teclar enter, a capa do livro Naked Objects irá ser exibida e posteriormente, será apresentada a lista de classes contendo apenas a classe Empregado.

(70)

O Código da Classe Papel

Exemplo1

(71)

O Código da Classe Papel

‡ A classe Papel é criado e disponibilizado da mesma forma que a classe

Empregado.

‡ Vamos nos concentrar, portanto, em algumas diferenças, tal como a

associação da classe Papel com a classe Empregado.

Empregado

nom e

Projeto

nome criaLíder()

Papel

nome 0..*

0..1 0..*

0..1 0..*

0..*

0..*

0..*

Associação

(72)

O Código da Classe Papel

‡ Os objetos naked objects implementam a associação como um atributo que

referencia objetos de uma outra classe naked objects.

‡ No caso, a classe Papel terá que manter, no

máximo, uma referência à objetos da classe

Empregado (veja a multiplicidade: 0..1).

Multiplicidade

Empregado

nom e

Projeto

nome criaLíder()

Papel

nome 0..*

0..1 0..*

0..1 0..*

0..*

0..*

0..*

(73)

O Código da Classe Papel

‡ Assim, a associação é implementada como um atributo simples, o qual

pode armazenar uma única referência para um objeto da classe Empregado.

‡ Posteriormente, veremos como implementar

multiplicidades maiores que 1.

import org.nakedobjects.object.AbstractNakedObject;

import org.nakedobjects.object.Title;

import org.nakedobjects.object.value.TextString;

public class PapelextendsAbstractNakedObject { private finalTextString nome = newTextString();

privateEmpregadoempregado;

publicTextString getNome() { returnnome;

}

publicEmpregado getEmpregado() { resolve(empregado);

returnempregado;

}

public voidsetEmpregado(Empregado empregado) { this.empregado = empregado;

objectChanged();

}

publicTitle title() { returnnome.title();

} }

Associação

(74)

O Código da Classe Papel

‡ Como qualquer atributo de classe, o atributo

empregado não pode ser acessado diretamente.

‡ A única maneira de

acessar um atributo de classe deve ser através dos métodos de acesso denominados set e get.

‡ Assim:

„ getEmpregado() é

utilizado para consultar um objeto associado da classe Empregado.

„ setEmpregado() é

utilizado para alterar um objeto associado da classe Empregado.

import org.nakedobjects.object.AbstractNakedObject;

import org.nakedobjects.object.Title;

import org.nakedobjects.object.value.TextString;

public class Papel extendsAbstractNakedObject { private finalTextString nome = newTextString();

privateEmpregadoempregado;

publicTextString getNome() { returnnome;

}

publicEmpregado getEmpregado() { resolve(empregado);

returnempregado;

}

public voidsetEmpregado(Empregado empregado) { this.empregado = empregado;

objectChanged();

}

publicTitle title() { returnnome.title();

} }

(75)

O Código da Classe Papel

‡ O framework Naked Objects reconhece que getEmpregado e

setEmpregado são métodos de acesso vinculados ao

atributo empregado porque ele utiliza um mecanismo chamado reflexão.

‡ Assim, quaisquer métodos que possuam prefixos get e set serão considerados como métodos de acesso a algum atributo existente.

import org.nakedobjects.object.AbstractNakedObject;

import org.nakedobjects.object.Title;

import org.nakedobjects.object.value.TextString;

public class Papel extendsAbstractNakedObject { private finalTextString nome = newTextString();

privateEmpregadoempregado;

publicTextString getNome() { returnnome;

}

publicEmpregado getEmpregado() { resolve(empregado);

returnempregado;

}

public voidsetEmpregado(Empregado empregado) { this.empregado = empregado;

objectChanged();

}

publicTitle title() { returnnome.title();

} }

(76)

O Código da Classe Papel

‡ O método getEmpregado() é implementado

chamando o método resolve(empregado) do framework.

„ O método resolve

assegura que um objeto referenciado seja

recuperado corretamente do repositório de objetos.

„ Após o método resolve, carregar para a memória um objeto da classe

Empregado, referenciado pelo atributo empregado, essa referência é

retornada.

import org.nakedobjects.object.AbstractNakedObject;

import org.nakedobjects.object.Title;

import org.nakedobjects.object.value.TextString;

public class Papel extendsAbstractNakedObject { private finalTextString nome = newTextString();

privateEmpregadoempregado;

publicTextString getNome() { returnnome;

}

publicEmpregado getEmpregado() { resolve(empregado);

returnempregado;

}

public voidsetEmpregado(Empregado empregado) { this.empregado = empregado;

objectChanged();

}

publicTitle title() { returnnome.title();

} }

(77)

O Código da Classe Papel

‡ O método setEmpregado () é implementado:

„ Atualizando o atributo da classe Papel: empregado, com a referência passada pelo parâmetro

empregado.

„ Depois disso, o método objectChanged() do framework é chamado.

„ O método

objectChanged() informa aos mecanismos de

visualização e de

persistência que o status do objeto da classe Papel foi alterado.

import org.nakedobjects.object.AbstractNakedObject;

import org.nakedobjects.object.Title;

import org.nakedobjects.object.value.TextString;

public class Papel extendsAbstractNakedObject { private finalTextString nome = newTextString();

privateEmpregadoempregado;

publicTextString getNome() { returnnome;

}

publicEmpregado getEmpregado() { resolve(empregado);

returnempregado;

}

public voidsetEmpregado(Empregadoempregado) { this.empregado= empregado;

objectChanged();

}

publicTitle title() { returnnome.title();

} }

(78)

O Código da Classe Papel

‡ Copie o código da classe Papel (ao lado) num

arquivo com o nome Papel.java.

„ E salve esse arquivo dentro do mesmo diretório onde está Empregado.java e

Run.java foram salvos.

Por exemplo, c:\exemplo1.

import org.nakedobjects.object.AbstractNakedObject;

import org.nakedobjects.object.Title;

import org.nakedobjects.object.value.TextString;

public class Papel extendsAbstractNakedObject { private finalTextString nome = newTextString();

privateEmpregado empregado;

publicTextString getNome() { returnnome;

}

publicEmpregado getEmpregado() { resolve(empregado);

returnempregado;

}

public voidsetEmpregado(Empregado empregado) { this.empregado = empregado;

objectChanged();

}

publicTitle title() { returnnome.title();

} }

(79)

O Código da Classe Papel

‡ Modifique a classe Run, para que ela adicione a classe Papel na lista de classes.

import org.nakedobjects.Exploration;

import org.nakedobjects.object.NakedClassList;

public class RunextendsExploration { public static void main(String args[]) {

newRun();

}

public void classSet(NakedClassList classes) { classes.addClass(Empregado.class);

classes.addClass(Papel.class);

} }

Adicionado

(80)

O Código da Classe Papel

‡ Copie o arquivo Hammer16.gif e

Hammer32.gif para o diretório c:/Exemplo1/images.

(81)

O Código da Classe Papel

‡ Renomeie os arquivos:

„ Hammer16.gif para Papel16.gif

„ Hammer32.gif para Papel32.gif.

(82)

O Código da Classe Papel

‡ Compile:

‡ Execute:

(83)

O Código da Classe Papel

‡ Ao executar, a lista de classes ao lado irá ser exibida.

‡ Agora é possível criar

objetos da classe Papel e associá-los á objetos da classe empregado.

(84)

O Código da Classe Papel

‡ Uma coisa que está

incomodando é o nome da classe exibida na lista de ícones: Papels.

‡ Para corrigir esse problema, podemos informar ao framework qual é o plural correto de Papel, que no caso é

Papéis.

Nome da classe + ‘s’

(85)

import org.nakedobjects.object.AbstractNakedObject;

import org.nakedobjects.object.Title;

import org.nakedobjects.object.value.TextString;

public class Papel extendsAbstractNakedObject { private finalTextString nome = newTextString();

privateEmpregado empregado;

public staticString pluralName() { return"Papéis";

}

publicTextString getNome() { returnnome;

}

publicEmpregado getEmpregado() { resolve(empregado);

returnempregado;

}

public voidsetEmpregado(Empregado empregado) { this.empregado = empregado;

objectChanged();

}

publicTitle title() { returnnome.title();

} }

O Código da Classe Papel

‡ Para isso, acrescente o seguinte método

pluralName como ilustra código ao lado:

‡ Após compilar e executar novamente, a seguinte lista de ícones será

exibida:

Com o plural correto

(86)

O Código da Classe Projeto

Exemplo1

(87)

Código da classe Projeto

‡ A classe Projeto é criada e disponibilizada da mesma forma que as classes

Empregado e Papel.

‡ Vamos nos concentrar, portanto, em algumas diferenças, tal como a associação de

multiplicidade 0..* entre as classes Projeto e Papel, e na criação do método

criaLider exibida como uma das opções do menu pop-up.

Empregado

nom e

Projeto

nome criaLíder()

Papel

nome 0..*

0..1 0..*

0..1 0..*

0..*

0..*

0..*

Associação

Multiplicidade

(88)

Código da classe Projeto

‡ Para facilitar a visualização, as diretivas de

importação ao lado serão omitidas do código.

importjava.util.Enumeration;

importorg.nakedobjects.object.collection.InternalCollection;

importorg.nakedobjects.object.AbstractNakedObject;

importorg.nakedobjects.object.Title;

importorg.nakedobjects.object.control.About;

importorg.nakedobjects.object.control.ActionAbout;

importorg.nakedobjects.object.value.Case;

importorg.nakedobjects.object.value.TextString;

(89)

Código da classe Projeto

‡ A classe Projeto pode conter múltiplos objetos da classe Papel.

„ Para isso, o tipo

InternalCollection do framework foi utilizado.

‡ O tipo InternalCollection permite guardar uma

coleção de objetos de um tipo indicado.

„ Neste caso, o tipo indicado é a classe Papel.

„ A palavra this é também passada como

parâmetro para indicar que a classe Papel está contida nesta instância da classe Projeto.

public classProjeto extendsAbstractNakedObject { private finalTextString nome = newTextString();

private finalInternalCollectionpapeis = newInternalCollection(Papel.class, this);

publicTextString getNome() { returnnome;

}

publicInternalCollection getPapeis() { returnpapeis;

}

publicPapel actionCriaLider() {

Papel liderDeProjeto = (Papel) createInstance(Papel.class);

liderDeProjeto.getNome().setValue("Líder de Projeto");

papeis.add(liderDeProjeto);

returnliderDeProjeto;

}

publicAbout aboutActionCriaLider() { Enumeration e = getPapeis().elements();

while(e.hasMoreElements()) {

Papel role = (Papel) e.nextElement();

if(role.getNome().contains("líder de projeto", Case.INSENSITIVE)) { returnActionAbout.DISABLE;

} }

returnActionAbout.ENABLE;

}

publicTitle title() { returnnome.title();

} }

(90)

Código da classe Projeto

‡ Como qualquer atributo de classe, o atributo papeis é private final.

‡ Ele possui também um método get, permitindo que a coleção, com

referências a objetos da classe Papel, possa ser consultada pelo

framework utilizando o mecanismo de reflexão.

public classProjeto extendsAbstractNakedObject { private finalTextString nome = newTextString();

private finalInternalCollectionpapeis= newInternalCollection(Papel.class, this);

publicTextString getNome() { returnnome;

}

publicInternalCollectiongetPapeis() { returnpapeis;

}

publicPapel actionCriaLider() {

Papel liderDeProjeto = (Papel) createInstance(Papel.class);

liderDeProjeto.getNome().setValue("Líder de Projeto");

papeis.add(liderDeProjeto);

returnliderDeProjeto;

}

publicAbout aboutActionCriaLider() { Enumeration e = getPapeis().elements();

while(e.hasMoreElements()) {

Papel role = (Papel) e.nextElement();

if(role.getNome().contains("líder de projeto", Case.INSENSITIVE)) { returnActionAbout.DISABLE;

} }

returnActionAbout.ENABLE;

}

publicTitle title() { returnnome.title();

} } Lista de

objetos da classe

Papel

(91)

Código da classe Projeto

‡ Só para recordar, a opção Cria Lider deve estar

acessível pressionando-se o botão direito do mouse sobre o título de um objeto da classe Projeto.

‡ Ao selecionar essa opção, um novo objeto da classe Papel será criado

automaticamente com o campo Nome já

preenchido.

Campo nome preenchido automaticamente

(92)

Código da classe Projeto

‡ A opção Cria Lider é implementada através dos métodos de ação (action method).

‡ O framework adiciona uma opção no menu pop- up automaticamente para todo o método que

comece com a palavra actionCriaLider.

‡ Assim, quando o usuário seleciona a opção Cria Lider do menu pop-up, o método actionCriaLider é executado.

public classProjeto extendsAbstractNakedObject { private finalTextString nome = newTextString();

private finalInternalCollection papeis = newInternalCollection(Papel.class, this);

publicTextString getNome() { returnnome;

}

publicInternalCollection getPapeis() { returnpapeis;

}

publicPapel actionCriaLider() {

Papel liderDeProjeto = (Papel) createInstance(Papel.class);

liderDeProjeto.getNome().setValue("Líder de Projeto");

papeis.add(liderDeProjeto);

returnliderDeProjeto;

}

publicAbout aboutActionCriaLider() { Enumeration e = getPapeis().elements();

while(e.hasMoreElements()) {

Papel role = (Papel) e.nextElement();

if(role.getNome().contains("líder de projeto", Case.INSENSITIVE)) { returnActionAbout.DISABLE;

} }

returnActionAbout.ENABLE;

}

publicTitle title() { returnnome.title();

} }

(93)

Código da classe Projeto

‡ Quando o método actionCriaLider é

executado, ele cria uma nova instância da classe Papel através do método createInstance.

‡ Instâncias de classes

naked objects não devem ser criadas usando o

operador padrão new da linguagem Java – isso não irá inicializá-las apropriadamente.

public classProjeto extendsAbstractNakedObject { private finalTextString nome = newTextString();

private finalInternalCollection papeis = newInternalCollection(Papel.class, this);

publicTextString getNome() { returnnome;

}

publicInternalCollection getPapeis() { returnpapeis;

}

publicPapel actionCriaLider() {

PapelliderDeProjeto = (Papel) createInstance(Papel.class);

liderDeProjeto.getNome().setValue("Líder de Projeto");

papeis.add(liderDeProjeto);

returnliderDeProjeto;

}

publicAbout aboutActionCriaLider() { Enumeration e = getPapeis().elements();

while(e.hasMoreElements()) {

Papel role = (Papel) e.nextElement();

if(role.getNome().contains("líder de projeto", Case.INSENSITIVE)) { returnActionAbout.DISABLE;

} }

returnActionAbout.ENABLE;

}

publicTitle title() { returnnome.title();

} }

(94)

Código da classe Projeto

‡ A referência para a nova instância de classe Papel foi guardada na variável lideDeProjeto.

‡ O nome desse novo objeto é inicialmente obtido usando o método getNome.

‡ O método getNome

retorna o objeto da classe TextString, o qual define o método setValue.

‡ Enfim, o método setValue permite alterar o nome do novo objeto para “Líder de Projeto”.

public classProjeto extendsAbstractNakedObject { private finalTextString nome = newTextString();

private finalInternalCollection papeis = newInternalCollection(Papel.class, this);

publicTextString getNome() { returnnome;

}

publicInternalCollection getPapeis() { returnpapeis;

}

publicPapelactionCriaLider() {

PapelliderDeProjeto= (Papel) createInstance(Papel.class);

liderDeProjeto.getNome().setValue("Líder de Projeto");

papeis.add(liderDeProjeto);

returnliderDeProjeto;

}

publicAbout aboutActionCriaLider() { Enumeration e = getPapeis().elements();

while(e.hasMoreElements()) {

Papel role = (Papel) e.nextElement();

if(role.getNome().contains("líder de projeto", Case.INSENSITIVE)) { returnActionAbout.DISABLE;

} }

returnActionAbout.ENABLE;

}

publicTitle title() { returnnome.title();

} }

(95)

Código da classe Projeto

‡ O objeto da classe Papel, recém criado, com o

nome “Líder de Projeto” é adicionado à coleção de papeis associados ao objeto da classe Projeto.

‡ No final, o objeto liderDeProjeto é retornado.

public classProjeto extendsAbstractNakedObject { private finalTextString nome = newTextString();

private finalInternalCollectionpapeis= newInternalCollection(Papel.class, this);

publicTextString getNome() { returnnome;

}

publicInternalCollection getPapeis() { returnpapeis;

}

publicPapelactionCriaLider() {

PapelliderDeProjeto= (Papel) createInstance(Papel.class);

liderDeProjeto.getNome().setValue("Líder de Projeto");

papeis.add(liderDeProjeto);

returnliderDeProjeto;

}

publicAbout aboutActionCriaLider() { Enumeration e = getPapeis().elements();

while(e.hasMoreElements()) {

Papel role = (Papel) e.nextElement();

if(role.getNome().contains("líder de projeto", Case.INSENSITIVE)) { returnActionAbout.DISABLE;

} }

returnActionAbout.ENABLE;

}

publicTitle title() { returnnome.title();

} }

Referências

Documentos relacionados

Verificou-se nas análises que, a exceção da água consumida na escola, todas as amostras analisadas indicaram presença de coliformes fecais, o que potencializa a não conformidade

Fig.1- Água Balnear – Quinta do Barco - Local de monitorização da qualidade água (seta amarela)... 4/7 1.1_Perfil Quinta do Barco 5 – Identificação de

Os resultados dos testes foram mapas de velocidade do vento para a área de estudo (Ferreira e Assis, 2010), os quais foram utilizados para comparação com a simulação física e

SD QPCBM FEM CATIA SOLANGE MACIEL DE CASTRO SD QPCBM ROONEI HEARLE PICANÇO BACELAR SD QPCBM EDIVALDO ALMEIDA DA SILVA SD QPCBM FEM DÉBORA MACIEL MARQUES SD QPCBM

4.3.1 Os candidatos considerados habilitados na fase de análise curricular serão submetidos à avaliação de habilidades por meio de dinâmica de grupo ou

O pagamento deverá ser efetuado no setor financeiro da Escola, no prazo de 48h antes da realização da prova de Recuperação Paralela impreterivelmente, para melhor planejamento

A abertura de vagas de estágios nas empresas do setor eletro-eletrônico, instaladas na Zona Franca de Manaus-AM, que passaram a responder pela maior parte dos estágios na área

A partir deste resultado, a empresa então teve condições de analisar as causas do problema e partir para melhorias buscando sua solução, além de tomar a decisão