Adaptive Programming – Part 6


Início
Continuação da parte 5.

Adaptive Programming

Vamos fazer agora algumas modificações radicais no código para gerar os programas associados a determinadas funcionalidades. Para o “traversal” vamos nos inspirar no pattern Walkabout (The Essence of the Visitor Pattern, By Jens Palsberg and C. Barry Jay). Para especificar a funcionalidade vamo criar a classe Operation.

Operations

A classe Operation conterá as especificações suficientes para as funcionalidades. Vamos exemplificar inicialmente com a funcionalidade associada ao método #todosEmpregados.

Nota: O código visitor result add: visited viola a Lei de Demeter. Mas como em toda lei há exceções aqui a violação é válida. Como o visitor tem a propriedade result que sabidamente foi inicializada com uma OrderedCollection que aceita a mensagem #add: e o objetivo é conhecer bem o objeto temporário em result a violação não impacta a manutenção do resto do código.

operation acima gera o método entry point na classe Empresa:

O método #visit:, de OperationVisitor, providencia o traversal da estrutura:

Para que o código acima encare o traversal de collections da mesma forma que o traversal dos objetos das classes do modelo passamos a utilizar as classes abaixo em lugar das collections da biblioteca do Smalltalk:

List:

'From Pharo1.3 of 16 June 2011 [Latest update: #13328] on 29 June 2012 at 8:05:51 am'!
AdaptiveBase subclass: #List
instanceVariableNames: ''
classVariableNames: ''
poolDictionaries: ''
category: 'AdaptiveProgrammingBlogPost-Examples'!

!List methodsFor: 'as yet unclassified' stamp: 'FranciscoAryMartins 6/23/2012 19:20'!
add: anElement
^ NonEmptyList first: anElement rest: self! !

"-- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- "!

List class
instanceVariableNames: ''!

NonEmptyList:

'From Pharo1.3 of 16 June 2011 [Latest update: #13328] on 29 June 2012 at 8:06:02 am'!
List subclass: #NonEmptyList
instanceVariableNames: 'head tail'
classVariableNames: ''
poolDictionaries: ''
category: 'AdaptiveProgrammingBlogPost-Examples'!

!NonEmptyList methodsFor: 'as yet unclassified' stamp: 'FranciscoAryMartins 6/25/2012 13:13'!
append: anElement
^ NonEmptyList first: head rest: (tail append: anElement)! !

!NonEmptyList methodsFor: 'as yet unclassified' stamp: 'FranciscoAryMartins 6/25/2012 13:13'!
do: aBlockClosure
aBlockClosure value: head.
tail do: aBlockClosure ! !

!NonEmptyList methodsFor: 'as yet unclassified' stamp: 'FranciscoAryMartins 6/25/2012 13:13'!
head
^ head! !

!NonEmptyList methodsFor: 'as yet unclassified' stamp: 'FranciscoAryMartins 6/25/2012 13:14'!
head: anElement
head := anElement! !

!NonEmptyList methodsFor: 'as yet unclassified' stamp: 'FranciscoAryMartins 6/23/2012 20:39'!
select: aBlockClosure
| newCollection |
newCollection := EmptyList new.
self do: [:each | (aBlockClosure value: each) ifTrue: [newCollection := newCollection add: each]].
^newCollection! !

!NonEmptyList methodsFor: 'as yet unclassified' stamp: 'FranciscoAryMartins 6/25/2012 13:19'!
tail: anEmptyList
tail := anEmptyList! !

!NonEmptyList methodsFor: 'accessing' stamp: 'FranciscoAryMartins 6/25/2012 16:58'!
tail
^ tail! !

"-- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- "!

NonEmptyList class
instanceVariableNames: ''!

!NonEmptyList class methodsFor: 'as yet unclassified' stamp: 'FranciscoAryMartins 6/25/2012 13:19'!
first: anElement rest: aList
^ self new
head: anElement;
tail: aList! !

EmptyList:

'From Pharo1.3 of 16 June 2011 [Latest update: #13328] on 29 June 2012 at 8:05:59 am'!
List subclass: #EmptyList
instanceVariableNames: ''
classVariableNames: ''
poolDictionaries: ''
category: 'AdaptiveProgrammingBlogPost-Examples'!

!EmptyList methodsFor: 'as yet unclassified' stamp: 'FranciscoAryMartins 6/23/2012 19:44'!
append: anElement
^ NonEmptyList first: anElement rest: self! !

!EmptyList methodsFor: 'as yet unclassified' stamp: 'FranciscoAryMartins 6/23/2012 19:39'!
do: aBlockClosure ! !

!EmptyList methodsFor: 'as yet unclassified' stamp: 'FranciscoAryMartins 6/23/2012 20:31'!
select: aBlockClosure ! !

"-- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- "!

EmptyList class
instanceVariableNames: ''!

Agora toda a programação de funcionalidades se resume a criar e compilar operations e depois usar os entry points gerados. Vamos mostrar abaixo as outras operações:

O método #nomesEmpregados gerado é similar:

Abaixo mostraremos somente as operações para as funcionalidades restantes:

Abaixo segue o file-out até agora:

Object subclass: #Visitor
instanceVariableNames: 'result'
classVariableNames: ''
poolDictionaries: ''
category: 'AdaptiveProgrammingBlogPost-Examples'!

!Visitor methodsFor: 'accessing' stamp: 'FranciscoAryMartins 6/21/2012 08:19'!
result
^ result! !

!Visitor methodsFor: 'accessing' stamp: 'FranciscoAryMartins 6/21/2012 08:19'!
result: anObject
result := anObject! !

"-- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- "!

Visitor class
instanceVariableNames: ''!

!Visitor class methodsFor: 'as yet unclassified' stamp: 'FranciscoAryMartins 6/21/2012 18:48'!
result: anObject
^ self new result: anObject.! !

Visitor subclass: #NomesEmpregadosVisitor
instanceVariableNames: ''
classVariableNames: ''
poolDictionaries: ''
category: 'AdaptiveProgrammingBlogPost-Examples'!

!NomesEmpregadosVisitor methodsFor: 'as yet unclassified' stamp: 'FranciscoAryMartins 6/21/2012 08:26'!
visitDepartamento: umDepartamento
umDepartamento empregados do: [:each| each acceptVisitor: self].
umDepartamento divisoes do: [:each| each acceptVisitor: self] ! !

!NomesEmpregadosVisitor methodsFor: 'as yet unclassified' stamp: 'FranciscoAryMartins 6/22/2012 07:52'!
visitDivisao: umaDivisao
umaDivisao empregados do: [:each| each acceptVisitor: self]! !

