[MUD-Dev] (no subject)

KevinL darius at bofh.net.au
Tue Nov 21 11:37:55 CET 2000


>>> "John Buehler" wrote
> >From: KevinL <darius at bofh.net.au>
> >Date: Mon, 20 Nov 2000 13:07:01 +1100
> >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.
> 
> Until you realize that you need to toss in another door.  Maintenance of
> these systems is where things start to fall down.  We've been able to get

Um - that's _exactly_ what I said ;)

> >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 idea of bringing together behaviors must be done very carefully.

[snip]

> material types).  Strictly establishing those contracts enables the designer
> to discover if he's trying to construct something that is either ill-advised
> or impossible.  Defining and manipulating software contracts was a focal
> point of the research.

Again, exactly what I was referring to.  We're in agreement on the problems ;)

> >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).
> 
> Sorry, you lost me.  As you say later, terminology in this area is a bear.

*nod*

Essentially, by inheriting, you're assuming that one of the parent objects 
will take full responsibility for the behaviour - one parent or another will 
win out wrt: what attributes are inherited, where they clash.  If you're 
componentising, you can list all the different values for the different 
attributes (in essence), and write something to control that.

For instance, going with the materials example, if I inherit from cloth and 
steel, one or the other object is going to provide the "burnability" rating.  
If I have an object that contains both cloth and steel objects, and that 
object knows how to manage holding both objects, it can merge the burnability 
ratings of both, or it can burn one but not the other, or whatever.

The implementation aspects in inheritance are simply provided by one or the 
other parent.  In component systems, each component gets a chance to have it's 
say, but it's more likely that you're going to take those decisions out of the 
hands of the components, and manage it elsewhere - probably in the main object 
you're creating.

Note, this could just as easily be managed with a system that allowed you to 
refer to your parents explicitly - if I inherit from steel and cloth, I can 
easily intercept a request for burnability, query all my parents explicitly, 
and make the decisions myself, ala component systems.  So this vague 
difference between "contains" and "is" is what I'm trying to plumb, 
specifically in cases where you can have multiple (parents or components) but 
the collision between them needs managing.  If you don't need multiple 
(parents or components) then there doesn't appear to be a problem - likewise, 
if you need multiples but there's no collisions, there's no problem, the 
behaviour is identical (AFAICS) between inheritance and component.

I'm arguing myself into understanding, basically ;)

> >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 ;)
> 
> Inheriting implementation is the problem.  When you inherit implementation,
> you have two pieces of software (base and derived classes) that do not have
> a clear contract between them.  What is the base class responsible for and
> what is the derived class responsible for?  What happens when you inherit
> functionality from the same class along two different lineages?  I guess
> these are the collisions that you're trying to resolve.

Hrm.  I've not had any problems of this sort - I'm using inheritance to define 
behaviour.  The example I keep giving is the creator example - there's a bunch 
of methods that make up the "creator" abilities - things like create, destroy, 
edit, set - which all belong to a single object.  Inherit from that object, 
and you become a creator.  The base class is responsible for anything the 
child chooses not to take responsibility for - which strikes me as the same as 
component systems.

But I'm still not clear on what's meant by "implementation".

> Whenever you think inheritance, think composition instead.  What if, instead
> of inheriting some chunk of functionality, you built it into a
> self-contained service component that provided the same functionality?  That
> service component now has to have clearly-defined behavior that anyone can
> reuse.  Further, you can use that service component multiple times in the
> same component for different purposes.  That is, you can create multiple
> copies of it for your different purposes.

It seems to me that you're solving problems I wouldn't approach with 
inheritance - inheritance solves the "how do I make something that is x, y, 
and z" really well, whereas composition solves "how do I make something that 
provides x, y, and z" - the is-a vs. has-a thing I mentioned first time 
around.  Then you're saying replace inheritance with components.  I can 
understand the first bit - they are two different approaches that have their 
own values - but I can't understand why you'd want to use components where 
inheritance fits well.  You hold up resolving collisions as the main 
advantage, but you still have to resolve them the same way I do with 
inheritance - manually state which behaviour or how to merge the behaviours.

Then again, it has been noted already elsewhere that I think funny, so maybe 
it's just me not understanding.

> Think of implementation inheritance as a poor-man's component system.
> Inheritance systems tend to have a fairly compact notation for the
> compositions, and they are accomplished by 'inheriting' implementations.
> But that's what a component is - an implementation (of a specific behavior).
> Your comment about added complexity is off the mark, I believe.  If I give
> you a component language and some starting components, you'll be like a kid
> in a candy store.  Or perhaps I should say: a kid in a lego store  :)

Yeah, possibly.  But I haven't seen what components do that inheritance 
doesn't yet.  I'm going to accept that it's better, because there's a lot of 
people saying it's better, but I can't put my finger on _why_.

The example of needing doors in rooms - well, at the moment I have doors as 
objects in their own right, they happen to exist inside rooms.  That's a 
primitive version of components, and I can see a component system working 
nicely for that sort of requirement.  But I can't understand why people are 
convinced it therefore also does a good job where multiple inheritance does a 
good job - in defining the race, general abilities, etc. - the "class" of 
creature or object or whatever, which is how I'm proposing to use it in 
Moebius.  If you want to mix object type a and object type b, inheriting from 
both works nicely.  If you want an object to contain potentially multiple 
instances of x, then use a component system.  Yes?

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