Re: The wisdom of the object mentors (Was: Searching OO Associations with RDBMS Persistence Models)
Date: Thu, 1 Jun 2006 15:26:57 +0000 (UTC)
In article <1149172334.971049.210600_at_u72g2000cwu.googlegroups.com>,
Marshall <marshall.spight_at_gmail.com> wrote:
>Christian Brunschen wrote:
>> For a trivial example, consider an application that needs to somehow
>> authenticate users (because different users have permission or not for
>> different parts of the functonality of the application. The user
>> information (name, password, etc) will have to be stored somewhere - a
>> relational database might be an excellent place, in particular if this
>> application is essentially a stand-alone one.
>> However, it might be that the application is intented to be integrated
>> into an existing infrastructure, that has user information stored in an
>> LDAP-accessible database; or for another example, the user information
>> might be stored in a Unix-style flat file (a la /etc/passwd).
>> By separating out the logic that handles any interaction between the
>> chosen database into separate, database-specific modules that share a
>> common interface, the rest of the application can remain identically the
>> same, with only the database-specific parts needing to be plugged in or
>> out, depending on the precise environment where the application is
>There's a severe problem with that logic, though.
>If you want to build a layer to wrap a variety of different storage
>mechanisms, that layer *cannot* be any more powerful than
>the weakest mechanism you want to layer on top of. Which
>means your very high level, very powerful SQL dbms will
>be stuck at the level of the stupidest file store ever invented.
That's not true.
*If* all the wrapper did was translate APIs, *then* it might be true. However, the wrapper can itself choose to delegate functionality, or implement it itself if necessary.
>And in swoops the application programmer to "save" the day
>from the problem he invented! All he has to do is write that
>subset of a DBMS that he needs today. Which will slowly,
>over time, increase until it's a badly implemented, bug ridden,
>ad hoc implementation of half of a database. This is
>Spight's Law. You have to have a dbms, whether you
>use a good one or reinvent it yourself, badly.
This argument can actually be generalized to any service: If you want to use a service, and you don't have that service available, you have to implement it yourself - or at least those parts of it that you need. f you only need a small subset, that may not be a problem; if you need all of it, you may end up having to write the whole thing. This isn't in any way special for databases. If you need to have multiple concurrent communication channels open to adifferent device over a single underlying channel, you can either use existing, concurrent-channel-capable services (such as using PPP over the serial link to connect to the device, and simply opening multiple TCP/IP connections to it), or you will have to write a service - in this case a communications protocol - that manages to multiplex your severl channels over the single underlying one. Yet precisely that solution may in fact be the better one for the specific problem, for instance if the other device is an embedded one and has no room for a PPP and TCP/IP stack, but since your problem only needs part of what TCP/IP-over-PPP offers, implementing your own small, specific protocol is a solution that works, and is entirely appropriate.
So basically: for any service you use, you need to either get an existing implementation that offers you everything you need, or write at least parts of it yourself.
In *many* cases, using an existing, pre-built relational database - or a pre-built implementation of whatever service it is you need - will be exactly the right thing to do. But in some other cases, where the full strength of the relational model is not needed, and indeed other concerns may be more important (performance for instance), the appropriate solution may be to use a less powerful underlying mechanism, and implement on top of it precisely those parts of a database management system that you need. (In which case one should, of course, read up on how best to implement those features, and implement them well.)
To reconnect this to the authentication example, there may be an existing system in place for some of the application's deployments which offers user authentication out of the box; in that case, the wrapper will be a very thin one. In other deployments, no such service might exist, but there might be an RDBMS available. In this case, the RDBMS may offer less functionality than the pre-built user-authentication service we had available in the first deployment; however, using the RDBMS to store the usernames and encrypted passwords, and using suitable select statements, we can implement a user authentication service using the RDBMS as one component, and implementing any missing functionality within the wrapper.
>To put it in the terms of application programming, it is as if
>we decided we want to be able to swap our programming
>language one for another at will. So we can't use any features
>of any programming language that isn't in all of them.
>Oh, and we want assembly to be on the list.
Again, please see the discussion above. That there might be a lack of certain features in some of the available services does not preclude more powerful services being built on top of them, as long as it there is a sufficiently powerful extension facility available.
The example of assembly language is rather cute; but then, from assembly language it is quite possible to call into functions written in C, or any other language, or into a Smalltalk runtime system, etc ... So in a system where one wants to be able to use assembly language, there's actually no reason to not write parts of that system in some other arbitrary language, and indeed using arbitrary features from those languages (as long as there is a working interface between the two).
// Christian Brunschen
? Received on Thu Jun 01 2006 - 17:26:57 CEST