Well factored Objects
goran.hultgren at bluefish.se
goran.hultgren at bluefish.se
Tue Apr 29 15:51:23 UTC 2003
Jimmie Houchin <jhouchin at texoma.net> wrote:
> 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.
Thank you very much!
> > 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
Hmmm, well it looked like you simply created an "empty" JHPersonName
instance in the #name method. Right? Anyway, I think you understand what
> 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.
> 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?
Yes, decomposition is good. I was just opposing of the line:
p name first: 'John'.
Here you ask p (the JHPerson object) for it's name object and then you
send a message to the name object directly. I agree - this is bordering
on nitpicking but you are essentially hardcoding a dependency here - the
code depends on the fact that JHPerson has a JHPersonName instance kept
internally. My version removed that dependency:
p firstName: 'John'.
...this line has no idea what the JHPerson object will do with the
String sent in. No dependency on any internal representation. But again
- nitpicking. I have seen much worse cases of this kind of "ripping your
guts out-code". When I taught OO I used to tell the analogy of trying to
find out if John ate a sausage for dinner - two approaches, first the
datacentric newbie approach:
john intestines stomach contents includes: #sausage
...and my slightly more polite message based OO approach :-) :
john didYouEat: #sausage
The first solution breaks encapsulation three levels deep, it hardcodes
the fact that John has intestines and that those intestines include a
stomach and that the stomach has something called contents that
understands the message #includes:. A long hariy daisychain of
dependencies making changes to that object structure immediately
breaking this line of code.
The second version just relies on the fact that if we are polite to John
and asks him if he ate a sausage it is up to him to come up with the
> > 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?
Again, I wasn't implying that you should flatten anything out - I just
reacted to the "gut cutting". :-)
More information about the Squeak-dev