Command Pattern in Smalltalk

O Command Pattern é muito útil em vários contextos. Os exemplos mostrados nas figuras abaixo são de brinquedo mas ilustram um pouco o seu uso.

command-pattern-example

command-pattern-example2

command-pattern-example3

O terceiro exemplo, pelo aspecto visual, fornece um feedback mais interessante.

A seguir o file out com todo o código:

Error subclass: #NoCommandToRedo
	instanceVariableNames: ''
	classVariableNames: ''
	poolDictionaries: ''
	category: 'CommandPattern-Core-Errors'!

Error subclass: #NoCommandToUndo
	instanceVariableNames: ''
	classVariableNames: ''
	poolDictionaries: ''
	category: 'CommandPattern-Core-Errors'!Object subclass: #Commander
	instanceVariableNames: 'undoStack redoStack target'
	classVariableNames: ''
	poolDictionaries: ''
	category: 'CommandPattern-Core'!

!Commander methodsFor: 'as yet unclassified' stamp: 'FranciscoAryMartins 11/8/2015 13:54'!
initialize
	super initialize.
	undoStack := Stack new.
	redoStack := Stack new! !

!Commander methodsFor: 'as yet unclassified' stamp: 'FranciscoAryMartins 11/8/2015 18:27'!
redo
	^[ undoStack push: redoStack pop execute ] on: Error do: [ :error | NoCommandToRedo new signal ]
	! !

!Commander methodsFor: 'as yet unclassified' stamp: 'FranciscoAryMartins 11/8/2015 13:53'!
target:  anObject
	target := anObject! !

!Commander methodsFor: 'as yet unclassified' stamp: 'FranciscoAryMartins 11/8/2015 18:25'!
executeCommand: aCommand
	| result |
	aCommand target: target.
	result := undoStack push: (aCommand execute).
	redoStack removeAll.
	^result
	! !

!Commander methodsFor: 'as yet unclassified' stamp: 'FranciscoAryMartins 11/8/2015 18:26'!
undo
	^[ redoStack push: undoStack pop undo ] on: Error do: [ :error | NoCommandToUndo new signal ]! !

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

Commander class
	instanceVariableNames: ''!

!Commander class methodsFor: 'as yet unclassified' stamp: 'FranciscoAryMartins 11/8/2015 19:22'!
example
	| coll commander |
	coll := OrderedCollection new.
	commander := Commander target: coll.
	commander 
		executeCommand: (AddObjectToCollection object: 1);
		executeCommand: (AddObjectToCollection object: 2);
		executeCommand: (AddObjectToCollection object: 3);
		undo; redo.
	coll ! !

!Commander class methodsFor: 'as yet unclassified' stamp: 'FranciscoAryMartins 11/8/2015 13:50'!
target: aTarget  
	^self new 
		target: aTarget! !

!Commander class methodsFor: 'as yet unclassified' stamp: 'FranciscoAryMartins 11/8/2015 19:31'!
example3
	| morph commander submorph submorph2 |
	morph := BlMorph new withRectangleViewDo: [ :v | 
		v extent: 200@200; color: Color blue
	].
	submorph := BlMorph new withRectangleViewDo: [ :v | 
		v extent: 100@100; color: Color red
	].
	submorph2 := BlMorph new withRectangleViewDo: [ :v | 
		v extent: 50@50; color: Color green
	].

	commander := Commander target: morph.
	
	commander 
		executeCommand: (AddSubmorph morph: submorph);
		executeCommand: (AddSubmorph morph: submorph2);
		undo;redo.
	
	morph openInWorld! !

