[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