MAC 441/5714 - Programação Orientada a Objetos
Aula 21 - 5/6/2005
Padrões Prototype, Factory Method e Flyweight do GoF
- vimos em aula, falta incluir detalhes aqui.
Sependências em Smalltalk
- Um programa OO é formado por muitos objetos. Em muitos
casos, há relações de dependência, em tempo
de execução, entre alguns desses objetos. Ou seja, o
comportamento de um objeto depende de mudanças que ocorrem em
outros objetos.
- Exemplo: um mostrador de relógio que depende do
relógio interno da máquina ou um mostrador de temperatura
que depende da temperatura captada por um sensor ou um alarme (via
email) que depende do estouro da quota de disco de um usuário.
- A classe Object de Smalltalk contém todo o suporte para
gerenciamento de dependências deste tipo. Portanto, qualquer
objeto Smalltalk pode declarar-se dependente de outros objetos e
receber notificações sobre mudanças nos objetos
nos quais ele depende.
- Forma mais básica:
- definição/remoção de uma
dependência
- objetoA addDependent: objetoB
- objetoA removeDependent: objetoB
- objetoA release "remove todos os dependentes"
- notificação
- objetoA changed
- objetoA changed: anAspect
- os métodos changed desencadeiam os seguintes
métodos nos dependentes
- objetoB update
- objetoB update: anAspect
- broadcast (difusão) (só no VisualWorks) (exercício: implementar no Squeak)
- objetoA broadcast: aMessage
- objetoA broadcast: aMessage
with: aParameter
- usa a primitiva
perform:with:
- envia uma mensagem para todos os dependentes; note que isso
só é possível pois em Smalltalk mensagens
são objetos de primeira classe
- expressão de interesse específico
- através do mecanismo que vimos até agora, o objetoB recebe
notificações sobre qualquer tipo de
mudança no objetoA
mas pode ser que ele só esteja
interessado em algum tipo específico de mudança; neste
caso usamos o seguinte
- objetoA
expressInterestIn: anAspect for: objetoB sendBack: aSelector
- quando o aspecto anAspect
do objetoA mudar, ele
enviará a mensagem aSelector
para o objetoB
- veja no VisualWorks a implementação desta
mensagem como é interessante:
- Object>>expressInterestIn:
anAspect for: anObject sendBack: aSelector
"Arrange
for anObject to receive a message named aSelector when
I
signal that my attribute anAspect has changed."
|
dt deps |
dt
:= DependencyTransformer new.
"funciona como um proxy"
dt
setReceiver: anObject
aspect: anAspect
selector: aSelector.
deps
:= self myDependents.
(deps
class == DependentsCollection
ifTrue: [deps includes: dt]
ifFalse: [deps = dt]) ifTrue:
[^self].
self
addDependent: dt
Padrão Observer (293) do
GoF
- Objetivo: definir uma relação de dependência
1-para-muitos entre objetos de forma que quando o estado de 1 objeto
muda, todos os seus dependentes são notificados
- Motivação: um efeito colateral de quebrarmos um
sistema grande em vários objetos menores é que muitas
vezes precisamos manter a consistência entre os estados de
objetos relacionados. Por outro lado, não queremos garantir a
consistência tornando estes objetos fortemente acoplados,
queremos mantê-los desacoplados. Portanto, estabelecemos a
relação de dependência de uma forma bem
genérica de forma que o código das classes se
mantém bem independente.
- Exemplo: num editor gráfico de UML, ao movermos as caixas
de um lado para outro, as flechas que as conectam também se
movem.
- Aplicabilidade:
- quando uma abstração possui 2 aspectos, separando
estes aspectos em objetos diferentes permite que você os varie e
reuse independentemente;
- quando uma mudança em um objeto exige mudanças em
outros e você não sabe quantos outros objetos
precisarão mudar;
- quando um objeto precisa notificar outros objetos sem
conhecimento a priori sobre quem são estes objetos.
- Estrutura: ver GoF
- Em Smalltalk toda essa estrutura está potencialmente
embutida em qualquer objeto.
Referências
- Conhecendo o Smalltalk. Abdala e Wangenheim. Cap. 9 Mecanismo de Dependência.
- GoF (para Prototype, Flyweight, Factory Method e Observer)
Página de MAC
441/5714
Página do Fabio
Página do DCC