From: Brendan Guild on
H. S. Lahman wrote in news:dAjOg.11713$xC3.3610(a)trnddc06:

> Responding to Guild...
>
> The problem is reading the attributes because they are not in
> [ConcreteA], they are in [ObjectA]. So the saveIt() method in
> ConcreteA must navigate the R1 relationship to get to them rather
> than the 'this' pointer. If R1 is implemented as a pointer, then
> the address of that reference with be exactly the same as the
> address provided by the 'this' pointer. The only difference is
> that the 'this' pointer in Serializer is hidden while the R1
> pointer in the deconstructor approach must be explicitly
> implemented, instantiated, and navigated.
>
> In the Serializer case somebody had to "walk" the objects in
> [ObjectA] set and invoke the Serializer's saveIT() (or whatever)
> protocol method for each object. Somebody has to do the same
> thing for the deconstructor approach. When they do so, they must
> instantiate the R1 pointer to the current ObjectA in hand before
> invoking saveIt() to be sure saveIt() gets the right attribute
> values.

If I understand this correctly, the ConcreteA class will have only
one object and the persistence encoding algorithm walks through the
relationships of the objects to be encoded. Each time it encounters
an object it finds the appropriate 'saveIt' object, i.e. the lone
instance of ConcreteA or ConcreteB or ConcreteC, depending on the
class of the object to encode and using dynamic cast if polymorphism
is involved.

Earlier, you said, "When you read the object type you can instantiate
the R1 relationship so that ObjectA is processed by the ConcreteA
deconstructor when saveIt() is invoked. Essentially what you have
done is moved the polymorphic dispatch from the object to be saved
into a GoF Strategy pattern."

I am sure that the Deconstructor class and its subclasses are the
strategies, even though the GoF specifically say that the Context
object has a reference to its strategy. But I cannot see where
polymorphic dispatch is involved here. I presumed that it had been
sacrificed when we abandoned the Serializer pattern to avoid coupling
with the persistence.

Assuming that you literally meant that the Decontructor was following
the Strategy pattern and therefore each ObjectA must have a reference
to the unique ConcreteA, then I have another interpretation of your
words: the factory does choose which Deconstructor goes with each
object and stores it in a reference for the life of the object, to be
used by the persistence algorithm and eliminating the need for
dynamic casts.

I suspected that was what you intended, but I made the leap to
assuming that each ObjectA would get a distinct ConcretaA. The
intentions are identical though one needlessly costs more in time and
memory.

In fact, I think this entire technique for persistence could be
simply described as the Serializer pattern, but with the
implementations of the 'Serializable' interface removed from the
actual Serializable class and into another object by using the
Strategy pattern.

That is very close to what you said, but I was confused by the idea
of moving the polymorphic dispatch, since the polymorphic dispatch is
not actually being moved but destroyed. It is the implementation of
the methods that is being moved.

It is interesting that this seems like something you could call a
poor use of the Strategy pattern, since every object of any
particular persistent class will share just one strategy object for
the entire execution of the software.
From: Brendan Guild on
I think you have lead me to a fundamental realization about my domain
that should revolutionize my design. I will explain my thoughts on
this matter below.

H. S. Lahman wrote in news:LWiOg.2317$yc4.1371(a)trndny01:
> Responding to Guild...
>
> Basically what I am hearing here is that you want to make this
> game up as you go along developing the software. I don't think
> that works.
>
> All software needs requirements and all software developers need
> to understand the problem domain /before/ the software can be
> built. Here the problem domain is a fantasy realm. You have to
> have a clear idea of how that realm works (i.e., what the
> requirements are) before you start designing software.

Even so, the fact remains that large areas of the domain are fluid
and uncertain. I know for a fact that no matter how carefully I plan
the initial design I will need extensive maintenance. Surely you are
not suggesting that it is impossible to create software under those
conditions. Even though this is only a game, I cannot change the
domain. So the question is, what is the best way to use OO design to
assist me?

Though I would not have worded it this way, until now my plan has
been to use an extremely abstract entity objects. For each one I
would represent physical properties as a collection of 'Property'
objects which are also extremely abstract, holding only a data value
and a 'PropertyType' reference to provide the semantics of the value.
The behaviour properties of the entities would be represented by a
fixed set strategy objects which polymorphically dispatched event
messages to low-level entity manipulation methods.

I could implement my entire design in this way by creating strategies
until all the desired entities were behaving as desired, with no
difficulty in adding or modifying entities except for the complexity
of working on such a low level.

Through reading this thread, I have come to realize exactly what I
need. Primarily, I need extremely high decoupling between entities.
It is a priority above all others that I should be able to add or
modify entities at will in any manner that satisfies the very
primitive fundamental structure of the domain without forcing even
the slightest modification to other entities.

