Well factored Objects

Jimmie Houchin jhouchin at texoma.net
Tue Apr 29 14:27:26 UTC 2003


goran.hultgren at bluefish.se wrote:
> Hi Jimmie!

Howdy Göran!
(In Texas we not only get to say y'all but also howdy. :)

And by the way, congratulations!!!
May it be a long, prosperous and blessed marriage.

> 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"?

Yes, you are absolutely correct. I did exactly that in other areas, but 
did not apply it consistently. Thanks for pointing that out.

>>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).

Ah! another one. Thanks.

>>... 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
oops.  I wrote that in MozillaMail as an example.  :)
> 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'.
>>...

In the code I was playing with, I initialize the JHPersonName object 
when JHPerson is created. Yes, the JHPerson object must always have a 
name. In fact there is quite a bit of data that is required. One reason 
I want to move to Squeak and out of MSWorks. In Squeak I can ensure my 
data requirements and not rely on my memory to populate the fields.


>>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:

This is where I get confused.
in
p _ JHPerson new initialize. "initialize initializes name variable."
p name first: 'John'.

p is a JHPerson object.
name is a JHPerson instance variable assigned a JHPersonName object.
p name first: 'John'  accesses the JHPersonName objects 'first' instance 
variable through its interface method.

You might already have understood all of that, I just wanted to make 
sure I was communicating.

Isn't that one of the purposes of decomposing a large object into 
smaller objects of common data and behaviour?

> 	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.

JHPersonName probably should be
JHPersonID and have 'first middle last maiden suffix ssn' instance 
variables. ssn is the US Social Security Number our government ID number 
for citizens.

If I put all of that data into JHPerson doesn't that reduce/eliminate 
the need for JHPersonName?

Hard questions I know and you don't have the app info in your head.

Thanks for helping.

>>Thanks for any wisdom.
> 
> Well, I did what I could. :-)

Yes indeed.

Jimmie Houchin



More information about the Squeak-dev mailing list