• Nenhum resultado encontrado

aula11 projetoSistemas TopicosAdicionaisProjeto 2012.2

N/A
N/A
Protected

Academic year: 2021

Share "aula11 projetoSistemas TopicosAdicionaisProjeto 2012.2"

Copied!
45
0
0

Texto

(1)

Tópicos Adicionais em Projeto de

Sistemas

Projeto de Sistemas

(2)
(3)

Herança versus Composição

• Composição e herança são dois mecanismos para reutilizar funcionalidade

• Alguns anos atrás (e na cabeça de alguns programadores ainda!), a herança era considerada a ferramenta básica de extensão e

reutilização de funcionalidade

• A composição estende uma classe pela delegação de trabalho para outro objeto

• A herança estende atributos e métodos de uma classe

• Hoje, considera-se que a composição é muito superior à herança na maioria dos casos

(4)

Vantagens e Desvantagens

• As grandes vantagens da composição são:

– A herança gera um acoplamento muito forte. A

composição pode reduzir acoplamento, principalmente se interfaces forem usadas

– A composição pode ser mudada em tempo de execução

• A grande vantagem da herança é que ela gera código

mais simples de ler e entender

– A composição usa muitos objetos pequenos e só sabemos quem vai ser composto com quem em tempo de execução – Isso é mais difícil de entender

(5)

Quando usar composição

• Use composição para estender as responsabilidades pela

delegação de trabalho a outros objetos

• Um exemplo no domínio de endereços

– Uma empresa tem um endereço (digamos só um) – Uma empresa "tem" um endereço

– Podemos deixar o objeto empresa responsável pelo objeto endereço e temos agregação composta (composição)

(6)

Quando usar herança

• Atributos, conexões a objetos e métodos

comuns vão na superclasse (classe de

generalização)

• Adicionamos mais dessas coisas nas subclasses

(classes de especialização)

(7)

Um exemplo de herança

• Exemplo no domínio de

reserva e compra de

passagens de avião

• Uma transação é um

momento notável ou

intervalo de tempo

(8)

Benefícios da herança

• Captura o que é comum e o isola daquilo que

é diferente

• A herança é vista diretamente no código

• Código mais fácil de entender

(9)

Problemas da herança

• O encapsulamento entre classes e subclasses é fraco (o

acoplamento é forte)

– Mudar uma superclasse pode afetar todas as subclasses

• The weak base-class problem

– Isso viola um dos princípios básicos de projeto O-O (manter fraco acoplamento)

• Às vezes um objeto precisa ser de uma classe diferente em

momentos diferentes

– Com herança, a estrutura está parafusada no código e não pode sofrer alterações facilmente em tempo de execução

(10)

Um exemplo de problema da herança

• Problema: uma pessoa

pode mudar de papel a

assumir combinações de

papeis

• Fazer papeis múltiplos

requer 7 combinações

(subclasses)

(11)

Solucionando o problema com

composição

(12)

Solucionando o problema com

composição

• Estamos estendendo a funcionalidade de Pessoa de várias formas, mas sem usar herança.

• Observe que também podemos inverter a composição (uma pessoa tem um ou mais papeis). Pense na implicação para a interface de “pessoa”.

• Aqui, estamos usando delegação: dois objetos estão envolvidos em atender um pedido (setNome). O objeto tripulação delega

setNome para o objeto pessoa que ele tem por composição.

• Técnica também chamada de forwarding.

• É semelhante a uma subclasse delegar uma operação para a superclasse (herdando a operação).

(13)

Delegação sempre pode ser usada para

substituir a herança

• Se usássemos herança, o objeto tripulação poderia referenciar a pessoa com this

• Com o uso de delegação, tripulação pode passar this para Pessoa e o objeto Pessoa pode referenciar o objeto original se quiser

• Em vez de tripulação ser uma pessoa, ele tem uma pessoa

• A grande vantagem da delegação é que o comportamento pode ser escolhido em tempo de execução em vez de estar amarrado em tempo de compilação

• A grande desvantagem é que um software muito dinâmico e parametrizado é mais difícil de entender do que software mais estático

(14)

O resultado de usar composição

