Although this is a gamedev project, the question is about general OOP practices, so I believe it goes here. Here's the problem: (note: I will call any equivalent of real-world physical objects "entities" from now on; e.g. a rock in the game is an entity)
A specific class:
class Character
{
public/private CharacterInventory Inventory;
public/private CharacterStats Stats;
public/private CharacterEquipment Equipment;
}
Inventory functionality is self-contained in the CharacterInventory class. Same goes for stats. My aim is to make each character in my game a self-manageable entity. What do I mean by this? To put it plainly, I want to design the base Character class so that in the end I get an object that reacts in its entirety even when the smallest change occurs, in any of its components. To make things clearer, here's an example: when an item that changes the strength of the character gets equipped, the CharacterEquipment component of Character gets updated. At the same time, the Character will call the Stats object to change the strength attribute.
I've thought about doing this using events. Character subscribes to Equipment's OnEquip event, and in its handler, tells the Stats component do do its job. I believe this is an elegant enough solution; my issue however lies somewhere else.
I've got two ways in which I can update the character's inventory. First, by making the inventory (and any other component) private and providing a public method inside of Character, that does the work of calling the appropriate update method in the inventory. Like so:
Character chara = new Character();
chara.AddItemToInventory(SomeItem);
The 2nd way is by making the components public and accessing them like:
Character chara = new Character();
chara.Inventory.AddItem(SomeItem);
To me, both ways seem roughly equivalent in terms of readability. But the 2nd way seems like it's breaking the whole "self-manageable" idea. Basically, I'm invading the "private" space of the character. By going with the 2nd way, I can hook to the inventory events from some other place, but then again, this breaks the main idea even further. However, going the 1st way, I get the impression of writing duplicated code; even though it's not! I think the impression is given to me by the fact that Character.AddItemToInventory(...) and CharacterInventory.AddItem(...) share enough naming similarities to suggest duplicated code.
To be sincere, I'd go the first way, even though it seems to me like an extra layer of code. Then again, to make the character a self-manageable object, an extra layer of security is essential. But I'd like to hear from people more experienced than me. Are there any advantages to the 2nd way? Any severe disadvantages? I just can't get over the impression that I'm writing extra, unnecessary code.