!NomesEmpregadosVisitor methodsFor: 'as yet unclassified' stamp: 'FranciscoAryMartins 6/21/2012 08:26'!
visitEmpregado: umEmpregado
result add: umEmpregado nome! !

!NomesEmpregadosVisitor methodsFor: 'as yet unclassified' stamp: 'FranciscoAryMartins 6/21/2012 08:26'!
visitEmpresa: umaEmpresa
umaEmpresa departamentos do: [:each| each acceptVisitor: self]! !

Visitor subclass: #NumeroEmpregadosVisitor
instanceVariableNames: ''
classVariableNames: ''
poolDictionaries: ''
category: 'AdaptiveProgrammingBlogPost-Examples'!

!NumeroEmpregadosVisitor methodsFor: 'as yet unclassified' stamp: 'FranciscoAryMartins 6/21/2012 21:59'!
visitDepartamento: umDepartamento
umDepartamento empregados do: [:each| each acceptVisitor: self].
umDepartamento divisoes do: [:each| each acceptVisitor: self] ! !

!NumeroEmpregadosVisitor methodsFor: 'as yet unclassified' stamp: 'FranciscoAryMartins 6/22/2012 07:52'!
visitDivisao: umaDivisao
umaDivisao empregados do: [:each| each acceptVisitor: self]! !

!NumeroEmpregadosVisitor methodsFor: 'as yet unclassified' stamp: 'FranciscoAryMartins 6/21/2012 22:00'!
visitEmpregado: umEmpregado
result value: result value + 1! !

!NumeroEmpregadosVisitor methodsFor: 'as yet unclassified' stamp: 'FranciscoAryMartins 6/21/2012 21:59'!
visitEmpresa: umaEmpresa
umaEmpresa departamentos do: [:each| each acceptVisitor: self]! !

Object subclass: #Aplicacao
instanceVariableNames: 'empresa'
classVariableNames: ''
poolDictionaries: ''
category: 'AdaptiveProgrammingBlogPost-Examples'!

!Aplicacao methodsFor: 'as yet unclassified' stamp: 'FranciscoAryMartins 6/26/2012 14:10'!
initialize
empresa := Empresa nome: 'ABC Ltda.'..

((Operation
signature: #todosEmpregados
result: OrderedCollection new
from: Empresa
to: Empregado)
addWrapperTo: Empregado
withPrefix: [:visitor :visited|
visitor result add: visited
]
) compile.

((Operation
signature: #nomesEmpregados
result: OrderedCollection new
from: Empresa
to: Empregado)
addWrapperTo: Empregado
withPrefix: [:visitor :visited|
visitor result add: visited nome
]
) compile.

((Operation
signature: #numeroEmpregados
result: (Accumulator value: 0)
from: Empresa
to: Empregado)
addWrapperTo: Empregado
withPrefix: [:visitor :visited|
visitor result value: visitor result value + 1
]
) compile.

((Operation
signature: #empregadosSalarioMaiorQue:
result: (OrderedCollection new)
from: Empresa
to: Empregado)
addWrapperTo: Empregado
withPrefix: [:visitor :visited|
visited salario > visitor arguments first ifTrue: [visitor result add: visited]
]
) compile.

((Operation
signature: #somaSalariosEmpregados
result: (Accumulator value: 0)
from: Empresa
to: Empregado)
addWrapperTo: Empregado
withPrefix: [:visitor :visited|
visitor result value: visitor result value + visited salario
]
) compile.

((Operation
signature: #empregadoComMaiorSalario
result: (Accumulator value: nil)
from: Empresa
to: Empregado)
addWrapperTo: Empregado
withPrefix: [:visitor :visited|
(visitor result value = nil or: [visited salario > visitor result value salario]) ifTrue: [visitor result: visited]
]
) compile.
! !

!Aplicacao methodsFor: 'as yet unclassified' stamp: 'FranciscoAryMartins 6/26/2012 14:39'!
listarEmpregadoComMaiorSalario
| empregado |
Transcript cr; show: 'Empregado com maior salário:'.
empregado := empresa empregadoComMaiorSalario.
Transcript tab; show: empregado matricula; space; show: empregado nome; space; show: empregado salario.! !

!Aplicacao methodsFor: 'as yet unclassified' stamp: 'FranciscoAryMartins 6/25/2012 20:33'!
listarEmpregados
| empregados |
Transcript cr; show: 'Empregados:'.
empregados := empresa todosEmpregados.
empregados do: [:empregado|
Transcript cr; tab; show: empregado matricula; space; show: empregado nome; space; show: empregado salario.
]! !

!Aplicacao methodsFor: 'as yet unclassified' stamp: 'FranciscoAryMartins 6/26/2012 07:48'!
listarEmpregadosComSalariosAltos
| empregados |
Transcript cr; show: 'Empregados com salarios altos:'.
empregados := empresa empregadosSalarioMaiorQue: 7000.
empregados do: [:empregado|
Transcript cr; tab; show: empregado matricula; space; show: empregado nome; space; show: empregado salario.
]! !

!Aplicacao methodsFor: 'as yet unclassified' stamp: 'FranciscoAryMartins 6/14/2012 07:57'!
listarEmpregadosdoDepartamento: dep
Transcript
cr;
show: 'Empregados:'.
dep empregados
do: [ :empregado |
Transcript
cr;
tab;
show: empregado matricula;
space;
show: empregado nome;
space;
show: empregado salario ]! !

!Aplicacao methodsFor: 'as yet unclassified' stamp: 'FranciscoAryMartins 6/25/2012 20:34'!
listarNomesEmpregados
| nomes |
Transcript cr; show: 'Nomes de empregados:'.
nomes := empresa nomesEmpregados.
nomes do: [:each|
Transcript space; show: each
]! !

!Aplicacao methodsFor: 'as yet unclassified' stamp: 'FranciscoAryMartins 6/25/2012 20:35'!
listarNumeroEmpregados
Transcript cr; show: 'Número de empregados: ', empresa numeroEmpregados asString.
! !

!Aplicacao methodsFor: 'as yet unclassified' stamp: 'FranciscoAryMartins 6/26/2012 09:36'!
listarSomaSalariosEmpregados
Transcript cr; show: 'Soma dos salários dos empregados: ', empresa somaSalariosEmpregados asString.! !

!Aplicacao methodsFor: 'as yet unclassified' stamp: 'FranciscoAryMartins 6/26/2012 14:07'!
run
Transcript clear.
self listarEmpregados.
self listarNomesEmpregados.
self listarNumeroEmpregados.
self listarEmpregadosComSalariosAltos.
self listarSomaSalariosEmpregados.
self listarEmpregadoComMaiorSalario! !

"-- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- "!

Aplicacao class
instanceVariableNames: ''!