Towards this goal, each entity becomes like a subsystem with the
properties acting as the data interface, though it is data by
reference to accommodate the necessity of entities modifying each
other's properties. Also, entities will naturally share classes and
stateless objects, but otherwise they will be quite separate.

Now the only problem is to overcome the complexity and maintenance
nightmares of dealing with the low-level property manipulation. I
suspect that this should be dealt with using your idea of role
objects. The only place lacking abstraction currently is within the
implementation of the entity behaviour, so let it be dealt with
independently. The behaviour strategy for each entity can assign
roles to each entity that it interacts with by wrapping the bare
Entity objects in more meaningful Role objects, such as Weapon,
Monster, Furniture, etc.

Just as you suggested, when a Monster picks up a Jaws to attack with,
the Jaws will be wrapped in a Weapon object because it is now
conceptually a weapon. The Weapon object will implement some or all
of the low-level property manipulation that goes along with using a
weapon but in an abstract way. No other Entity object needs to know
about the existence of the Weapon object.

I can use object-oriented design within the implementation of an
entity or even a large group of entities to greatly simplify the
otherwise low-level implementation, but that design is to be
encapsulated to always a subset of entities.

If I find that my abstractions and generalization for my current
entities are not allowing me to create a new entity which I need, I
can implement that new entity entirely independently with a
completely different object-oriented design.

This requires that the strategy objects will often carry state to
maintain their individual abstract views of the situation between
events. This state will be partially redundant with the state
contained in the entities themselves, but the strategy state will be
far more advanced and detailed, giving roles to entities which do not
otherwise have roles.

While it is true that one needs to know what is being designed before
design can begin, I hope to design each group of entities as
independently as possible and I think that something similar to the
above is the way to do that.

>> In an adventure game the thing that is being simulated is as
>> complicated as everyday life. It is people and creatures
>> interacting and fighting, collecting objects with magical
>> effects, etc. The variety of things that can happen is so large
>> that it is impossible to grasp the fundamentals, just as there
>> are no fundamental rules of what people can say and do in life.
>> (Aside from the obvious ones, but even those are lifted in a
>> fantasy game.)
>
> All commercial simulations abstract everyday life. That's what
> they do -- extract basic fundamentals from myriads of complex
> interactions.

They abstract things which exist in reality, but that is not what I
meant by 'everyday life'. I was hoping to convey connotations with
that term when I should have made more explicit. I actually meant
personal interactions between people and objects such as friendships,
employment, tools, clothing, buildings, the full range of objects
that an average individual would consider important during the course
of a single day, but nothing beyond that such as planets and
molecules and weather patterns.

Even those people who are concerned with the tanker charter market
would not consider it to be important in the span of a single day. It
is important in a span of years, over changing economic conditions,
and perhaps over months with changing gas prices, or even from week-
to-week in the salary of tanker employees, but it is not important
just for getting through a day.
From: Brendan Guild on
Dmitry A. Kazakov wrote in
news:1eqtbrnri1fcy$.yl9831mjokfa.dlg(a)40tude.net:

> On Tue, 12 Sep 2006 18:22:05 GMT, Brendan Guild wrote:
>
>> It depends on what you mean by similar. All properties
>> represented by numbers will be of the same type in the language,
>> and so will all properties represented by strings. I do not think
>> there is any benefit to creating more detailed types than that.
>
> Benefits are huge:
>
> 1. OO programming. You can't define different method on the same
> type

It has not been made clear why I might want to dispatch on the class
of a property. Properties are data objects for use by methods
expecting data of a certain type; I cannot imagine a situation where
there could be a choice about the type of the data, so I cannot see a
benefit to overloading on that type.

> 2. Static type checks

My properties will be drawn out of a collection, so their specific
subclass will be dynamic. Therefore, no matter how many subclasses
there are there will be no static type checks.

>> But each property type has different semantics and is used in a
>> different way and known about by different objects.
>
> = it is not single dispatch. When semantics sufficiently depends
> on both the type of Entity and the type Property that is
> equivalent to MD.

Could you expand upon that? MD can only exist in a method call, if I
understand it correctly, but it is not clear what method call you are
refering to.

>> A property does not know about entities, but there is an
>> outsider, called 'the client' who chooses an appropriate
>> behaviour for the entities. The client works with some
>> properties, entities work with other properties, and different
>> entities work with still other properties.
>
> And how the outsider decides when it makes what? If the decision
> is based on the types of Outsider, Entity and Property, that is
> triple dispatch. If the decision is based additionally on the
> values of, that is a total ad-hoc mess.

No decisions are made based on the type of Property. It does not make
sense to use 'Property' as a proper name like that unless you are
talking about the Property class, in which case there is only one
type. The reason is that every decision will involve multiple
properties.

