Inline was getting messy, so i broke the topics out.
UPDATE TRIGGER:
Whatever is taking the request (a Mach-II listener, in my case) calls the
persistArtist method to persist the artist. I've implemented the method a
couple ways:
1) it takes as parameters all data to define an Artist, modifies the
relevant Artist object (or creates a new one), and then persists it
2) simply takes an artist object and persists it, leaving the caller to
ensure the Artist's state is updated first.
Number two is definitely the better way to do it, in my opinion. The first
method is a little to tightly coupled for my tastes, because it requires
passing data around, rather than sending messages instructing objects to
perform actions.
WHAT IS THE List CLASS:
The List class is a generic wrapper of an array. It provides exactly the
same functionality as arrayAppend, arrayGetAt, and arrayDeleteAt just
wrapped up in a cohesive package. It stores anything of any type (CFCs,
numbers, whatever), and doesn't return a specifc type. I only have one List
class, but if I were to extend it, the extensions would be LinkedList, or
DoubleLinkedList or something. The implementation would change, not what
it's storing.
C++ has something like you describe called templates. They are the devil.
(at least I think so).
CACHE SIZING:
Cache sizing is no big deal. Since your cache is managed within a single
object, it's simple enough to keep it a certain size. With no checking,
your cacheEvent method would look like this:
private void cacheEvent(Event e) {
variables.myEventList.add(e);
}
Now lets say we want to cache no more than 50 Events at a time. Now our
cacheEvent method looks like this:
private void cacheEvent(Event e) {
if (variables.myEventList.getSize() GT 50) {
variables.myEventList.delete(1);
}
variables.myEventList.add(e);
}
Your method will likely end up a somewhat more complicated, since you'll
probably want to expire objects more intelligently that I've demonstrated
(first in, first out). You may want to track a last access date and expire
based on that, rather than first access order like this method would, though
this will work fine.
Keep in mind that each CFC instance is only storing the instance data it
posesses, not the method implementations and such. Those are only loaded
once for each filesystem version of the CFC. So you can store a LOT of
instances in memory.
cheers,
barneyb
> -----Original Message-----
> From: Jim Davis [mailto:[EMAIL PROTECTED]
> Sent: Sunday, September 14, 2003 11:17 PM
> To: CF-Talk
> Subject: RE: Conceptual OO question(s)
>
>
> > responses inline below. Keep in mind this is how I usually do things;
> > there
> > are many correct solutions, though all will share many of the same
> traits.
>
> After I wrote this I finally found the "right" term for this: apparently
> they're called "Implementation Classes" (as opposed to the more
> real-world "Domain classes").
>
> I'm not sure if that terminology is cardinal, but it has helped me
> search better. It's amazing how much easier it is to find things when
> you know what they're called. ;^)
>
> > > Consider that I have an "Artist" object which has properties like
> > > "name", "profile", "website", etc. That data is, of course, stored
> in a
> > > database (SQL Server, for what it's worth) table. Here are some of
> my
> > > confusions:
> > >
> > > 1) How do you (using good OO practices) put the data in the
> database?
> > > Does the "Artist" object have a "SaveData()" method (or somesuch) so
> > > that you first instantiate the object, then store the data in the
> > > database or do you have another object that stores the data for
> later?
> > > Everything I read talks about instantiating the object with data but
> > > nothing details the link between the persistent data store and the
> > > transient object.
> >
> > Your actual Artist object should know nothing about persistant
> storage, be
> > it a database, flat files, whatever. The object that instantiates the
> > Artist object should deal with the persistance layer. I typically
> call
> > such
> > objects Services, and they have methods like getArtistById() which
> takes a
> > numeric ID parameter, and returns an Artist object. That Service
> object
> > (in
> > this case named ArtistService) is the only object that knows anything
> > about
> > persisting Artists.
>
> Sounds good to me... I like the concept. I also like the abstraction in
> the sense that (it should) allow for easier migration to different
> persistence datastores.
>
> So my application is, if I understand this correctly, "layered". One
> layer does nothing but abstract the data. I actually already do this in
> my procedural programming - all data comes from a "Data Translation
> Layer" (DTL) and converts database data, for example, into useful data
> for the UI.
>
> The data translation layer is called by a "show" or "display" template
> that did nothing but display the data. For example "Artist-Show.cfm"
> would contain the layout and such and call "Artist-DTL.cfm" which would
> query the DB and format the "raw" data for the screen.
>
> I'm not sure if my procedural programming was OO-like or if OO just
> isn't all that different but at least I'm not spending MOST of my time
> confused... just some. ;^)
>
> > > 2) In the same way, when I'm editing the properties of the object
> does
> > > the object normally update the persistent store immediately in the
> > > "set()" methods or is there normally a method to do this all in one
> go -
> > > something like a "save()" method?
> >
> > This should also happen in the service object. I usually use
> > persistArtist() method, which takes an Artist object and stores it in
> the
> > database. It will chekc the Artist object's getId() method and if it
> > returns a valid ID, then the service knows it needs to do an update.
> If
> > it
> > returns an invalid ID, that means the object has not been persisted,
> and
> > needs to be inserted.
>
> Sound like my existing DTLs again - which is good.
>
> I'm a little unclear on the "trigger" here tho'. When you've got an
> "update" page and changes are made. Upon submit (assuming you want to
> store the data immediately) do first call the Artist object which,
> noticing a change, calls the persistArtist() method or do you call the
> service directly and have it, having noticed that it's changing the
> data, automatically update the Artist?
>
> The former seems to more sense to me (especially if you want to hold off
> making permanent changes until requested). I suppose that this is
> probably less of a best practices question and more of a "however it
> makes sense to the app" question, uh?
>
> > > 3) When I present a list of the artists do I (again using best
> > > practices) instantiate a structure (or array or whatever) of
> "Artist"
> > > objects (which will contain much more data than my list needs but
> seems
> > > conceptually sound) or do I have some intermediate "ArtistList"
> object
> > > which just outputs a record set?
> >
> > It's kind of personal preference. For large report-type datasets, I
> > usually
> > prefer to do a task-specific query (via a method in a service object,
> > though
> > not necessarily one bound to a business object type), and return that
> > recordset directly to the display. However if I have an admin page
> that
> > provides a list of users, I'll probably return a List of User objects.
> > List
> > is an object similar to Java's ArrayList which is just an object
> wrapper
> > around an array, but carries the benefit of being able to extend it
> with a
> > different underlying mechanism if that's more appropriate for the
> specific
> > data storage need.
>
> Are you saying that "List" is a generic object (an "Interface", right)?
> So then I would extend it to create (perhaps) "ArtistList", "VenueList"
> and so forth?
>
> One thought I had was that some of the "List" functions should (maybe)
> be handled by the overall container object (in this case "Festival") so
> that the Festival object would have "EventList()" and "VenueList()"
> methods returning arrays of objects. Perhaps also having methods like
> "SimpleEventList()" and "SimpleVenueList()" that just return simple
> recordsets?
>
> Sound sound?
>
>
> > > Basically this last one concerns memory usage. I can conceptualize
> a
> > > "Festival" object which contains many "Event" and "Venue" objects
> which
> > > are linked together by "TimeSlot" objects. The "Event" objects
> would
> > > further contain references to "Artist" objects which in turn contain
> > > references to "Asset" objects (images, multimedia, etc).
> > >
> > > Although I can conceptualize how the whole thing, all together,
> would
> > > "feel" and be constructed I'm having trouble conceptualizing how to
> pull
> > > just the needed information from the database. When an end user
> > > requests a list of Venues, then selects one to see the events at
> that
> > > venue what gets instantiated?
> > >
> > > Is it a "VenueList" object or an array of (all) Venue objects?
> >
> > Keep in mind that a good object model will let you make an insane
> amount
> > of
> > object caching. Your services and business objects should allow for
> > multithreading, so that they can be used my multiple clients at the
> same
> > time. If so, you can cache all the business objects in the service
> > objects,
> > which means instantion doesn't have to hit the persistance layer
> except
> > for
> > the first time. And because all the updates to the persistance layer
> also
> > happen through the service object, you can ensure that your in-memory
> > cache
> > is in sync with the persistance layer, so even across updates, you
> don't
> > have to run SELECTs.
>
> For this particular application this is exactly what I'm planning. The
> total amount of data is quite small (about 70 Venues and 200 Artists for
> a big one-day event). I plan to cache the entire model in memory for
> performance sake (this site gets a LOT of traffic on New Year's Eve).
>
> However I'm still a little confused how I would deal with really large
> datasets (the database we use at the office is several gigabytes in size
> for example - nearly 6 million products and a million-ish customers)...
> but I suppose that will come.
>
> > This also has a very nice benefit when you're building your
> application.
> > You can just skip writing any of the peristance code, and just let the
> > service manage the in-memory cache, and have a fully functional
> > application
> > without a database at all. Of course, the data won't survive a
> restart,
> > but
> > it lets you build the entire application without having to deal with
> the
> > persistance model until the end, which is a VERY nice feature.
>
> This is actually my problem - this is how all the books I've read pose
> things: as if there is an effectively infinite amount of space for these
> object models to float around in. For example one of the early classes
> I took modeled a Video Store - with "Tape" objects. It worked of course
> - but immediately places all the tapes into an array in memory - all 20
> or so of them.
>
> The class, unfortunately, never really explained how this would work
> with 10,000 tapes. ;^)
>
> I know it DOES work somehow - but it's that leap from limitless theory
> to cold reality that I'm having trouble with.
>
> Thanks for the help. I'm still open to suggestions, but you've given me
> an (I think) a good path to follow.
>
> Jim Davis
>
>
>
~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~|
Archives: http://www.houseoffusion.com/lists.cfm?link=t:4
Subscription: http://www.houseoffusion.com/lists.cfm?link=s:4
Unsubscribe: http://www.houseoffusion.com/cf_lists/unsubscribe.cfm?user=89.70.4
Signup for the Fusion Authority news alert and keep up with the latest news in
ColdFusion and related topics.
http://www.fusionauthority.com/signup.cfm