Object subclass: #AdaptiveBase
instanceVariableNames: ''
classVariableNames: ''
poolDictionaries: ''
category: 'AdaptiveProgrammingBlogPost-Examples'!

!AdaptiveBase methodsFor: 'as yet unclassified' stamp: 'FranciscoAryMartins 6/23/2012 08:32'!
accept: aVisitor
aVisitor visit: self! !

AdaptiveBase subclass: #Departamento
instanceVariableNames: 'nome empregados divisoes crudManager empregadosCrudManager divisoesCrudManager'
classVariableNames: ''
poolDictionaries: ''
category: 'AdaptiveProgrammingBlogPost-Examples'!

!Departamento methodsFor: 'as yet unclassified' stamp: 'FranciscoAryMartins 6/21/2012 08:10'!
acceptVisitor: aVisitor
aVisitor visitDepartamento: self! !

!Departamento methodsFor: 'as yet unclassified' stamp: 'FranciscoAryMartins 6/24/2012 08:48'!
adicionarDivisao: aDivisao
^ divisoes := divisoesCrudManager addElement: aDivisao ! !

!Departamento methodsFor: 'as yet unclassified' stamp: 'FranciscoAryMartins 6/24/2012 08:50'!
adicionarEmpregado: anEmpregado
^ empregados := empregadosCrudManager addElement: anEmpregado ! !

!Departamento methodsFor: 'as yet unclassified' stamp: 'FranciscoAryMartins 6/20/2012 10:19'!
empregadosSalarioMaiorQue: aSmallInteger
| result |
result := OrderedCollection new.
empregados do: [:each| result addAll: (each empregadosSalarioMaiorQue: aSmallInteger)].
divisoes do: [:each| result addAll: (each empregadosSalarioMaiorQue: aSmallInteger)].
^ result! !

!Departamento methodsFor: 'as yet unclassified' stamp: 'FranciscoAryMartins 6/23/2012 20:43'!
initialize
empregados := EmptyList new.
divisoes := EmptyList new.
empregadosCrudManager := CRUDManager collection: empregados idSelector: #matricula.
divisoesCrudManager := CRUDManager collection: divisoes idSelector: #nome.
! !

!Departamento methodsFor: 'as yet unclassified' stamp: 'FranciscoAryMartins 6/17/2012 19:48'!
listarDivisoes
self divisoes
do: [:divisao|
Transcript
space;
show: divisao nome
] ! !

!Departamento methodsFor: 'as yet unclassified' stamp: 'FranciscoAryMartins 6/18/2012 07:40'!
listarEmpregados
self empregados
do: [:empregado | Transcript cr; tab;
show: empregado matricula; space;
show: empregado nome; space;
show: empregado salario].
self divisoes do: [:divisao|
Transcript cr; show: 'Divisão: '; show: divisao nome.
divisao listarEmpregados]! !

!Departamento methodsFor: 'as yet unclassified' stamp: 'FranciscoAryMartins 6/19/2012 16:28'!
nomesEmpregados
| result |
result := OrderedCollection new.
empregados do: [:each| result addAll: each nomesEmpregados].
divisoes do: [:each| result addAll: each nomesEmpregados].
^ result! !

!Departamento methodsFor: 'as yet unclassified' stamp: 'FranciscoAryMartins 6/20/2012 07:03'!
numeroEmpregados
| result |
result := 0.
empregados do: [:each| result := result + each numeroEmpregados].
divisoes do: [:each| result := result + each numeroEmpregados].
^ result! !

!Departamento methodsFor: 'as yet unclassified' stamp: 'FranciscoAryMartins 6/25/2012 09:58'!
printOn: aStream
super printOn: aStream.
aStream nextPutAll: ': ', nome! !

!Departamento methodsFor: 'as yet unclassified' stamp: 'FranciscoAryMartins 6/18/2012 13:31'!
recuperarDivisaoNome: aByteString
^ divisoesCrudManager getElementById: aByteString! !

!Departamento methodsFor: 'as yet unclassified' stamp: 'FranciscoAryMartins 6/18/2012 13:27'!
recuperarEmpregadoMatricula: aSmallInteger
^ crudManager getElementById: aSmallInteger! !

!Departamento methodsFor: 'as yet unclassified' stamp: 'FranciscoAryMartins 6/18/2012 13:32'!
removerDivisaoNome: aString
^ divisoesCrudManager deleteElementById: aString! !

!Departamento methodsFor: 'as yet unclassified' stamp: 'FranciscoAryMartins 6/18/2012 13:32'!
removerEmpregadoMatricula: aSmallInteger
^ empregadosCrudManager deleteElementById: aSmallInteger! !

!Departamento methodsFor: 'as yet unclassified' stamp: 'FranciscoAryMartins 6/19/2012 07:47'!
todosEmpregados
| result |
result := OrderedCollection new.
empregados do: [:each| result addAll: each todosEmpregados].
divisoes do: [:each| result addAll: each todosEmpregados].
^ result! !

!Departamento methodsFor: 'accessing' stamp: 'FranciscoAryMartins 6/17/2012 19:33'!
divisoes
^ divisoes! !

!Departamento methodsFor: 'accessing' stamp: 'FranciscoAryMartins 6/14/2012 07:24'!
empregados
^ empregados! !

!Departamento methodsFor: 'accessing' stamp: 'FranciscoAryMartins 6/16/2012 09:23'!
nome
^ nome! !

!Departamento methodsFor: 'accessing' stamp: 'FranciscoAryMartins 6/16/2012 09:23'!
nome: anObject
nome := anObject! !

"-- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- "!

Departamento class
instanceVariableNames: ''!

!Departamento class methodsFor: 'as yet unclassified' stamp: 'FranciscoAryMartins 6/16/2012 09:26'!
nome: aString
^ self new nome: aString! !

AdaptiveBase subclass: #List
instanceVariableNames: ''
classVariableNames: ''
poolDictionaries: ''
category: 'AdaptiveProgrammingBlogPost-Examples'!

!List methodsFor: 'as yet unclassified' stamp: 'FranciscoAryMartins 6/23/2012 19:20'!
add: anElement
^ NonEmptyList first: anElement rest: self! !

List subclass: #NonEmptyList
instanceVariableNames: 'head tail'
classVariableNames: ''
poolDictionaries: ''
category: 'AdaptiveProgrammingBlogPost-Examples'!

!NonEmptyList methodsFor: 'as yet unclassified' stamp: 'FranciscoAryMartins 6/25/2012 13:13'!
append: anElement
^ NonEmptyList first: head rest: (tail append: anElement)! !

!NonEmptyList methodsFor: 'as yet unclassified' stamp: 'FranciscoAryMartins 6/25/2012 13:13'!
do: aBlockClosure
aBlockClosure value: head.
tail do: aBlockClosure ! !