Each individual property has its own type, but there are many
properties, not one Property, and in all the places were decisions
are made the types of the properties involved are fixed while the
values are used to calculate the results.

On the other hand, the type of the entity and the type of the
outsider are indeed used to make decisions, but only one of them for
each decision.
From: H. S. Lahman on
Responding to Guild...

>>What I am arguing against is the alternative that you seem to be
>>suggesting where all entity properties are dynamically added
>>rather than being intrinsic properties. In effect Entity then
>>becomes an abstraction that is so abstract that it only has two
>>properties: identity and a type. (You need the type to enforce
>>whatever rules exist to add properties to a specific entity.)
>>That's fine, but it has a huge drawback in an OO context. It does
>>not reflect the intrinsic structure of the problem space.
>
>
> Entities also have position in the simulated environment, and I think
> we should count the 'properties' collection as a property of the
> entities.
>
> I am seriously not certain that there is very much intrinsic
> structure to this problem space. These are the things that I can
> currently say with absolute certainty about the problem space:
>
> There is an environment that is represented by one or more two-
> dimensional grids of environment elements. At any moment there is a
> set of entities and each entity has a unique position, either as
> coordinates in the environment or within or upon another entity. It
> is possible to navigate positional relationships from any entity
> through any number of other entities to finally find coordinates in
> the environment. The set of entities and the positions of those
> entities can change from moment to moment, as can any particular
> environment element, but there will always be at least one entity and
> there will always be an environment element for every point on every
> grid.

I would expect the graphic representation is an entirely different view
of the entities than the game context view. Its abstractions would be
driven by the graphic algorithms and display paradigm, not game
semantics because it is an entirely different problem space. It would
normally be in a different subsystem.

While it may be convenient to have some location information in the game
view, the real "owner" of that information would be in another subsystem
and you would need some sort of synchronization mechanism to ensure the
game view was changed when the graphic (or map) view changed.

> I would like to say more, but I have deliberately excluded saying
> anything that is not fundamentally true of the problem space. For
> example: What is an environment element? It's a wall, an open space,
> perhaps a door, perhaps other things to be added in maintenance.
> That's fine, but what is a wall? It is an environment element which
> prevents entities from having the corresponding position. Except
> that's not true because there will be entities that can move through
> walls. There are a very large number of things which I know will be
> true in almost all cases, but there will also be a very large number
> of exceptions.

Then the semantics of the 'wall' abstraction changes. In the real world
there are bullet proof vests that are a barrier to most ammunition but
essentially transparent to full metal jacketed rounds coated with
teflon. Does that mean such vests can't be abstracted as bullet proof
vests?

> I am trying and I will continue to try to think of additional
> statements that I know will be invariably true, but an adventure game
> thrives on encountering new things and exceptions to rules.

I think you have to decide two things before you start developing the
software. First, are you developing a single fantasy adventure game or
some kind of tool for generating fantasy adventures games in general
(i.e., based on external specification of the game)?. If the former,
then you have to decide in basic terms what the rules are in your
particular realm for the way it works (i.e., what can and what cannot
happen there). If the latter, you will have an entirely different set
of abstractions than Troll, Wall, and Jaws. (I dealt with this in
yesterday's message, so I won't belabor it here.)

>>Imagine someone else built such an application and you came in
>>cold to maintain it. How would you understand what it was doing?
>>How would you understand what the real problem space structure was
>>at the moment? Most important of all, how would you understand
>>what basic assumptions about the problem space the original author
>>had made. It might be easy to add entities and properties but
>>just figuring where and how to do it safely would be a nightmare.
>>A large part of maintainability is an easily understood
>>representation of what is going on _right now_. Without that it
>>gets very tough to figure out what to fix.
>
>
> This is a very serious issue and one of great mystery for me. I have
> been so concerned about preventing the maintainer from having to make
> systemic changes when introducing new entities that the maintenance
> issue you raise here never occurred to me.
>
> What are the ways I can balance these two maintenance issues? I do
> not want to start introducing structure upon the problem space that
> does not exist there just to simplify the design, but I also do not
> want my design to be so nightmarishly complicated that it cannot be
> maintained. Perhaps careful documentation is the solution.

I think the root problem here is the assumption that maintenance can
change the way the game works arbitrarily. It can't. Certain changes
don't modify the game; they make it a different game. It may be a
fantasy realm but it still needs some set of rules and policies that are
invariant, just as our physical world needs the laws of physics to work
properly. You have to define that set of rules up front. Then you
build the application around them so that you can change the details
easily. But changing the fundamental rules once the software is
implemented will be a Big Problem and no software methodology is going
to avoid that.