!Commander class methodsFor: 'as yet unclassified' stamp: 'FranciscoAryMartins 11/8/2015 19:28'!
example2
	| dict commander |
	dict := Dictionary new.
	commander := Commander target: dict.
	commander 
		executeCommand: (AtPutObjectToDicitionary key: #One value: 1);
		executeCommand: (AtPutObjectToDicitionary key: #Two value: 2);
		executeCommand: (AtPutObjectToDicitionary key: #Three value: 3);
		undo.
	dict! !


Object subclass: #Command
	instanceVariableNames: 'target'
	classVariableNames: ''
	poolDictionaries: ''
	category: 'CommandPattern-Core'!

!Command methodsFor: 'as yet unclassified' stamp: 'FranciscoAryMartins 11/8/2015 14:12'!
undo
	self subclassResponsibility ! !

!Command methodsFor: 'as yet unclassified' stamp: 'FranciscoAryMartins 11/8/2015 14:12'!
execute
	self subclassResponsibility ! !

!Command methodsFor: 'as yet unclassified' stamp: 'FranciscoAryMartins 11/8/2015 14:33'!
target: anObject
	target :=  anObject ! !
Command subclass: #AddSubmorph
	instanceVariableNames: 'morph'
	classVariableNames: ''
	poolDictionaries: ''
	category: 'CommandPattern-Examples'!

!AddSubmorph methodsFor: 'as yet unclassified' stamp: 'FranciscoAryMartins 11/8/2015 18:43'!
undo
	target removeMorph: morph! !

!AddSubmorph methodsFor: 'as yet unclassified' stamp: 'FranciscoAryMartins 11/8/2015 18:42'!
execute
	target addMorph: morph! !

!AddSubmorph methodsFor: 'as yet unclassified' stamp: 'FranciscoAryMartins 11/8/2015 18:41'!
morph: aMorph 
	morph :=  aMorph! !

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

AddSubmorph class
	instanceVariableNames: ''!

!AddSubmorph class methodsFor: 'as yet unclassified' stamp: 'FranciscoAryMartins 11/8/2015 18:40'!
morph: aMorph 
	^self new morph: aMorph ! !


Command subclass: #AddObjectToCollection
	instanceVariableNames: 'object'
	classVariableNames: ''
	poolDictionaries: ''
	category: 'CommandPattern-Examples'!

!AddObjectToCollection methodsFor: 'as yet unclassified' stamp: 'FranciscoAryMartins 11/8/2015 18:28'!
undo
	target removeLast! !

!AddObjectToCollection methodsFor: 'as yet unclassified' stamp: 'FranciscoAryMartins 11/8/2015 18:28'!
execute
	target add: object! !


!AddObjectToCollection methodsFor: '*AsmJit-Extension' stamp: 'FranciscoAryMartins 11/8/2015 14:27'!
object: anObject 
	object := anObject! !

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

AddObjectToCollection class
	instanceVariableNames: ''!

!AddObjectToCollection class methodsFor: 'as yet unclassified' stamp: 'FranciscoAryMartins 11/8/2015 14:27'!
object: anObject 
	^self new object: anObject! !


Command subclass: #AtPutObjectToDicitionary
	instanceVariableNames: 'key value'
	classVariableNames: ''
	poolDictionaries: ''
	category: 'CommandPattern-Examples'!

!AtPutObjectToDicitionary methodsFor: 'as yet unclassified' stamp: 'FranciscoAryMartins 11/8/2015 18:01'!
undo
	target removeKey: key! !

!AtPutObjectToDicitionary methodsFor: 'as yet unclassified' stamp: 'FranciscoAryMartins 11/8/2015 17:56'!
key: anObject 
	key := anObject! !

!AtPutObjectToDicitionary methodsFor: 'as yet unclassified' stamp: 'FranciscoAryMartins 11/8/2015 17:57'!
execute
	target at: key put: value! !

!AtPutObjectToDicitionary methodsFor: 'as yet unclassified' stamp: 'FranciscoAryMartins 11/8/2015 17:56'!
value: anObject 
	value :=  anObject! !

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

AtPutObjectToDicitionary class
	instanceVariableNames: ''!

!AtPutObjectToDicitionary class methodsFor: 'as yet unclassified' stamp: 'FranciscoAryMartins 11/8/2015 17:54'!
key: aKey value: aValue
	^self new
		key: aKey; 
		value: aValue! !

Anúncios

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