• Em vez de codificar um comportamento estaticamente,

definimos pequenos comportamentos padrão e usamos

composição para definir comportamentos mais complexos

• De forma geral, a composição é melhor do que herança

normalmente, pois:

– Permite mudar a associação entre classes em tempo de execução;

– Permite que um objeto assuma mais de um comportamento (ex. papel);

(15)

Cinco regras para o uso de herança

(Regras de Coad)

1. O objeto "é um tipo especial de" e não "um papel assumido por"

2. O objeto nunca tem que mudar para outra classe

3. A subclasse estende a superclasse mas não faz override ou anulação de variáveis e/ou métodos*

4. Não é uma subclasse de uma classe “utilitária”**

5. Para classes do domínio do problema, a subclasse expressa tipos especiais de papeis, transações ou dispositivos

(16)

** Não é uma subclasse de uma classe

"utilitária"

• Não é uma boa idéia fazer isso porque herdar de, digamos,

HashMap deixa a classe vulnerável a mudanças futuras à classe HashMap

• O objeto original não "é" um HashMap (mas pode usá-lo) • Não é uma boa idéia porque enfraquece o encapsulamento

– Clientes poderão supor que a classe é uma subclasse da classe utilitária e não funcionarão se a classe eventualmente mudar sua superclasse – Exemplo: x usa y que é subclasse de Vector

• x usa y sabendo que é um Vector

• Amanhã, y acaba sendo mudada para ser subclasse de HashMap • x se lasca!

(17)

Exemplo de aplicação das regras

• Considere Agente, Tripulação e Passageiro como

subclasses de Pessoa

– Regra 1 (tipo especial): não passa. Um Passageiro não é um tipo especial de Pessoa: é um papel assumido por uma Pessoa – Regra 2 (mutação): não passa. Um Agente pode se

transformar em Passageiro com o tempo – Regra 3 (só estende): ok.

– Regra 4: ok.

– Regra 5: não passa. Passageiro está sendo modelado como tipo especial de Pessoa e não como tipo especial de papel

(18)

Outro exemplo: transações

• Reserva e Compra podem herdar de Transação?

– Regra 1 (tipo especial): ok. Uma Reserva é um tipo especial de Transação e não um papel assumido por uma Transação

– Regra 2 (mutação): ok. Uma reserva sempre será uma Reserva, e nunca se transforma em Compra (se houver uma compra da

passagem, será outra transação). Idem para Compra: sempre será uma Compra

– Regra 3 (só estende): ok. Ambas as subclasses estendem Transação com novas variáveis e métodos e não fazem override ou anulam coisas de Transação

– Regra 4 (não estende classe utilitária): ok

– Regra 5 (tipo especial de papel/transação/dispositivo): ok. São tipos especiais de Transação

(19)

IMPLEMENTAÇÃO DE ASSOCIAÇÕES

(VISIBILIDADE DE OBJETOS)

(20)

Implementação de associações: exemplo

• De onde vem o cliente do pedido? Como

pedido ganha uma referência para um cliente?

• Pelo menos seis diferentes maneiras de ter

acesso a uma referência são possíveis

(Arthur Riel, Object-Oriented Design Heuristics)

(21)

Implementação de associações

• Atributos referenciais

– Passados como argumentos de construtores

– Construídos dentro da classe

– Obtidos de terceiros

– Combinando construtores e mutators

• Objetos temporários

– Passados como argumentos de métodos

– Criados on-the-fly dentro de um método

(22)

Atributos referenciais

• Atributo referencial: atributo de um objeto

que se refere a outro objeto, ainda que este

não esteja logicamente contido na classe que

mantém o atributo

(23)

Atributos referenciais: passados como

argumentos de construtores

• Ao construir um objeto, passe a referência já

existente do outro objeto como parâmetro do

construtor

• Depois, torne o parâmetro um atributo

referencial

• Esta situação assume que o outro objeto já

existe inicializado

(24)

Atributos referenciais: passados como

argumentos de construtores

