Reputation: 3182
I wan't to create Actors
that are tied to a World
. I'm thinking of using one of the two following code fragments. Which one of these is considered the better design? By better I mean, more readable for source code maintainer, more readable for someone just reading through the code, more flexible for future adjustments, etc.
I'm sorry if a similar question has already been asked, but I don't really know what a concept like this is called in OOP.
Option A:
// declaration:
class World {
public:
RegisterActor(Actor* a);
};
class Actor {
public:
Actor(World& w) {
w.RegisterActor(this);
}
foo();
};
// usage:
World myWorld;
Actor myActor(myWorld);
myActor.foo();
Option B:
// delcaration:
class Actor;
class World {
public:
Actor& CreateActor();
}
class Actor {
friend class World;
public:
foo();
private:
Actor();
};
// usage:
World myWorld;
Actor& myActor = myWorld.CreateActor();
myActor.foo();
Upvotes: 2
Views: 157
Reputation: 6264
Does an Actor only ever belong to exactly one world at all times, and always the same one? Option B fits the situation best. It limits the visibility of the Actor constructor and uses a factory method to construct instances. That makes fewer commitments to clients of your code, and that means you have more flexibility to change the implementation of Actor. It also fits the semantics of the domain pretty well - you use your World to make Actor.
However, if an Actor could change worlds, or be registered to more than one world at the same time, then you're heading towards Option A.
It all depends on how your references need to end up.
Upvotes: 1
Reputation: 14279
The only difference I really see in the two is that in B, an actor is tied to world. It is not tied to a world in A. If an actor ever needs to exist outside the context of a world, or if an actor can exist in multiple worlds, I would vote for A.
In terms of future extensiblity, you may want to consider changing the actor base class to an interface. Then anyone would be able to add their own actor classes without needing to inherit from your base.
Upvotes: 0
Reputation: 1693
As usual it is hard to tell without the full usage context, but there are surely some pros and cons to evaluate:
In the first case
Actor
class it could be easily decoupled to work against an interface or contract. As your code is right now you could pass an Actor
's subclass and the world would never know. This has the advantage that you lower the coupling between a world and its actors.World
class to achieve the SRP, makes it easier to run unit tests (e.g. to pass a mock object) and is more flexible for the client. On the other had, this moves the work of creating (and eventually configuring) the actor instance on the client.In the second case you get the inverse pros and cons of the first one; the world is tightly coupled with the actor, making it harder to configure and test, but you require your client to know less about the process of creating an actor.
An alternative that you may consider is the use of a builder (if the process of a World
creation is a complex one) or a factory (if you have different configurations for creating different subclasses). This can help you to keep your World
class decoupled form the actors while leveraging from the client the complexities of creating it.
HTH
Upvotes: 3
Reputation: 14874
First thought : Factory Pattern, when creating an object is complex then another class will be defined which handle this job.
Second: If creation is easy then it could be a simple constructor, then you set one of it's properties by calling a method.
Third: If there exists an Aggregate object which is World maybe, then you can ask him to create an actor for you, it depends on your domain.
Upvotes: 0
Reputation: 80192
When in doubt on which class should contain the responsibility, I suggest you decide based on General Responsibility Assignment Software Patterns (GRASP)
Upvotes: 0