CS 535 Object-Oriented Programming & Design Fall Semester, 2001 An Example |
||
---|---|---|
© 2001, All Rights Reserved, SDSU & Roger Whitney San Diego State University -- This page last updated 25-Nov-01 |
An Example
Here is an example, which we will examine. The windowSpec for the class has been removed to save space. Read the source code and write down what you think are the problems in this class.
Smalltalk.CS535 defineClass: #Customer superclass: #{UI.ApplicationModel} indexedType: #none private: false instanceVariableNames: 'name phone id ' classInstanceVariableNames: ' imports: '' category: 'UIApplications-New'
Class Method name: aName phone: aNumberString id: aNumber ^self new setName: aName setPhone: aNumberString setID: aNumberInstance methods id ^id isNil ifTrue: [id := 0 asValue] ifFalse: [id]
id: anInteger self id value: anInteger
name ^name isNil ifTrue: [name := String new asValue] ifFalse: [name]
name: aString self name value: aString
phone ^phone isNil ifTrue: [phone := String new asValue] ifFalse: [phone]
phone: aString self phone value: aString
printOn: aStream aStream print: 'Customer('; print: self name; print: ', '; print: self phone; print: ', '; print: self id; print: ')'
setName: aNameString setPhone: aPhoneString setID: aNumber self name value: aNameString. self phone value: aPhoneString. self id value: aNumber
find | separator dataFile stream names readingBlock | dataFile := 'names.txt' asFilename. stream := dataFile readStream. separator := $;. names := OrderedCollection new. readingBlock := [[stream atEnd] whileFalse: [stream next = Graphics.TextConstants.CR ifFalse: [names add: (Customer name: (stream upTo: separator) phone: (stream upTo: separator) id: (stream upTo: Graphics.TextConstants.CR))]]]. readingBlock valueNowOrOnUnwindDo: [stream close]. names do: [:each | each name value = self name value ifTrue: [self setPhone: each phone value. self setID: each id value]]
Comments
Before you read further write down what you think are the problems with this class.
Class as Struct
The class has very little intelligence. It is just a struct.
Lack of Information Hiding
Each instance variable has a method to get and a method to set its value
The accessor methods expose all users to the internal representation of the instance variable: value holders. So each access becomes:
aCustomer name value
rather than
aCustomer name
The Find method
A number of problems
Find is an operation on a collection of customers not a single customer. It does not belong in the customer class
The name of the data file is hard coded. This is something the commonly changes.
The method does a number of different things:
Some Solutions
Class as Struct
When you have just a struct usually the data is the struct is being used somewhere. Look at those locations and see if those operations really belong in the struct-like class. Look for things that are not being done yet.
Lack of Information Hiding
Do you really need methods that set and get the value for each instance variable? Remove those that are not being used. Look at what the others are being used for. It may be those operations belong in the Customer class.
The problem with the value holders has a number of solutions. One is to provide special methods for access to the instance variable for the GUI. These methods can return either a value holder or an aspect adapter. The normal access methods return the actual instance variable, not the value holder.
The Find Method
The find method does not belong in the Customer class. It also should be broken up into a number of methods.
Copyright ©, All rights reserved.
2000 SDSU & Roger Whitney, 5500 Campanile Drive, San Diego, CA 92182-7700 USA.
OpenContent license defines the copyright on this document.
Previous    visitors since 25-Nov-01    Next