[MUD-Dev] (no subject)

KevinL darius at bofh.net.au
Mon Nov 20 13:07:01 CET 2000


>>> "John Buehler" wrote
>   I'm just jumping into this discussion.  I'm not really picking on Kevin or
> Ben.

Fair enough ;)

>   Try this:  create components that implement well-defined behavior and
> stick 'em together to build up bigger components.  One example presented was

This is exactly how I approach multiple inheritance - it's a question of how 
you stick the components together, I guess.

> a room with a door and a room without a door.  What about a room with two or
> more doors?  Adding a door is a construction issue, not one of inheritance.
> Inheritance really isn't needed in most cases.  And I'm talking about one
> contract (set of behaviors with a given virtual table of functions)
> inheriting its definition from another contract.  That kind of inheritance
> is rarely needed, while inheritance of implementation is never needed.
> Create components from other components instead.  That way, all contracts
> that exist in the software system are actually materialized instead of just
> being a vaguely understood relationship between a base C++ class
> implementation and the derived class.

I had this discussion with a friend the other day.  The difference between 
'is-a' and 'has-a' relationships.  Here's my take on it, for what it's worth 
(very little):

You're right in the case of doors in rooms, where more than one door in a room 
is a reasonable occurence.  However, if you look at the situations where 
you've got only one instance of the behaviour occurring (for instance, adding 
"lockable" to a chest), you'll find very little difference between those two 
relationships.

I could make an object an open/close/lock/unlock object by either adding a 
component that describes those behaviours, or by inheriting from an object 
that describes those behaviours.  In actual fact, the difference is negligible 
- in both cases, I've added the behaviour, in both cases there's no chance of 
adding it again, or adding a similar set of behaviours that might clash, or 
whatever.

In fact, by componentising, you don't really solve the "collision" problem 
anyway.  The case I got into the discussion on in particular was materials - 
the difference between inheriting the attributes for "steel", and adding a 
component called "steel".  In the second case, you can easily add "cloth" as 
well (say, chain mail or something similar) - but the collision between the 
attributes of the two components still has to be managed in some way, the same 
as it would if you were inheriting.

The only difference I can really see is that, in inheriting, it's assumed 
you're picking between one or the other, and the behaviour is encapsulated in 
the object - whereas in componentising, you externalise the behaviour, and 
build yourself a way to handle both sets at the same time.  In that respect, 
it makes sense to use components rather than inheritance.  But then each 
object does not carry it's own behaviour itself necessarily - and in some 
environments that makes a difference (think, particularly, distributed objects 
where the objects can migrate from server to server - the object itself needs 
to know how to resolve conflicts anyway, so it's implementation might as well 
be inherited as componentised).

I will actually pick on a couple of points above (sorry ;) - you mention C++, 
I don't work in C++, and whether I did or not would be irrelevant, as the 
mud-level object system is (should be?) disparate from the language system, 
inasmuch as it needn't follow the same rules.  I could, in fact, implement 
some sort of "half-match" ability, so you can inherit from two objects that 
implement functions to call precisely to deal with collisions (although I'd 
count that a kludge fix).

I'd also say writing off inheritance of implementation as "never needed" is a
bit rash.  Can you explain what you mean by that a bit more?  At the moment,
I'm using multiple inheritance in a lot of cases specifically _because_ I want
to inherit implementation, I think (I'm not good with terminology, so precise
explanation here would be useful ;)

>   I spent two years working at Microsoft Research with Tony Williams
> (inventor of COM) and Clemens Szyperski (author of "Component Software :
> Beyond Object-Oriented Programming" and who is also a 'name' in the
> component world) and had my eyes opened to what component software can do
> and why the C++ implementation-inheritance approach is giving engineers lots
> of rope to hang themselves with.  Take some time to learn about component
> software and about strict contractual software development.  I believe that
> it's the future of software.  I'm very pleased that Dmitri brought up his
> 'atomic functions' topic because that goes hand in hand with where software
> must go in the future.  We will need transacted methods if we want to have
> the high quality reusable software that is one of the holy grails of the
> software world.  Funny how the database guys have known this all along...

I have books on COM and CORBA, I've implemented CORBA and XMLRPCish solutions 
to thing - but I haven't the names or experience you hold.  So I'll bow to a 
higher understanding than mine, but I'll note that for what we're doing, 
multiple inheritance and inheritance of the implementation of various small 
aspects of things is really elegant so far - easy to understand, easy to work 
with, extremely flexible.  Agreed for certain things it doesn't fit, but then 
for certain things components add a level of complexity that doesn't appear 
warranted.  Multiple inheritance in this environment just seems to "make 
sense".

KL

_______________________________________________
MUD-Dev mailing list
MUD-Dev at kanga.nu
https://www.kanga.nu/lists/listinfo/mud-dev



More information about the mud-dev-archive mailing list