public class SalesInvoice {

// --Constructors---public SalesInvoice( Customer soldTo )

{

this.soldTo = soldTo;

// Other initializations }

// Details omitted

// --Class and Object Attributes---private Customer soldTo;

(25)

Atributos referenciais: construídos dentro

da classe

• Ao comprar algo, você tem duas opções:

– Preenche uma solicitação de crédito e depois

preenche o pedido de compra;

– Preenche o pedido de compra e depois faz uma

verificação do crédito do cliente.

• No último caso, pode-se criar uma referência

ao cliente durante ou após a construção do

pedido.

(26)

Atributos referenciais: construídos dentro

da classe

public class SalesInvoice {

// --Constructors---public SalesInvoice( ... )

{

this.soldTo = new Customer(); // Other initializations

}

// Details omitted

// --Class and Object Attributes---private Customer soldTo;

(27)

Atributos referenciais: obtidos de

terceiros

• Há um repositório de objetos disponível

• Exemplo: localize um cliente pelo número do

cartão fidelidade (parâmetro)

• O parâmetro é usado para construir o objeto

pedido e dentro dele o objeto cliente

(28)

Atributos referenciais: obtidos de

terceiros

public class SalesInvoice {

// --Constructors---public SalesInvoice( int custNo, ... )

{

this.soldTo = CustomerDB.getCustomer(custNo); // Other initializations

}

// Details omitted

// --Class and Object Attributes---private Customer soldTo;

(29)

Atributos referenciais: combinando

construtores e mutators

• A solução anterior padece do problema de ainda ter

de fornecer um parâmetro (mesmo que seja só

numérico). O cliente tem de ser conhecido de

qualquer jeito.

• Solução:

– dê dois construtores a pedido, sendo que o construtor default pega um cliente default (cliente cash)

– crie um método mutator em Pedido que altera o cliente

(30)

Atributos referenciais: combinando

construtores e mutators

public class SalesInvoice { // =============================== // CONSTRUCTORS // =============================== public SalesInvoice( Customer

soldTo, Customer shipTo, SalesPerson soldBy, LineItems items ) { this.soldTo = soldTo; this.shipTo = shipTo; this.soldBy = soldBy; this.items = items; } public SalesInvoice( ) { this( Customer.getCustomer(0), null, new SalesPerson(), null);

this.items = new LineItems(5, this ); }

// Details omitted //

=================================== // CLASS AND OBJECT ATTRIBUTES

//

=================================== private Customer soldTo;

private Customer shipTo; private SalesPerson soldBy; private LineItems items; }

(31)

Objetos temporários

• Em algumas situações, você não quer que a

associação seja permanente

• Às vezes, um objeto pode ter um relacionamento

muito curto e transitório com outro objeto

• Pode ser necessário usar um objeto somente em um

só método, sem precisar guardar seu estado

• A solução é criar um objeto temporário (variável

local) para uso pela duração de um método

(32)

Objetos temporários: passados como

argumentos de métodos

• Uma primeira possibilidade seria passar o objeto

como argumento de um método. Isto é apropriado

quando:

– O estado do objeto não precisa ser retido entre duas chamadas do método

– O objeto carrega com ele informações de estado que têm de ser atualizadas cada vez que o método é chamado (por exemplo: public static void paint

(Graphics g))

– O objeto é construído facilmente fora de seu ambiente de classe)

(33)

Objetos temporários: criados on-the-fly

dentro de um método

• Vantagens em relação a passar como parâmetro:

– torna a chamada do método mais simples

SomeObject obj = new SomeObject(); obj.doSomeGraphicsThing();

em vez de:

SomeObject obj = new SomeObject(); Graphics g = obj.getGraphics(); obj.doSomeGraphicsThing( g );

– Torna o código mais fácil de manter

• Usado quando o objeto usuário tem conhecimento

especial que é requerido para criar o objeto que será

usado

(34)

Objetos temporários: criados on-the-fly

dentro de um método

public void doSomeGraphicsThing()

{

Graphics g = getGraphics();

g.setFont(...);

g.dispose();

}

(35)

Regras para o uso de objetos

• Use um atributo referencial quando:

– O objeto é usado em vários métodos diferentes ou o objeto armazena informação de estado persistente entre chamadas de métodos

– O objeto é usado repetidamente

– É muito custoso construir o objeto e você o utiliza mais de uma vez

• Passe um objeto como argumento de um método quando:

– O objeto será usado em um só método

– É fácil construir o objeto fora de sua classe (o objeto a ser usado traz informação suprida por quem chamou o método)

• Construa o objeto on-the-fly quando:

– o objeto será usado só naquele método

(36)

DETALHES ADICIONAIS SOBRE

(37)

Multiplicidade de atributos referenciais

[1..*]

(38)

Visibilidade de atributos e métodos

Person + name : String # address : Address # birthdate : Date ~ phone : String / age : Date - ssn : Id

Atributos e métodos podem ser: + public

# protected - private

~ default (package, friendly) / derived

(39)

Classe de Associação

• São classes produzidas quando da ocorrência

de associações que possuem multiplicidade

muitos (*) em ambas as extremidades.

• São necessárias nesses casos porque não

existe um repositório que possa armazenar as

informações produzidas pelas associações

(40)

Classe de Associação

Tournament Player * * Statistics + getAverageStat(name) + getTotalStat(name) + updateStats(match) Registration modelNumber serialNumber warrentyCode

(41)

Transformação de uma classe de

associação

Tournament Player

* *

Modelo de design antes da transformação

Modelo de design depois da transformação: 1 classe e 2 associações binárias Statistics + getAverageStat(name) + getTotalStat(name) + updateStats(match) Statistics + getAverageStat(name) + getTotalStat(name)

(42)

Associação qualificada

Modelo de design depois da transformação

Player nickName * 0..1 League Player * *

Modelo de design antes da transformação

League

nickName

(43)

Associação qualificada unidirecional

public class League {

private Map players;

public void addPlayer

(String nickName, Player p) {

if (! players.containsKey(nickName)) { players.put(nickName, p); p.addLeague(nickName, this); } } }

public class Player {

} Código-fonte depois da transformação

(44)

Associação qualificada bidirecional

public class League {

private Map players;

public void addPlayer

(String nickName, Player p) {

if (! players.containsKey(nickName)) { players.put(nickName, p); p.addLeague(nickName, this); } } }

public class Player { private Map leagues; public void addLeague

(String nickName, League l) {

if (!leagues.containsKey(l)) { leagues.put(l, nickName); l.addPlayer(nickName, this); } } } Código-fonte depois da transformação

(45)

Classe parametrizada (template)

LinkedList T add(T) remove(T) T 1 .. *

Uma classe parametrizada ou template define uma família de elementos

potenciais de outra classe.

Para usá-la, o parâmetro deve ser ligado (bound).

Um template é representado por um

pequeno retângulo tracejado superposto no canto superior direito do retângulo da classe. O retângulo tracejado contém uma lista dos parâmetros formais para a

Referências

Documentos relacionados

Quero ir com o avô Markus buscar a Boneca-Mais-Linda-do-Mundo, quero andar de trenó, comer maçãs assadas e pão escuro com geleia (17) de framboesa (18).... – Porque é tão

A espectrofotometria é uma técnica quantitativa e qualitativa, a qual se A espectrofotometria é uma técnica quantitativa e qualitativa, a qual se baseia no fato de que uma

Em assembly podem-se também usar valores imediatos como operandos das instruções, que são assim chamados por serem colocados na memória imediatamente a seguir à instrução em

Braverman, siguiendo a Taylor, enfatiza que el taylorismo puede aplicarse sobre cualquier base técnica dentro del sistema capitalista (BRAVERMAN, 1988, p. Resulta

Estos aspectos importantes que marcaron la vida de Clarín, estarán presentes en las actitudes de los personajes: Ana Ozores, es la primera analizada, pero

São estabelecidas condições gerais de aquisição e de outorga pela controlada Suzano Papel e Celulose de ‘ações fantasma’ a esses executivos (beneficiários), as quais

A dimensão média dos projectos é variável consoante a medida: é bastante menor nas Explorações Agrícolas (108 mil euros) e na Floresta (58 mil euros) do que na Transformação

Será sujeito passivo de uma obrigação acessória a pessoa indicada na norma como obrigada a realizar um fazer ou um não fazer em prol da administração ou da