CarPartFactory>>makeCar
self
subclassResponsibility
CarPartFactory>>makeEngine
self
subclassResponsibility
CarPartFactory>>makeBody
self
subclassResponsibility
FordFactory>>makeCar
^FordCar new
FordFactory>>makeEngine
^FordEngine
new
FordFactory>>makeBody
^FordBody
new
ToyotaFactory>>makeCar
^ToyotaCar
new
ToyotaFactory>>makeEngine
^ToyotaEngine
new
ToyotaFactory>>makeBody
^ToyotaBody
new
Object subclass: #CarAssembler
instanceVariableNames:
'factory'
classVariableNames: ''
poolDictionaries:
''
CarAssembler>>factory: aCarPartFactory
"Setter
method"
factory := aCarPartFactory
CarAssembler class>>using:
aCarPartFactory
"Instance creation method"
^self new factory:
aCarPartFactory
CarAssembler>>assembleCar
| car |
"Create the
top-level part, the car object which
starts out having no subcomponents, and
add an
engine, body, etc." car :=
factory makeCar.
car
addEngine: factory
makeEngine;
addBody: factory makeBody.
^car
CarPartFactory>>makeCar
^self carClass
new
CarPartFactory>>makeEngine
^self engineClass
new
CarPartFactory>>makeBody
^self bodyClass
new
FordFactory>>carClass
^FordCar
FordFactory>>engineClass
^FordEngine
FordFactory>>bodyClass
^FordBody
PorscheFactory>>carClass
^PorscheCar
PorscheFactory>>engineClass
^PorscheEngine
PorscheFactory>>bodyClass
^PorscheBody
Object subclass: #CarPartFactory
instanceVariableNames:
'partCatalog'
classVariableNames: ''
poolDictionaries:
''
CarPartFactory class>>new
^self basicNew
initialize
CarPartFactory>>initialize
partCatalog :=
Dictionary new
FordFactory>>initialize
super
initialize.
partCatalog
at: #car put: FordCar;
at:
#body put: FordBody;
at: #engine put:
FordEngine.
^self
PorscheFactory>>initialize
super
initialize.
partCatalog
at: #car put: PorscheCar;
at: #body put: PorscheBody;
at: #engine put:
PorscheEngine.
^self
CarPartFactory>>make: partType
"Create a new part
based on partType."
| partClass |
partClass := partCatalog at:
partName ifAbsent: [^nil].
^partClass new
“anAutoFactory make: #engine.
anAutoFactory make:
#body.”
“anAutoFactory makeEngine.
anAutoFactory
makeBody.”
Object subclass: #CarPartFactory
instanceVariableNames:
''
classVariableNames: ''
poolDictionaries: ''
CarPartFactory class
instanceVariableNames:
'partCatalog'
CarPartFactory class>>make: partType
"We moved
this method; it's a class method now."
| partClass |
partClass
:= partCatalog at: partType ifAbsent: [^nil].
^partClass
new
CarPartFactory class>>new
partCatalog isNil
ifTrue: [self initialize].
^self basicNew
CarPartFactory class>>initialize
"Initialize the
part catalog. This is now a class method."
partCatalog := Dictionary
new
FordFactory class>>initialize
"Initialize the
*local* part catalog."
super initialize.
partCatalog
at: #car put: FordCar;
at: #body put: FordBody;
at: #engine
put: FordEngine.
CarPartFactory>>make: partType
"Create a new part
based on partType."
^self class make: partType
CarPartFactory class>>fordFactory
"Create and
return a new Ford factory."
| catalog |
catalog := Dictionary
new.
catalog
at: #car put: FordCar;
at: #engine
put: FordEngine.
^self new partCatalog: catalog
CarPartFactory class>>porscheFactory
"Create and
return a new Porsche factory."
| catalog |
catalog :=
Dictionary new.
catalog
at: #car put:
PorscheCar;
at: #engine put: PorscheEngine.
^self new
partCatalog: catalog
“carFactory := CarPartFactory fordFactory.
carFactory make:
#engine.”
CarPartFactory>>makeCar:
manufacturersName
"manufacturersName is a Symbol, such as #Ford, #Toyota,
or #Porsche."
| carClass |
carClass := Smalltalk
at: (manufacturersName, #Car) asSymbol
ifAbsent: [^nil].
^carClass
new
CarPartFactory>>makeEngine: manufacturersName
|
engineClass |
engineClass := Smalltalk
at: (manufacturersName,
#Engine) asSymbol
ifAbsent: [^nil].
^engineClass new
“carFactory := CarPartFactory new.
car := carFactory makeCar:
carCompany.
car addEngine: (carFactory makeEngine:
carCompany);”
Object subclass: #CarBuilder
instanceVariableNames:
'car'
classVariableNames: ''
poolDictionaries:
''
CarBuilder class>>new
^self basicNew
initialize
CarBuilder>>car
"getter
method"
^car
CarBuilder>>car: aCar
"setter
method"
car := aCar
CarBuilder subclass:
#FordBuilder
instanceVariableNames: ''
classVariableNames:
''
poolDictionaries: ''
CarBuilder subclass:
#ToyotaBuilder
instanceVariableNames: ''
classVariableNames:
''
poolDictionaries: ''
CarBuilder subclass:
#PorscheBuilder
instanceVariableNames: ''
classVariableNames:
''
poolDictionaries: ''
FordBuilder>>initialize
self car: FordCar
new
ToyotaBuilder>>initialize
self car: ToyotaCar
new
PorscheBuilder>>initialize
self car: PorscheCar
new
CarBuilder>>add4CylinderEngine
"Do nothing.
Subclasses will override."
FordBuilder>>add4CylinderEngine
self car
addEngine: Ford4CylinderEngine new
ToyotaBuilder>>add4CylinderEngine
self car
addEngine: Toyota4CylinderEngine new
PorscheBuilder>>add4CylinderEngine
self car
addEngine: Porsche4CylinderEngine new
CarBuilder>>addStandard6CylinderEngine
"Do
nothing. Subclasses will override."
FordBuilder>>addStandard6CylinderEngine
self car
addEngine: FordStandard6CylinderEngine new
ToyotaBuilder>>addStandard6CylinderEngine
self
car addEngine: ToyotaStandard6CylinderEngine new
PorscheBuilder>>addStandard6CylinderEngine
self
car addEngine: PorscheStandard6CylinderEngine new
ViewManager subclass:
#CarAssemblerUI
instanceVariableNames:
'builder'
classVariableNames: ''
poolDictionaries:
''
CarAssemblerUI>>carMenu
"Build the car-manufacturers
menu."
| menu |
menu := Menu new
title:
'Car';
owner: self.
CarBuilder subclasses do: [:aClass
|
menu
appendItem: aClass manufacturer "the
label"
selector: (Message "the action"
receiver:
self
selector: #userChoseBuilder:
arguments:
(Array with: aClass))].
^menu
CarAssemblerUI>>userChoseBuilder:
builderClass
builder := builderClass new.
CarBuilder class>>manufacturer
self
implementedBySubclass
FordBuilder
class>>manufacturer
^'Ford'
ToyotaBuilder
class>>manufacturer
^'Toyota'
PorscheBuilder
class>>manufacturer
^'Porsche'
CarAssemblerUI>>engineMenu
^Menu new
title: 'Engine';
owner: self;
appendItem: '4-Cylinder'
selector:
#engineIs4Cylinder;
appendItem: '6-Cylinder Standard'
selector: #engineIsStandard6Cylinder;
appendItem: '6-Cylinder Turbocharged'
selector: #engineIsTurbocharged6Cylinder;
yourself
CarAssemblerUI>>engineIs4Cylinder
"The user has
selected the '4-cylinder' menu item
from the 'Engine' pulldown menu. Tell my
Builder."
self builder add4CylinderEngine
CarAssemblerUI>>engineIsStandard6Cylinder
"The user has
selected the 'Standard 6-cylinder'
menu item from the 'Engine' pulldown
menu."
self builder addStandard6CylinderEngine
CarAssemblerUI>>engineIsTurbocharged6Cylinder
"The user
has selected the 'Turbocharged 6-cylinder'
menu item from the 'Engine'
pulldown menu."
self builder
addTurbocharged6CylinderEngine
CarAssemblerUI>>orderCar
"The user has selected the
'Order' menu item, signaling
all car/components selections have been
made."
| completeCar |
"Get the assembled car from my
Builder:"
completeCar:= builder assembledCar.
completeCar
isNil ifTrue: [^MessageBox message:
'You haven''t finished assembling
a complete car yet!'].
"Assemble and print an invoice for the assembled
car:"
CarInvoiceMaker new printInvoiceFor: completeCar.
CarBuilder>>assembledCar
"Return my final Product
after verifying there's
a completed Product to return."
car isNil
ifTrue: [^nil].
car engine isNil ifTrue:
[^nil].
^car
FordBuilder>>add4CylinderEngine
"Add a 4-cylinder
engine; it is created by
invoking a factory method."
self car
addEngine: self fourCylinderEngine
ToyotaBuilder>>add4CylinderEngine
self car
addEngine: self fourCylinderEngine
FordBuilder>>fourCylinderEngine
"The Ford 4-cylinder
engine factory method."
^Ford4CylinderEngine new
ToyotaBuilder>>fourCylinderEngine
^Toyota4CylinderEngine
new
“Prototype Version”
Object subclass: #Policy
instanceVariableNames: 'policyNumber
coverageStartDate
lengthOfCoverage organization
procedureRules'
classVariableNames: ''
poolDictionaries: ''
Policy>>postCopy
"See general comments in
superimplementor."
"Make an independent copy of this Policy's
attributes"
| newDictionary |
newDictionary := Dictionary
new.
procedureRules keysAndValuesDo:[:key :value |
newDictionary at: key put: value copy].
procedureRules :=
newDictionary.
organization:= organization copy
“Decorator Version”
Policy>>ruleAt: aProcedureCode
^self
procedureRules
at: aProcedureCode
ifAbsent:
[self defaultRule]
Policy>>setRuleFor: aProcedureCode rule:
aProcedureRule
self procedureRules
at:
aProcedureCode
put: aProcedureRule
DecoratingPolicy>>ruleAt:
aProcedureCode
^self
at: aProcedureCode
ifAbsent: [self basePolicy ruleAt: aProcedureCode]
Policy>>lengthOfCoverage
"Return the length of
time, in years, this Policy
is in
effect."
^lengthOfCoverage
DecoratingPolicy>>lengthOfCoverage
"See
superimplementor."
"If the value has not yet been set, return the
base policy's value."
^lengthOfCoverage isNil
ifTrue: [self basePolicy lengthOfCoverage]
ifFalse:
[lengthOfCoverage]
Policy>>derivedPolicy
"Return a new Policy
derived from this one."
^DecoratingPolicy new basePolicy:
self
Object subclass: #DatabaseAccessor
instanceVariableNames:
'lock'
classVariableNames: 'Instance'
poolDictionaries: ''
DatabaseAccessor class>>singleton
Instance
isNil
ifTrue: [Instance := self basicNew
initialize].
^Instance
DatabaseAccessor class>>new
^self error:
'DatabaseAccessor has only one instance. ','To retrieve it, send
"DatabaseAccessor singleton".'
DatabaseAccessor>>initialize
lock :=
false.
"Open the file"
DatabaseAccessor>>write: aDatabaseRecord
"Set the
lock and fork the 'real' write method."
lock := true.
[self
writePrim: aDatabaseRecord] fork
DatabaseAccessor>>writePrim:
aDatabaseRecord
"Write the record in aDatabaseRecord to the
file."
"Now that the write is
complete, unlock:"
lock := false.
DatabaseAccessor>>read: aKey
"Return the
DatabaseRecord keyed by aKey."
| record |
"Don't read while a
write is in progress."
[lock] whileTrue: [Processor
yield].
"Now, read the record:"
record := DatabaseRecord
new.
"Modify the Record"
^record
“DatabaseAccessor singleton read: aKey”
“DatabaseAccessor default.”