Well factored Objects

goran.hultgren at bluefish.se goran.hultgren at bluefish.se
Tue Apr 29 09:26:41 UTC 2003


Hi Jimmie!

Jimmie Houchin <jhouchin at texoma.net> wrote:
> Hello,
> 
> I am wanting/trying to move some homebrew software I wrote at work in 
> MSWorks to Squeak. It is a database application.
> 
> It is a person database with close to 200 fields. Not all fields are an 
> attribute of person, but I am very contrained with MSWorks. Alas, it was 
> all I had available.
> 
> The JHPerson class could easily have dozens of instance variables. But 
> what I had been thinking is to group common variables into new classes 
> similar to but not necessarily exactly:
> 
> JHPersonName (first, middle, last, maiden, suffix)
> JHPersonBirth (date, place)
> JHPersonDeath (date, place)
> JHPersonMarriage (list of (dates, places, spouses))

Hmmm. Ok, here there may be a little newbie trap.
It looks to me that you are collecting numerous things into one object.
How about: JHPersonMarriage (date, place, spouse)

...and then let JHPerson have a collection of those in an instance
variable called "marriages"?

> JHPersonAddress (street, city, county, state, zip)
> JHPersonOccupation (title, industry)
> JHPersonEducation (numYears, listOfSchools)

Same advice would go for JHPersonEducation perhaps - if changed a little
bit like:
JHPersonEducation (startYear, endYear, school)

...and then again let JHPerson have a collection of those in an instvar
called "educations" (he, there is probably a better word to put in
plural in english).

> ... lots more data ...
> 
> and aggregate something like above into:
> JHPerson
>    name _ JHPersonName
>    birth _ JhPersonBirth
> ...
> 
> Is that a good or proper approach?

Looks fair to me. A normal guideline is to also be able to have
behaviour on these objects - but sometimes it is just nice to split
things up a little even if the resulting objects turn a bit "dumb".

> And would code like the below be good or proper?
> #JHPerson
> name
>      name isNil ifFalse: [^name]
>                 ifTrue: [name _ FHPersonName new].

Well, a part from a missing "^" in the true-branch the above looks a bit
strange - you are intending "lazy initialization" but in this case you
will end up with an "empty" FHPersonName instance. Sure, you could do it
this way but it feels to me that a JHPerson instance should always have
a proper name - by which I mean that it should be given to it when
instantiated.

Like:
	newPerson _ JHPerson firstName: 'John' lastName: 'Smith'

...using a class side "instance creation" method.

> with access like:
> 
> p _ FHPerson new initialize. "initialize initializes name variable."
> p name first: 'John'.
> ...
> 
> Is this reasonably on course, or did I fall off the beam somewhere?

Well, it is bordering on another "newbie trap" where you tend to break
encapsulation by asking an object for it's internal parts and then
interactive directly with those and thus bypassing the JHPerson
instance. Sure, you are only doing it "one level deep" but if we are
nitpicking it would be better with:

	p _ JHPerson new initialize. "initialize initializes name variable."
	p firstName: 'John'.

...with:

JHPerson>>firstName: aString
	"Set the first name."

	name firstName: aString


...simply forwarding it in this case. It may look like duplication of
code but the end result is that you don't break encapsulation and if
JHPerson later simply wants to store the firstName and lastName in two
String instance variables instead you can easily do that change without
breaking the client code.

> Thanks for any wisdom.

Well, I did what I could. :-)
 
> Jimmie Houchin

regards. Göran



More information about the Squeak-dev mailing list