Jump to content

  • Log In with Google      Sign In   
  • Create Account


Pointers to an instance's owner


Old topic!
Guest, the last post of this topic is over 60 days old and at this point you may not reply in this topic. If you wish to continue this conversation start a new topic.

  • You cannot reply to this topic
8 replies to this topic

#1 CramerFish   Members   -  Reputation: 108

Like
0Likes
Like

Posted 20 November 2012 - 08:31 PM

I have a question about the following design
class Unit {
  Manager *my_manager;
  ...
};

class Manager {
  vector<Unit> unit_list;
  ...
};
In the interest of encapsulation the Unit handles it's own actions (e.g. movement), the pointer to the manager is then required so that the unit can interact with other units (e.g. colliding). It feels like it's a hack, I've added in the pointer in the absence of a better design strategy. Is this an intelligent way to structure my code, or should I be looking for a different design pattern?

I'm from a Maths/Science background and so while I have done quite a bit of programming (FEM, graph theory, simulations) I haven't formally learned application programming. If there is a good book on how to design/structure a program that is more than just datain->process->dataout I would love to hear your recommendations.

Sponsor:

#2 Hodgman   Moderators   -  Reputation: 29568

Like
4Likes
Like

Posted 20 November 2012 - 08:45 PM

Bi-directional dependencies (Unit uses Manager but Manager also uses Unit) are a kind of "code smell": not necessarily a problem, but may indicate there's something wrong with the design.

One small step that you can try to take is to remove that member variable, and instead pass the manager as an argument when using the Unit. This is still a bidirectional dependency, but a little weaker.
class Unit {
  void DoStuff( Manager* );
};

If Units need to access each other for collisions, perhaps you can move the collision logic out of the Unit and into the Manager?

Alternatively, you can pass in the parts of the manager that the unit needs, instead of the whole manager:
class Unit {
  void MoveWithCollisions( const vector<Unit>& others );
};

Edited by Hodgman, 20 November 2012 - 09:24 PM.


#3 CramerFish   Members   -  Reputation: 108

Like
0Likes
Like

Posted 20 November 2012 - 09:27 PM

Thanks. I did think it smelled a bit fishy. I believe I have some thinking to do...

#4 Telastyn   Crossbones+   -  Reputation: 3726

Like
0Likes
Like

Posted 21 November 2012 - 09:39 AM

In my experience, this tends to go beyond even a code smell. It's an outlet for the instance to get at more things than even the manager. And there will be times when you want the object (even temporarily) not to be owned by anything. And keeping the collection and pointer synchronized is a little tricky once you start dealing with concurrency, serialization, and network operations.

#5 ChaosEngine   Crossbones+   -  Reputation: 2292

Like
1Likes
Like

Posted 21 November 2012 - 02:33 PM

In the interest of encapsulation the Unit handles it's own actions (e.g. movement), the pointer to the manager is then required so that the unit can interact with other units (e.g. colliding)


This right here is your problem from a design perspective. You say that the unit handles it's own movement "in the interest of encapsulation", but then immediately after state that the manager is required.

By definition, the units movement cannot be fully encapsulated as it requires external information to function correctly. The unit cannot move independently (it has to handle collisions etc). As Hodgman said, it might be better to move the unit movement logic out of the unit and into the manager.
if you think programming is like sex, you probably haven't done much of either.-------------- - capn_midnight

#6 Bacterius   Crossbones+   -  Reputation: 8584

Like
1Likes
Like

Posted 22 November 2012 - 01:00 AM

By definition, the units movement cannot be fully encapsulated as it requires external information to function correctly. The unit cannot move independently (it has to handle collisions etc). As Hodgman said, it might be better to move the unit movement logic out of the unit and into the manager.

+1, for instance the unit could expose its movement capabilities (range, etc...) to the manager, which will then use that information to move it correctly within the world, which allows you to abstract away unit types more comfortably.

The slowsort algorithm is a perfect illustration of the multiply and surrender paradigm, which is perhaps the single most important paradigm in the development of reluctant algorithms. The basic multiply and surrender strategy consists in replacing the problem at hand by two or more subproblems, each slightly simpler than the original, and continue multiplying subproblems and subsubproblems recursively in this fashion as long as possible. At some point the subproblems will all become so simple that their solution can no longer be postponed, and we will have to surrender. Experience shows that, in most cases, by the time this point is reached the total work will be substantially higher than what could have been wasted by a more direct approach.

 

- Pessimal Algorithms and Simplexity Analysis


#7 Bubsy   Members   -  Reputation: 407

Like
0Likes
Like

Posted 23 November 2012 - 09:18 PM

My take

I'd scrap the manager, at least for know, and create an Unit class hierarchy. It's a responsability of Units knowing what they are capable of doing, perhaps by returning a set of Actions. But the catch, to know which Actions they're are capable of doing, they must be supplied a context, or a World, the World responsability is to provide methods to query the spatial state of the Things (which can be Units) within itself.

Its a crude design, but I would start it like that.

#8 ChaosEngine   Crossbones+   -  Reputation: 2292

Like
0Likes
Like

Posted 25 November 2012 - 02:43 PM

I'd scrap the manager, at least for know, and create an Unit class hierarchy.


How does creating a Unit hierarchy help here?
if you think programming is like sex, you probably haven't done much of either.-------------- - capn_midnight

#9 Bubsy   Members   -  Reputation: 407

Like
0Likes
Like

Posted 25 November 2012 - 05:23 PM

Seems to me that the propose of the manager class as presented was to manage all the possible movements and iterations from every kind of units. (I'm assuming there're many kind of units), by doing so it would be coupled to every type of unit given. By moving the the movement logic to an Unit class hierarchy, this coupling is eliminated.

But you're right, external information must be given to an unit so it can know which movements they´re capable of doing within a context that is given in a World class object (which is similar to the manager concept, but with diferent responsabilities).

P.S. On this rationale, I was think on a board gaming, something like chess or checkers, maybe to other kind of games, those concepts would not cut ...




Old topic!
Guest, the last post of this topic is over 60 days old and at this point you may not reply in this topic. If you wish to continue this conversation start a new topic.



PARTNERS