Leszek Wiesner
Leszek Wiesner

Reputation: 155

How to determine which class should have a specified method

This is a question regarding the concept of OOP.

Let's say I'm creating a game and I have a few objects:

Now I know that player can dig a field using shovel. And this action will be a method of one of those classes. Is there some rule to determine which of those classes should have this method.

The most obvious performer of this action is the player (User), so User class could have method like digField(Field field). But actually the field itself is most affected by this action, so maybe it shold be the Field class method, like dig(User performer) or dig(Item toolUsed). Or maybe the Item itself should have a child class like Tool with a method like digField(Field field).

There are lots of ways to solve this problem and I was just wondering if there is some kind of simple best practice there.

Upvotes: 3

Views: 236

Answers (3)

Katie
Katie

Reputation: 2693

It depends on the rest of your game. You can't architect your classes without thinking about all of it. So questions such as:

  1. Are there many tools, do they perform different actions on different objects?
  2. Are there many types of land masses (field, stream, etc)
  3. Does the user have any effect (such as with strength) on the action

These types of questions are useful to think about before laying out your classes. As an example, if you have many different tools, then you could tie the digging with the shovel, which will detail what it does to different types of land (and which ones it can work with). Then maybe there is a tractor, which does something different to the land.

One last thought, the closer your classes match the real world, the better the classes work as the code expands. In other words, if you were describing a shovel to someone who has never seen one, your class should model itself after that kind of description.

Upvotes: 1

Michel Keijzers
Michel Keijzers

Reputation: 15367

Like said in other answers, it depends on what else is happening (or can happen in the future).

For example, for digging there can be some options:

  • user.digField(field, tool): this way can be helpful when your user also needs to spend time, or maybe he gets tired, i.e. use this way if you want to FOCUS on the user.
  • field.dig(user, tool): this way can be helpful when the field itself should be focussed on, like setting the status of the field.
  • tool.dig(user, field): this way can be used to change e.g. the status of the tool, or the maintenance needed.

However, in most cases there are a multiple of statuses/changes need to be set. So maybe it is best to create a separate class Action like:

public class Action
{
    public void DigField(User user, Location location, Tool tool)
    {
        user.Status = Digging;
        user.Energy -= 50;
        location.Status = Digging;
        tool.Status = Digging;
        tool.Usage++;
    }
}

As you can see this function may grow as action might get more complex. So what is a good way to call separate functions in the appropriate classes, like a mix:

public class Action
{
    public void DigField(User user, Location location, Tool tool)
    {
        user.DigField();
        location.Dig();
        tool.Dig();
    }
}

public class User
{
    public void DigField()
    {
        Status = Digging; 
        Energy -= 50;
    }
}

public class Field
{
    public void Dig() 
    { 
         Status = Digging; 
    }
}

public class Tool
{
    public void Dig()
    {
          Status = Digging;
          Usage++;
    }
}

This has the advantage to keep the functionality where it belongs.

Nothing prevents you from passing parameters, like if the energy drain for auser depends on the type of field, use:

public class User
{
    public void DigField(Field field)
    {
        Status = Digging; 
        Energy -= field.Type == Clay ? 30 : 20;
    }
}

Upvotes: 2

saheedmyself
saheedmyself

Reputation: 7

This not a case of overloading, I think you have recognise the complexity but you are trying to escape it. It's been you take time to model it now,it may be costly later.

Here is what I think:

User object performs the action so it must have the User.Dig() method. Maybe you can decide to pass in an Item object (eg Shovel).

Field object reacts to the action (Dig) of the User object. You now have to determine what this reaction is. Also you determine what the action is.

Like you said there are likely many approach and I think game engines have solved problems like this but I don't use them so I can't recommend. If I would have to model what explain I first try out Observable Pattern https://en.wikipedia.org/wiki/Observer_pattern?wprov=sfla1

Good luck

Upvotes: 0

Related Questions