Hi Ron,
In a nutshell, I have an application that needs to read Items from a
database.
I recently discovered that in Smalltalk classes are real objects.
This struck me as cool, so when I was deciding how to instantiate
these Items, I thought, hey I'll use the class object as a factory
(actually, I think it's more of an adapter pattern, but...)
So I taught the Item class object how to talk to the database,
including username/password, and then I was able to do something like:
item = Item findById: 2
And items from the database were instantiated as Items, seemingly by
magic.
This seemed so intuitive and simple, and just 'right'. It
encapsulated and hid the whole legacy database messiness and adapted
the database fields into the Item attributes I really needed.
Best of all, it could later be reprogrammed to talk to a slightly
different database and adapt that database's fields into exactly the
same Items, so the rest of the program didn't have to know it was
talking to a different database.
The problem arose when I needed to talk to more than one database *at
the same time*, since the Item class was programmed to talk to a
specific database. The only way to talk to another database was to
update the class variables before asking for the new Item. This was
ugly and, worse, the Item users had to know that there were different
databases to deal with.
Anyway, yesterday I realized I needed multiple objects to connect to
multiple databases. I figured I had two choices:
- subclass the Item class
- refactor entirely and build something like an ItemAdapter class,
who's instantiated objects would connect to the database, create Item
objects, initialize them from the data records, and hand them to the
Item consumers.
The second choice seemed the better, so that's what I did.
So, I think it was a case of falling in love with a cool feature, and
then mis-applying it, just because it was dying to be used.
Hope this explains it... I'm afraid I don't always get the jargon
right, but that's why I'm a newbie, I guess!
-- John
On Oct 26, 2007, at 10:48 PM, Ron Teitelbaum wrote:
Hi John,
I read your question, but had some trouble trying to understand
what you did
or why you are having trouble now that you have to connect to multiple
databases.
You say that you have only one Item class. That's good because
your domain
classes shouldn't be affected by your backend database. You mention a
factory to decide on and build your adapter. That's good too
because based
on some rule you would need to figure out what database to use.
Then I get foggy, you say you have to change class variables. Ok
so I'm
guessing that your factory sets the class variables which hold your
adaptors
that are used to pull items.
I think your question is: how can I keep from having to change
database
adapter class variables? If this is not your question please let
me know.
The answer to that question is to modify your model to provide the
flexibility you need so that you can supply adaptors to your
application.
Don't use class variables, use some other object instead. Classes
are cheap
if you need more functionality.
There is some rule that you are modeling that tells you when you
need one
database versus another database. You already have adapters that
handle the
different databases, so you only need to build a new object to hold
those
database sessions, built from your factory, and some session
manager that
knows when to attach and which adapter to use.
So build a session manager, that holds multiple database sessions
(adapters), and code the logic for picking a session on the
manager. When
global behavior stops being global move from class side (and class
variables) to a new class instance and model there instead. Let me
know if
any of that wasn't clear, feel free to provide more specific
information
about what you are trying to do.
Happy Coding!!
Ron Teitelbaum
President / Principal Software Engineer
US Medical Record Specialists
________________________________________
From: John Almberg
One of the cool things, I think, about Smalltalk is that Classes are
objects... i.e. concrete factories that can be modified at runtime to
produce objects in different ways, depending on the runtime
situation. I
just find this so much more intuitive, compared to how classes are
done in
other languages...
But I think I may have used it in a naive way...
For example, I needed an Adapter class that could produce standard
Item
objects by connecting to a variety of legacy database tables,
converting the
non-standard item records into standard Item objects. This way, the
consumer
of those Item objects doesn't care where the items come from.
Originally, I thought I would only have to make these connections,
one at a
time. I.e., I'd program the Item class 'factory' with the legacy
database
hostname, username, password, and then just start asking for Items.
The Item
class would then go out to the database, fetch the proper row,
create an
Item object, initialize the instance variables, and return it to
the Item
object consumer.
This is intuitive, cool, and it works.
Then the requirements changed and I needed to connect to multiple
database
*at the same time*.
But there is only one Item class object!
This really muddles things up, because I basically have to update
the Item
class variables every time I need an Item object. No longer cool!
Did I just misuse this feature? Should I have built two Adapter
Objects,
instead? Am I missing something obvious? Is a little knowledge a
dangerous
thing? :-)
TIA... John
_______________________________________________
Beginners mailing list
Beginners@lists.squeakfoundation.org
http://lists.squeakfoundation.org/mailman/listinfo/beginners
~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
Websites for On-line Collectible Dealers
~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
Identry, LLC
John Almberg
(631) 546-5079
[EMAIL PROTECTED]
www.identry.com
~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
_______________________________________________
Beginners mailing list
Beginners@lists.squeakfoundation.org
http://lists.squeakfoundation.org/mailman/listinfo/beginners