!NonEmptyList methodsFor: 'as yet unclassified' stamp: 'FranciscoAryMartins 6/25/2012 13:13'!
head
^ head! !

!NonEmptyList methodsFor: 'as yet unclassified' stamp: 'FranciscoAryMartins 6/25/2012 13:14'!
head: anElement
head := anElement! !

!NonEmptyList methodsFor: 'as yet unclassified' stamp: 'FranciscoAryMartins 6/23/2012 20:39'!
select: aBlockClosure
| newCollection |
newCollection := EmptyList new.
self do: [:each | (aBlockClosure value: each) ifTrue: [newCollection := newCollection add: each]].
^newCollection! !

!NonEmptyList methodsFor: 'as yet unclassified' stamp: 'FranciscoAryMartins 6/25/2012 13:19'!
tail: anEmptyList
tail := anEmptyList! !

!NonEmptyList methodsFor: 'accessing' stamp: 'FranciscoAryMartins 6/25/2012 16:58'!
tail
^ tail! !

"-- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- "!

NonEmptyList class
instanceVariableNames: ''!

!NonEmptyList class methodsFor: 'as yet unclassified' stamp: 'FranciscoAryMartins 6/25/2012 13:19'!
first: anElement rest: aList
^ self new
head: anElement;
tail: aList! !

List subclass: #EmptyList
instanceVariableNames: ''
classVariableNames: ''
poolDictionaries: ''
category: 'AdaptiveProgrammingBlogPost-Examples'!

!EmptyList methodsFor: 'as yet unclassified' stamp: 'FranciscoAryMartins 6/23/2012 19:44'!
append: anElement
^ NonEmptyList first: anElement rest: self! !

!EmptyList methodsFor: 'as yet unclassified' stamp: 'FranciscoAryMartins 6/23/2012 19:39'!
do: aBlockClosure ! !

!EmptyList methodsFor: 'as yet unclassified' stamp: 'FranciscoAryMartins 6/23/2012 20:31'!
select: aBlockClosure ! !

AdaptiveBase subclass: #Empregado
instanceVariableNames: 'matricula nome salario'
classVariableNames: ''
poolDictionaries: ''
category: 'AdaptiveProgrammingBlogPost-Examples'!

!Empregado methodsFor: 'accessing' stamp: 'FranciscoAryMartins 6/14/2012 07:31'!
matricula
^ matricula! !

!Empregado methodsFor: 'accessing' stamp: 'FranciscoAryMartins 6/14/2012 07:31'!
matricula: anObject
matricula := anObject! !

!Empregado methodsFor: 'accessing' stamp: 'FranciscoAryMartins 6/14/2012 07:26'!
nome
^ nome! !

!Empregado methodsFor: 'accessing' stamp: 'FranciscoAryMartins 6/14/2012 07:26'!
nome: anObject
nome := anObject! !

!Empregado methodsFor: 'accessing' stamp: 'FranciscoAryMartins 6/14/2012 07:26'!
salario
^ salario! !

!Empregado methodsFor: 'accessing' stamp: 'FranciscoAryMartins 6/14/2012 07:26'!
salario: anObject
salario := anObject! !

!Empregado methodsFor: 'as yet unclassified' stamp: 'FranciscoAryMartins 6/21/2012 08:10'!
acceptVisitor: aVisitor
aVisitor visitEmpregado: self! !

!Empregado methodsFor: 'as yet unclassified' stamp: 'FranciscoAryMartins 6/20/2012 10:21'!
empregadosSalarioMaiorQue: aSmallInteger
| result |
result := OrderedCollection new.
(self salario > aSmallInteger) ifTrue: [result add: self].
^ result! !

!Empregado methodsFor: 'as yet unclassified' stamp: 'FranciscoAryMartins 6/19/2012 16:29'!
nomesEmpregados
| result |
result := OrderedCollection new.
result add: self nome.
^ result! !

!Empregado methodsFor: 'as yet unclassified' stamp: 'FranciscoAryMartins 6/20/2012 07:06'!
numeroEmpregados
| result |
result := 1.
^ result! !

!Empregado methodsFor: 'as yet unclassified' stamp: 'FranciscoAryMartins 6/25/2012 10:00'!
printOn: aStream
super printOn: aStream.
aStream nextPutAll: ': ', nome! !

!Empregado methodsFor: 'as yet unclassified' stamp: 'FranciscoAryMartins 6/19/2012 07:49'!
todosEmpregados
| result |
result := OrderedCollection new.
result add: self.
^ result! !

"-- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- "!

Empregado class
instanceVariableNames: 'proximaMatricula'!

!Empregado class methodsFor: 'as yet unclassified' stamp: 'FranciscoAryMartins 6/14/2012 07:56'!
initialize
"
self initialize
"
self reinicieMatriculas! !

!Empregado class methodsFor: 'as yet unclassified' stamp: 'FranciscoAryMartins 6/14/2012 07:32'!
matricula: anInteger nome: aString salario: aFloat
^ self new
matricula: anInteger;
nome: aString;
salario: aFloat ! !

!Empregado class methodsFor: 'as yet unclassified' stamp: 'FranciscoAryMartins 6/14/2012 07:28'!
nome: aString salario: aFloat
^ self new
nome: aString;
salario: aFloat ! !

!Empregado class methodsFor: 'as yet unclassified' stamp: 'FranciscoAryMartins 6/14/2012 07:37'!
proximaMatricula
proximaMatricula := proximaMatricula + 1.
^ proximaMatricula! !

!Empregado class methodsFor: 'as yet unclassified' stamp: 'FranciscoAryMartins 6/14/2012 07:55'!
reinicieMatriculas
proximaMatricula := 0..! !

!Empregado class methodsFor: 'as yet unclassified' stamp: 'FranciscoAryMartins 6/14/2012 21:26'!
ultimaMatricula
^ proximaMatricula! !

AdaptiveBase subclass: #Divisao
instanceVariableNames: 'nome empregados crudManager'
classVariableNames: ''
poolDictionaries: ''
category: 'AdaptiveProgrammingBlogPost-Examples'!

!Divisao methodsFor: 'as yet unclassified' stamp: 'FranciscoAryMartins 6/21/2012 08:10'!
acceptVisitor: aVisitor
aVisitor visitDivisao: self! !

!Divisao methodsFor: 'as yet unclassified' stamp: 'FranciscoAryMartins 6/24/2012 08:50'!
adicionarEmpregado: anEmpregado
^ empregados := crudManager addElement: anEmpregado ! !

