From: Corey Date: 2004-11-13T10:20:43+09:00 Subject: Re: advice for a class implementation? ( ugh, long... ) On Thursday 11 November 2004 03:13 pm, Florian Gross wrote: > I think the problem is that you want to make the SQL adapter more > efficient than just pulling all the Objects out of the database and then > operating on them in RAM. I'd suppose you want to use SQL queries here > instead. > Affirmative. > I would expect the problem space to get a lot simpler if you'd > decide to use a prevalence system instead. > I'm not quite sure what you mean by prevalence system. > If you really want to use a SQL backend, this might work: > I would like the ability to be able to choose backends - whether it be an xml file, a sql db, or even a yaml file or an oodb. My purpose behind this being that it makes for a more difficult project - as this whole task is merely an assignment to myself to jump into ruby as thoroughly as possible. So, I want the datastore to be abstracted/plugable, and as transparent to the user as possible. > Have QuoteCollection::SQL and QuoteCollection::XML both implementing the > same interface that always return Quotes. I don't think an abstract base > class (QuoteCollection::Base) would make much sense here because it > doesn't seem like there's any functionality that those classes would share. > Yes - I think you're right. But what's adding to my confusion is this: Though the various backends/datastores ( QuoteCollection::#{persistence} ) won't share any actual implementation - I _do_ want to ensure that they will all share the same _interface_... I want them all to have the same public methods ( though, of course, not necessarily the same private methods or the same public/private attributes ) so that from the user's perspective, it will appear that they in fact do have the same functionality. More about this further down below. This is why I had the notion of a base class for QuoteCollection. I guess there is no way in ruby for me to formally enforce an "Interface" that all QuoteCollection::#{persistence} classes must share. That being said, in response to an earlier post of mine, it was suggested that I do things in the ruby-way rather than try too hard to bring old habits from other languages. I totally agree with that advice - my aim here is to understand/learn the ruby idioms. > If you would base your application on a prevalence system you would just > need to provide different constructors (.from_xml and .from_db) for one > single QuoteCollection class that just uses Quotes internally. > Thanks for your advice here - this suggestion of yours, as well as your first suggestion to create QuoteCollection::SQL and ::XML classes was very helpful and got me to thinking. After pondering over all this, I realized that I was definitely missing something that would allow all these pieces to work together. Turns out there were two things. I believe I was trying to overload the QuoteCollection class with more functionality that it should be responsible for. So, I've decided to first of all make the QuoteCollections extremely stupid - a QuoteColection itself only knows that it's a container for something, namely quotes. A QuoteCollection has no insight into exactly what a Quote is, only that it has one or more of them, and it only deals with them under its own native storage format ( xml, sql, yaml, etc ) - it is only able to add them, remove them, iterate through them, and dispense them.... it's relegated to being nothing more than a sort of Quote filesystem - it doesn't try to be an editor or pager. Then of course I have the Quote class - which is _really_ stupid: being nothing more than a collection of attributes which describe a quote. A Quote requires only two of its attributes to be populated in order to be a Quote, namely @quotation and @source, every other attribute is merely optional meta-data. A Quote only contains state, it has no behavior ( unless you consider instantiation and attribute accessors to be behavior. ) -- it has no concept of persistence, or various data formats, or anything. So what I need now is a "QuoteMachine" class... it provides the necessary interface between Quotes and a QuoteCollection. It will be through the instantiation of a QuoteMachine by which the means of normalized interaction/access to any particular QuoteCollection will be performed. This will be how the user searches Quotes, and displays Quotes, removes/adds/modifies Quotes, etc - the QuoteCollection backend and the Quote class itself will be totally transparent... QuoteMachine will have .from_collection and .to_collection private methods that will fullfill the roll of translating a Quote object in/out from a QuoteCollection::#{persistence} data format. Finally, there will be various frontends for actual end-users ( rather than programmers ); i.e. I'll start with a simple command line interface, then I'll tackle a web-based frontend in order to get me up to speed on Rails ( no pun intended ). Does this sound like a reasonable/workable model for what I'm trying to accomplish? Any hints/tips/advice regarding this design, or should I just shut-up already and start hacking! (c8= > I'm not sure if this is the best or most professional way of doing > things, but I would expect it to work. > Thanks for the assistance! Beers, Corey -- Every man who puts money into the hands of a "government" (so called), puts into its hands a sword which will be used against himself, to extort more money from him, and also to keep him in subjection to its arbitrary will. - Lysander Spooner, 'No Treason. No. VI, The Constitution of No Authority'