From kragen@dnaco.net Sun Aug  2 14:49:12 1998
Date: Sun, 2 Aug 1998 14:49:12 -0400 (EDT)
From: Kragen <kragen@dnaco.net>
To: Jim Weirich <jweirich@one.net>
cc: clug-user@clug.org
Subject: Re: OO in non OOP languages
In-Reply-To: <13764.42245.943713.905091@localhost.localdomain>
Message-ID: <Pine.SUN.3.96.980802143138.21649e-100000@picard.dnaco.net>
MIME-Version: 1.0
Content-Type: TEXT/PLAIN; charset=US-ASCII
X-Keywords:
X-UID: 969
Status: O
X-Status: 

On Sun, 2 Aug 1998, Jim Weirich wrote:
> >>>>> "Kragen" == Kragen  <kragen@pobox.com> writes:
> Now I need a metric for polymorphism.  Do you count the number of
> polymorphic calls made?  The number of classes that are used
> polymorphically.  Here's one suggestion: calculate the ratio of
> abstract and interface classes to the total number of classes.

That's a good idea. 

How about this: count the number of well-defined interfaces with
run-time polymorphism that have at least two implementations.  So a
concrete class that has a derived class that overrides some of its
virtual methods would count; a struct of function pointers would count,
as long as at least one of those function pointers could point to at
least two different functions; an abstract base class would count if it
has at least two classes derived from it that override the methods it
defines in different ways.

I'm not sure what to use as the denominator; some kind of measure of
the size of the design.  I do *not* want to use lines of code or
function points, because they don't necessarily measure the complexity
of the design.

As an example, the 2.0.30 Linux kernel is something like 750,000 lines of
code, or 25,344K.  Half of that (12,418K) is device drivers.  Adding a
driver for another device does not significantly increase the
complexity of the design -- unless you have to make changes to other
parts of the kernel to support the driver's functionality.

Another 4,624K of the code is architecture-specific; the i386 directory
is 748K.  If I understand correctly, each of these arch/ directories
plugs into the kernel to provide architecture-specific functionality in
much the same way device drivers plug in to provide device-specific
functionality.

I want a design metric that is approximately the same size for a kernel
source tree with two architectures and two device drivers of each type
as for the full-blown source tree, because I believe that the
conceptual complexity of the two is approximately equal.

> Abstract classes are almost always meant to be used polymorphically so
> that seems a good number.
> 
> So, for the persistence library we get ...
> 
> Total number of classes:                 9
> Number of abstract or interface classes: 8
> Polymorphic Ratio:                       89%
> 
> Ok, not "dozens", but at least 8.

 . . . so there's only one concrete class, and it implements 8 interfaces? (?!)

> [1] I love this.  Database venders would just *love* for you to
>     sprinkle calls to their proprietary libraries throughout your
>     code, making it difficult to migrate to different venders of
>     course.  This library turns that on its head so that the
>     application code is almost totally dependent on the library.

Yes, I agree that this is very important.  What's the interface to this
library?  JDBC?  Or does the library speak JDBC to the database?

Kragen