!Divisao methodsFor: 'as yet unclassified' stamp: 'FranciscoAryMartins 6/20/2012 10:22'!
empregadosSalarioMaiorQue: aSmallInteger
| result |
result := OrderedCollection new.
empregados do: [:each| result addAll: (each empregadosSalarioMaiorQue: aSmallInteger)].
^ result! !

!Divisao methodsFor: 'as yet unclassified' stamp: 'FranciscoAryMartins 6/23/2012 20:02'!
initialize
empregados := EmptyList new.
crudManager := CRUDManager collection: empregados idSelector: #matricula.
! !

!Divisao methodsFor: 'as yet unclassified' stamp: 'FranciscoAryMartins 6/17/2012 19:30'!
listarEmpregados
self empregados
do: [ :empregado |
Transcript
cr;
tab;
show: empregado matricula;
space;
show: empregado nome;
space;
show: empregado salario ]! !

!Divisao methodsFor: 'as yet unclassified' stamp: 'FranciscoAryMartins 6/19/2012 16:30'!
nomesEmpregados
| result |
result := OrderedCollection new.
empregados do: [:each| result addAll: each nomesEmpregados].
^ result! !

!Divisao methodsFor: 'as yet unclassified' stamp: 'FranciscoAryMartins 6/20/2012 07:04'!
numeroEmpregados
| result |
result := 0.
empregados do: [:each| result := result + each numeroEmpregados].
^ result! !

!Divisao methodsFor: 'as yet unclassified' stamp: 'FranciscoAryMartins 6/25/2012 09:59'!
printOn: aStream
super printOn: aStream.
aStream nextPutAll: ': ', nome! !

!Divisao methodsFor: 'as yet unclassified' stamp: 'FranciscoAryMartins 6/18/2012 13:34'!
recuperarEmpregadoMatricula: aSmallInteger
^ crudManager getElementById: aSmallInteger! !

!Divisao methodsFor: 'as yet unclassified' stamp: 'FranciscoAryMartins 6/18/2012 13:34'!
removerEmpregadoMatricula: aSmallInteger
^ crudManager deleteElementById: aSmallInteger! !

!Divisao methodsFor: 'as yet unclassified' stamp: 'FranciscoAryMartins 6/19/2012 07:48'!
todosEmpregados
| result |
result := OrderedCollection new.
empregados do: [:each| result addAll: each todosEmpregados].
^ result! !

!Divisao methodsFor: 'accessing' stamp: 'FranciscoAryMartins 6/17/2012 19:30'!
empregados
^ empregados! !

!Divisao methodsFor: 'accessing' stamp: 'FranciscoAryMartins 6/17/2012 19:30'!
nome
^ nome! !

!Divisao methodsFor: 'accessing' stamp: 'FranciscoAryMartins 6/17/2012 19:30'!
nome: anObject
nome := anObject! !

"-- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- "!

Divisao class
instanceVariableNames: ''!

!Divisao class methodsFor: 'as yet unclassified' stamp: 'FranciscoAryMartins 6/17/2012 19:30'!
nome: aString
^ self new nome: aString! !

Object subclass: #Accumulator
instanceVariableNames: 'value'
classVariableNames: ''
poolDictionaries: ''
category: 'AdaptiveProgrammingBlogPost-Examples'!

!Accumulator methodsFor: 'accessing' stamp: 'FranciscoAryMartins 6/21/2012 22:15'!
value
^ value! !

!Accumulator methodsFor: 'accessing' stamp: 'FranciscoAryMartins 6/21/2012 22:04'!
value: anObject
value := anObject! !

"-- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- "!

Accumulator class
instanceVariableNames: ''!

!Accumulator class methodsFor: 'as yet unclassified' stamp: 'FranciscoAryMartins 6/21/2012 22:06'!
value: aSmallInteger
^self new value: aSmallInteger ! !

Visitor subclass: #EmpregadosSalarioMaiorQueVisitor
instanceVariableNames: 'salario'
classVariableNames: ''
poolDictionaries: ''
category: 'AdaptiveProgrammingBlogPost-Examples'!

!EmpregadosSalarioMaiorQueVisitor methodsFor: 'as yet unclassified' stamp: 'FranciscoAryMartins 6/21/2012 22:41'!
salario
^ salario! !

!EmpregadosSalarioMaiorQueVisitor methodsFor: 'as yet unclassified' stamp: 'FranciscoAryMartins 6/21/2012 22:40'!
salario: aSmallInteger
salario := aSmallInteger ! !

!EmpregadosSalarioMaiorQueVisitor methodsFor: 'as yet unclassified' stamp: 'FranciscoAryMartins 6/21/2012 22:29'!
visitDepartamento: umDepartamento
umDepartamento empregados do: [:each| each acceptVisitor: self].
umDepartamento divisoes do: [:each| each acceptVisitor: self] ! !

!EmpregadosSalarioMaiorQueVisitor methodsFor: 'as yet unclassified' stamp: 'FranciscoAryMartins 6/22/2012 07:52'!
visitDivisao: umaDivisao
umaDivisao empregados do: [:each| each acceptVisitor: self]! !

!EmpregadosSalarioMaiorQueVisitor methodsFor: 'as yet unclassified' stamp: 'FranciscoAryMartins 6/21/2012 22:32'!
visitEmpregado: umEmpregado
(umEmpregado salario > self salario) ifTrue: [
result add: umEmpregado]! !

!EmpregadosSalarioMaiorQueVisitor methodsFor: 'as yet unclassified' stamp: 'FranciscoAryMartins 6/21/2012 22:29'!
visitEmpresa: umaEmpresa
umaEmpresa departamentos do: [:each| each acceptVisitor: self]! !

"-- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- "!

EmpregadosSalarioMaiorQueVisitor class
instanceVariableNames: ''!

!EmpregadosSalarioMaiorQueVisitor class methodsFor: 'as yet unclassified' stamp: 'FranciscoAryMartins 6/21/2012 22:39'!
salario: aSmallInteger result: anOrderedCollection
^ self new
salario: aSmallInteger ;
result: anOrderedCollection! !

Object subclass: #Operation
instanceVariableNames: 'result sourceClass targetClass wrappers visitor signatureSymbol'
classVariableNames: ''
poolDictionaries: ''
category: 'AdaptiveProgrammingBlogPost-Examples'!

!Operation methodsFor: 'as yet unclassified' stamp: 'FranciscoAryMartins 6/23/2012 06:56'!
addWrapperTo: aClass withPrefix: aBlockClosure
wrappers at: aClass name asSymbol put: aBlockClosure ! !

!Operation methodsFor: 'as yet unclassified' stamp: 'FranciscoAryMartins 6/26/2012 06:11'!
compile
self compileEntryPoint! !