For example, if some critters can move through walls in your realm,
that's fine. But when you allow that you also buy into defining how
that happens. Is it an identifiable characteristic of certain critters?
If so, is it inherent in the nature of the critter or is it learned
like a skill? Or does it require the critter to use some external
mechanism? If so, what sort of mechanism (e.g., spell vs. machine)?
How does the critter get such a mechanism and learn how to use it? IOW,
how your
From: Dmitry A. Kazakov on
On Fri, 15 Sep 2006 18:19:07 GMT, Brendan Guild wrote:

> Dmitry A. Kazakov wrote in
> news:1eqtbrnri1fcy$.yl9831mjokfa.dlg(a)40tude.net:
>
>> On Tue, 12 Sep 2006 18:22:05 GMT, Brendan Guild wrote:
>>
>>> It depends on what you mean by similar. All properties
>>> represented by numbers will be of the same type in the language,
>>> and so will all properties represented by strings. I do not think
>>> there is any benefit to creating more detailed types than that.
>>
>> Benefits are huge:
>>
>> 1. OO programming. You can't define different method on the same
>> type
>
> It has not been made clear why I might want to dispatch on the class
> of a property. Properties are data objects for use by methods
> expecting data of a certain type;

Hmm, you could say something like this about parameters of any subprogram
in a typed language...

> I cannot imagine a situation where
> there could be a choice about the type of the data, so I cannot see a
> benefit to overloading on that type.

Egh, I don't understand this either. Both overloading and overriding are
examples of polymorphism. In both cases the type is the thing that
determines the choice. So there is no difference between them in that
respect. I.e. the behavior is selected by the actual type (or, more
precisely, by a tuple of actual types.)

The question is very simple - what determines the behavior of Get and Set?
In particular, do the actual types of entity and property influence the
choice? If yes, then it is multiple polymorphism. You have a tuple of
selecting types. For dynamic polymorphism it is MD, per definition. In the
case of static polymorphism (overloading) we silently take "M" for granted,
it would be silly to overload procedures only in the first parameter,
right? So why the buzz in the dynamic case?

>> 2. Static type checks
>
> My properties will be drawn out of a collection, so their specific
> subclass will be dynamic. Therefore, no matter how many subclasses
> there are there will be no static type checks.

No. Even if you don't always statically know the type, in any real-life
program you still know them in 90% cases. So static checks give a huge
advantage, because they save 90% of debugging/testing efforts.

>>> But each property type has different semantics and is used in a
>>> different way and known about by different objects.
>>
>> = it is not single dispatch. When semantics sufficiently depends
>> on both the type of Entity and the type Property that is
>> equivalent to MD.
>
> Could you expand upon that? MD can only exist in a method call, if I
> understand it correctly, but it is not clear what method call you are
> refering to.

"MD in a method" is an implementation of the model, in which a tuple of
statically unknown types selects the behavior. You can implement it using a
switch statement, or a jump table, if you wanted. That does not change the
fact on the ground - you have to select according to more than one type.
One of the objectives of problem analysis is to determine if you really
have this. I.e. whether the selection could be somehow made on the types
involved independently. If it could, then it could be implemented using
single dispatch.

>>> A property does not know about entities, but there is an
>>> outsider, called 'the client' who chooses an appropriate
>>> behaviour for the entities. The client works with some
>>> properties, entities work with other properties, and different
>>> entities work with still other properties.
>>
>> And how the outsider decides when it makes what? If the decision
>> is based on the types of Outsider, Entity and Property, that is
>> triple dispatch. If the decision is based additionally on the
>> values of, that is a total ad-hoc mess.
>
> No decisions are made based on the type of Property. It does not make
> sense to use 'Property' as a proper name like that unless you are
> talking about the Property class, in which case there is only one
> type. The reason is that every decision will involve multiple
> properties.
>
> Each individual property has its own type, but there are many
> properties, not one Property, and in all the places were decisions
> are made the types of the properties involved are fixed while the
> values are used to calculate the results.

Fixed? You mean, they are statically known or they are somehow derived from
the actual type of entity?

The first case is static polymorphism in Property x dynamic polymorphism in
Entity. It can be easily handled using genericity (templates).

The second case is more difficult. It is a parallel types hierarchy - you
vary the type of Entity E1->E2 and the type of Property varies coherently
P1->P2.

> On the other hand, the type of the entity and the type of the
> outsider are indeed used to make decisions, but only one of them for
> each decision.

Yep, this is a equivalent definition of single dispatch (polymorphism). The
only question if this is a result of analysis or belief. (:-))

--
Regards,
Dmitry A. Kazakov
http://www.dmitry-kazakov.de
First  |  Prev  |  Next  |  Last
Pages: 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20
Prev: Name of construct
Next: Deriving - .NET example