!Operation methodsFor: 'as yet unclassified' stamp: 'FranciscoAryMartins 6/26/2012 06:11'!
compileEntryPoint
sourceClass compile: self createEntryPointSource! !

!Operation methodsFor: 'as yet unclassified' stamp: 'FranciscoAryMartins 6/26/2012 06:11'!
createEntryPointSource
| sourceCode |
sourceCode := '
"Generated code"
| result visitor |
visitor := (Operation atSignature: #) visitor.
visitor arguments: thisContext arguments.
visitor visit: self.
^ visitor result value'.
^ sourceCode expandMacrosWith: (self signatureWithArgumentsFrom: signatureSymbol) with: signatureSymbol

! !

!Operation methodsFor: 'as yet unclassified' stamp: 'FranciscoAryMartins 6/23/2012 08:47'!
hasWrapperInClass: aClass
^ wrappers isEmpty not and: [wrappers includesKey: aClass] ! !

!Operation methodsFor: 'as yet unclassified' stamp: 'FranciscoAryMartins 6/23/2012 08:02'!
initialize
wrappers := Dictionary new.
visitor := OperationVisitor forOperation: self! !

!Operation methodsFor: 'as yet unclassified' stamp: 'FranciscoAryMartins 6/25/2012 13:09'!
prefixAt: aClassName
^ wrappers at: aClassName! !

!Operation methodsFor: 'as yet unclassified' stamp: 'FranciscoAryMartins 6/25/2012 12:44'!
result
^ result! !

!Operation methodsFor: 'as yet unclassified' stamp: 'FranciscoAryMartins 6/23/2012 06:51'!
result: anObject
result := anObject ! !

!Operation methodsFor: 'as yet unclassified' stamp: 'FranciscoAryMartins 6/25/2012 20:52'!
signature: aByteSymbol
signatureSymbol := aByteSymbol ! !

!Operation methodsFor: 'as yet unclassified' stamp: 'FranciscoAryMartins 6/25/2012 23:06'!
signatureWithArgumentsFrom: aByteSymbol
| stream count keywords |
stream := WriteStream on: ''.
count := 1.
keywords := aByteSymbol keywords.

(keywords size = 1 and: [(keywords first includes: $:) not] )ifTrue: [^ keywords first].

keywords do: [:keyword|
stream nextPutAll: keyword, ' anObject', count asString.
count := count + 1
].
^ stream contents! !

!Operation methodsFor: 'as yet unclassified' stamp: 'FranciscoAryMartins 6/23/2012 06:52'!
sourceClass: aClass
sourceClass := aClass! !

!Operation methodsFor: 'as yet unclassified' stamp: 'FranciscoAryMartins 6/23/2012 06:53'!
targetClass: aClass
targetClass := aClass! !

!Operation methodsFor: 'as yet unclassified' stamp: 'FranciscoAryMartins 6/23/2012 08:03'!
visitor
^visitor ! !

!Operation methodsFor: 'accessing' stamp: 'FranciscoAryMartins 6/25/2012 20:52'!
signature
^ signatureSymbol! !

"-- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- "!

Operation class
instanceVariableNames: 'operations'!

!Operation class methodsFor: 'as yet unclassified' stamp: 'FranciscoAryMartins 6/23/2012 07:45'!
atSignature: aSignature
^ operations at: aSignature! !

!Operation class methodsFor: 'as yet unclassified' stamp: 'FranciscoAryMartins 6/23/2012 07:54'!
initialize
"
self initialize
"
operations := Dictionary new! !

!Operation class methodsFor: 'as yet unclassified' stamp: 'FranciscoAryMartins 6/23/2012 07:58'!
registerOperation: anOperation
operations at: anOperation signature put: anOperation! !

!Operation class methodsFor: 'as yet unclassified' stamp: 'FranciscoAryMartins 6/23/2012 07:56'!
signature: aByteSymbol result: anObject from: aSourceClass to: aTargetClass
| operation |
operation := self new
signature: aByteSymbol ;
result: anObject ;
sourceClass: aSourceClass ;
targetClass: aTargetClass .
self registerOperation: operation.
^ operation! !

Object subclass: #CRUDManager
instanceVariableNames: 'collection idSelector'
classVariableNames: ''
poolDictionaries: ''
category: 'AdaptiveProgrammingBlogPost-Examples'!

!CRUDManager methodsFor: 'as yet unclassified' stamp: 'FranciscoAryMartins 6/23/2012 20:25'!
addElement: anElement
^ collection := collection add: anElement! !

!CRUDManager methodsFor: 'as yet unclassified' stamp: 'FranciscoAryMartins 6/18/2012 13:22'!
collection: aDictionary
collection := aDictionary! !

!CRUDManager methodsFor: 'as yet unclassified' stamp: 'FranciscoAryMartins 6/18/2012 13:08'!
deleteElementById: anId
^ collection removeKey: anId! !

!CRUDManager methodsFor: 'as yet unclassified' stamp: 'FranciscoAryMartins 6/25/2012 13:20'!
getElementById: anId
^ (collection select: [:each| (each perform: idSelector) = anId]) head! !

!CRUDManager methodsFor: 'as yet unclassified' stamp: 'FranciscoAryMartins 6/18/2012 13:23'!
idSelector: aByteSymbol
idSelector := aByteSymbol! !

!CRUDManager methodsFor: 'accessing' stamp: 'FranciscoAryMartins 6/18/2012 13:19'!
collection
^ collection! !

"-- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- "!

CRUDManager class
instanceVariableNames: ''!

!CRUDManager class methodsFor: 'as yet unclassified' stamp: 'FranciscoAryMartins 6/18/2012 13:24'!
collection: aCollection idSelector: aSymbol
^ self new
collection: aCollection;
idSelector: aSymbol

! !

AdaptiveBase subclass: #Empresa
instanceVariableNames: 'nome departamentos crudManager'
classVariableNames: ''
poolDictionaries: ''
category: 'AdaptiveProgrammingBlogPost-Examples'!

!Empresa methodsFor: 'accessing' stamp: 'FranciscoAryMartins 6/16/2012 10:59'!
departamentos
^ departamentos! !

!Empresa methodsFor: 'accessing' stamp: 'FranciscoAryMartins 6/16/2012 10:59'!
nome
^ nome! !

!Empresa methodsFor: 'accessing' stamp: 'FranciscoAryMartins 6/16/2012 10:59'!
nome: anObject
nome := anObject! !

!Empresa methodsFor: 'as yet unclassified' stamp: 'FranciscoAryMartins 6/21/2012 08:09'!
acceptVisitor: aVisitor
aVisitor visitEmpresa: self! !

!Empresa methodsFor: 'as yet unclassified' stamp: 'FranciscoAryMartins 6/24/2012 08:27'!
adicionarDepartamento: aDepartamento
^ departamentos := crudManager addElement: aDepartamento! !

!Empresa methodsFor: 'as yet unclassified' stamp: 'FranciscoAryMartins 6/26/2012 14:39'!
empregadoComMaiorSalario
"Generated code"
| result visitor |
visitor := (Operation atSignature: #empregadoComMaiorSalario) visitor.
visitor arguments: thisContext arguments.
visitor visit: self.
^ visitor result value! !

!Empresa methodsFor: 'as yet unclassified' stamp: 'FranciscoAryMartins 6/26/2012 14:39'!
empregadosSalarioMaiorQue: anObject1
"Generated code"
| result visitor |
visitor := (Operation atSignature: #empregadosSalarioMaiorQue:) visitor.
visitor arguments: thisContext arguments.
visitor visit: self.
^ visitor result value! !

!Empresa methodsFor: 'as yet unclassified' stamp: 'FranciscoAryMartins 6/23/2012 20:01'!
initialize
departamentos := EmptyList new.
crudManager := CRUDManager collection: departamentos idSelector: #nome.

self
adicionarDepartamento: (Departamento nome: 'A');
adicionarDepartamento: (Departamento nome: 'B');
adicionarDepartamento: (Departamento nome: 'C').

Empregado reinicieMatriculas.

(self recuperarDepartamentoNome: 'A')
adicionarEmpregado: (Empregado matricula: Empregado proximaMatricula nome: 'João' salario: 5000);
adicionarEmpregado: (Empregado matricula: Empregado proximaMatricula nome: 'Maria' salario: 6000);
adicionarEmpregado: (Empregado matricula: Empregado proximaMatricula nome: 'Paulo' salario: 3000).
(self recuperarDepartamentoNome: 'B')
adicionarEmpregado: (Empregado matricula: Empregado proximaMatricula nome: 'Carla' salario: 7000);
adicionarEmpregado: (Empregado matricula: Empregado proximaMatricula nome: 'Pedro' salario: 2000).
(self recuperarDepartamentoNome: 'C')
adicionarEmpregado: (Empregado matricula: Empregado proximaMatricula nome: 'Mateus' salario: 5000).

(self recuperarDepartamentoNome: 'A')
adicionarDivisao: (Divisao nome: 'D').
(self recuperarDepartamentoNome: 'B')
adicionarDivisao: (Divisao nome: 'E');
adicionarDivisao: (Divisao nome: 'F').
(self recuperarDepartamentoNome: 'C')
adicionarDivisao: (Divisao nome: 'G');
adicionarDivisao: (Divisao nome: 'H');
adicionarDivisao: (Divisao nome: 'I').

((self recuperarDepartamentoNome: 'A') recuperarDivisaoNome: 'D')
adicionarEmpregado: (Empregado matricula: Empregado proximaMatricula nome: 'Paulo' salario: 5200);
adicionarEmpregado: (Empregado matricula: Empregado proximaMatricula nome: 'Tatiana' salario: 6100);
adicionarEmpregado: (Empregado matricula: Empregado proximaMatricula nome: 'Joana' salario: 3500).
((self recuperarDepartamentoNome: 'B') recuperarDivisaoNome: 'E')
adicionarEmpregado: (Empregado matricula: Empregado proximaMatricula nome: 'Diego' salario: 2200);
adicionarEmpregado: (Empregado matricula: Empregado proximaMatricula nome: 'Natacha' salario: 8100).
((self recuperarDepartamentoNome: 'B') recuperarDivisaoNome: 'F')
adicionarEmpregado: (Empregado matricula: Empregado proximaMatricula nome: 'Carolina' salario: 7100).

((self recuperarDepartamentoNome: 'C') recuperarDivisaoNome: 'G')
adicionarEmpregado: (Empregado matricula: Empregado proximaMatricula nome: 'Rodrigo' salario: 4100).
((self recuperarDepartamentoNome: 'C') recuperarDivisaoNome: 'H')
adicionarEmpregado: (Empregado matricula: Empregado proximaMatricula nome: 'Pedro' salario: 2200);
adicionarEmpregado: (Empregado matricula: Empregado proximaMatricula nome: 'Raissa' salario: 8100).
((self recuperarDepartamentoNome: 'C') recuperarDivisaoNome: 'I')
adicionarEmpregado: (Empregado matricula: Empregado proximaMatricula nome: 'Francisco' salario: 5200);
adicionarEmpregado: (Empregado matricula: Empregado proximaMatricula nome: 'Melissa' salario: 6100);
adicionarEmpregado: (Empregado matricula: Empregado proximaMatricula nome: 'Betània' salario: 3500).

! !

!Empresa methodsFor: 'as yet unclassified' stamp: 'FranciscoAryMartins 6/16/2012 12:16'!
listarDepartamentos
self departamentos
do: [:departamento|
Transcript
space;
show: departamento nome
] ! !

!Empresa methodsFor: 'as yet unclassified' stamp: 'FranciscoAryMartins 6/19/2012 07:54'!
listarEmpregados
| empregados |
Transcript cr; show: 'Empregados:'.
empregados := self todosEmpregados.
empregados do: [:empregado|
Transcript cr; tab; show: empregado matricula; space; show: empregado nome; space; show: empregado salario.
]! !

!Empresa methodsFor: 'as yet unclassified' stamp: 'FranciscoAryMartins 6/20/2012 10:23'!
listarEmpregadosComSalariosAltos
| empregados |
Transcript cr; show: 'Empregados com salarios altos:'.
empregados := self empregadosSalarioMaiorQue: 7000.
empregados do: [:empregado|
Transcript cr; tab; show: empregado matricula; space; show: empregado nome; space; show: empregado salario.
]! !

!Empresa methodsFor: 'as yet unclassified' stamp: 'FranciscoAryMartins 6/16/2012 11:40'!
listarEmpregadosPorDepartamento
self departamentos do: [:departamento|
Transcript cr; show: departamento nome.
departamento listarEmpregados
]! !

!Empresa methodsFor: 'as yet unclassified' stamp: 'FranciscoAryMartins 6/19/2012 16:32'!
listarNomesEmpregados
| nomes |
Transcript cr; show: 'Nomes de empregados:'.
nomes := self nomesEmpregados.
nomes do: [:each|
Transcript space; show: each
]! !

!Empresa methodsFor: 'as yet unclassified' stamp: 'FranciscoAryMartins 6/20/2012 09:47'!
listarNumeroEmpregados
Transcript cr; show: 'Número de empregados: ', self numeroEmpregados asString.
! !

!Empresa methodsFor: 'as yet unclassified' stamp: 'FranciscoAryMartins 6/26/2012 14:39'!
nomesEmpregados
"Generated code"
| result visitor |
visitor := (Operation atSignature: #nomesEmpregados) visitor.
visitor arguments: thisContext arguments.
visitor visit: self.
^ visitor result value! !

!Empresa methodsFor: 'as yet unclassified' stamp: 'FranciscoAryMartins 6/26/2012 14:39'!
numeroEmpregados
"Generated code"
| result visitor |
visitor := (Operation atSignature: #numeroEmpregados) visitor.
visitor arguments: thisContext arguments.
visitor visit: self.
^ visitor result value! !

!Empresa methodsFor: 'as yet unclassified' stamp: 'FranciscoAryMartins 6/25/2012 07:49'!
printOn: aStream
super printOn: aStream.
aStream nextPutAll: ': ', nome! !

!Empresa methodsFor: 'as yet unclassified' stamp: 'FranciscoAryMartins 6/18/2012 13:20'!
recuperarDepartamentoNome: aByteString
^ crudManager getElementById: aByteString! !

!Empresa methodsFor: 'as yet unclassified' stamp: 'FranciscoAryMartins 6/18/2012 13:21'!
removerDepartamentoNome: aString
^ crudManager deleteElementById: aString! !

!Empresa methodsFor: 'as yet unclassified' stamp: 'FranciscoAryMartins 6/26/2012 14:39'!
somaSalariosEmpregados
"Generated code"
| result visitor |
visitor := (Operation atSignature: #somaSalariosEmpregados) visitor.
visitor arguments: thisContext arguments.
visitor visit: self.
^ visitor result value! !

!Empresa methodsFor: 'as yet unclassified' stamp: 'FranciscoAryMartins 6/26/2012 14:39'!
todosEmpregados
"Generated code"
| result visitor |
visitor := (Operation atSignature: #todosEmpregados) visitor.
visitor arguments: thisContext arguments.
visitor visit: self.
^ visitor result value! !

"-- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- "!

Empresa class
instanceVariableNames: ''!

!Empresa class methodsFor: 'as yet unclassified' stamp: 'FranciscoAryMartins 6/25/2012 07:47'!
nome: aByteString
^ self new
nome: aByteString ! !

Visitor subclass: #TodosEmpregadosVisitor
instanceVariableNames: ''
classVariableNames: ''
poolDictionaries: ''
category: 'AdaptiveProgrammingBlogPost-Examples'!

!TodosEmpregadosVisitor methodsFor: 'as yet unclassified' stamp: 'FranciscoAryMartins 6/21/2012 08:22'!
visitDepartamento: umDepartamento
umDepartamento empregados do: [:each| each acceptVisitor: self].
umDepartamento divisoes do: [:each| each acceptVisitor: self] ! !

!TodosEmpregadosVisitor methodsFor: 'as yet unclassified' stamp: 'FranciscoAryMartins 6/22/2012 07:52'!
visitDivisao: umaDivisao
umaDivisao empregados do: [:each| each acceptVisitor: self]! !

!TodosEmpregadosVisitor methodsFor: 'as yet unclassified' stamp: 'FranciscoAryMartins 6/21/2012 08:25'!
visitEmpregado: umEmpregado
result add: umEmpregado! !

!TodosEmpregadosVisitor methodsFor: 'as yet unclassified' stamp: 'FranciscoAryMartins 6/21/2012 08:20'!
visitEmpresa: umaEmpresa
umaEmpresa departamentos do: [:each| each acceptVisitor: self]! !

Visitor subclass: #OperationVisitor
instanceVariableNames: 'operation arguments'
classVariableNames: ''
poolDictionaries: ''
category: 'AdaptiveProgrammingBlogPost-Examples'!

!OperationVisitor methodsFor: 'as yet unclassified' stamp: 'FranciscoAryMartins 6/25/2012 23:12'!
arguments
^ arguments! !

!OperationVisitor methodsFor: 'as yet unclassified' stamp: 'FranciscoAryMartins 6/23/2012 08:40'!
hasWrapperIn: aClass
^ operation hasWrapperInClass: aClass! !

!OperationVisitor methodsFor: 'as yet unclassified' stamp: 'FranciscoAryMartins 6/23/2012 07:12'!
operation: anOperation
operation := anOperation ! !

!OperationVisitor methodsFor: 'as yet unclassified' stamp: 'FranciscoAryMartins 6/25/2012 12:43'!
result
^ operation result! !

!OperationVisitor methodsFor: 'as yet unclassified' stamp: 'FranciscoAryMartins 6/25/2012 17:23'!
result: anObject
operation result: anObject! !

!OperationVisitor methodsFor: 'as yet unclassified' stamp: 'FranciscoAryMartins 6/25/2012 17:05'!
visit: visitedObject
"Prefix processing"
(self hasWrapperIn: visitedObject class name)
ifTrue: [
(operation prefixAt: visitedObject class name)
value: self
value: visitedObject
].
"Traversal"
visitedObject class allInstVarNames
do: [:var |
(visitedObject respondsTo: var asSymbol)
ifTrue: [(visitedObject perform: var asSymbol)
ifNotNil: [:varValue |
self visit: varValue
]
]
]! !

!OperationVisitor methodsFor: 'accessing' stamp: 'FranciscoAryMartins 6/26/2012 06:01'!
arguments: anObject
arguments := anObject! !

!OperationVisitor methodsFor: 'accessing' stamp: 'FranciscoAryMartins 6/25/2012 12:40'!
operation
^ operation! !

"-- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- "!

OperationVisitor class
instanceVariableNames: 'operation'!

!OperationVisitor class methodsFor: 'as yet unclassified' stamp: 'FranciscoAryMartins 6/23/2012 07:11'!
forOperation: anOperation
^ self new operation: anOperation ! !

Empregado initialize!
Operation initialize!

Na parte 7 criaremos algumas funcionalidades envolvendo mais de uma classe no trajeto e introduziremos o sufix processing, entre outras coisas.

Anúncios

2 Respostas para “Adaptive Programming – Part 6

  1. Pingback: Adaptive Programming – Part 5 | Crab Log

  2. Pingback: Adaptive Programming – Part 1 | Crab Log

Deixe um comentário

Preencha os seus dados abaixo ou clique em um ícone para log in:

Logotipo do WordPress.com

Você está comentando utilizando sua conta WordPress.com. Sair / Alterar )

Imagem do Twitter

Você está comentando utilizando sua conta Twitter. Sair / Alterar )

Foto do Facebook

Você está comentando utilizando sua conta Facebook. Sair / Alterar )

Foto do Google+

Você está comentando utilizando sua conta Google+. Sair / Alterar )

Conectando a %s