I am in the process of refining my code to adhere more to my current understanding of the Single Responsibility Principle (SRP). Originally, I had a class called Animal that had a set of methods and several instance variables. According to the SRP, the main idea is that a class is only supposed to change for one "reason." The inclination I got is that changing the behavior of an Animal and changing the properties of an Animal would be two separate "reasons" to change, so I figured I needed to use encapsulation to separate them.
As a result, I created an AnimalInfo class to act as a wrapper and store all of the Animal's variables. The issue I see is that now instead of just calling the variables themselves, the Animal has to call its AnimalInfo class to retrieve the info, as if it's no longer the owner of its own info. There are also cases where other classes want to access the information in an AnimalInfo class but only have access to the Animal, so I figured it made most sense to make getters and setters in Animal that call the equivalent in AnimalInfo. Example:
public class Animal{
private AnimalInfo animalInfo;
public void eatFood(int amount)
{
getFoodSupply().consume(amount); //Consume method behavior isn't important. Just an example.
}
public void sleep()
{
setSleepMode(true);
}
public void hunt()
{
setHuntMode(true);
}
public FoodSupply getFoodSupply()
{
return animalInfo.getFoodSupply();
}
public void setFoodSupply(FoodSupply supply)
{
return animalInfo.setFoodSupply(supply);
}
public boolean setSleeping(boolean sleep)
{
return animalInfo.setSleeping(sleep);
}
public boolean setHunting(boolean hunt)
{
return animalInfo.setHunting(hunt);
}
public boolean isHunting()
{
return animalInfo.isHunting();
}
public boolean isSleeping()
{
return animalInfo.isSleeping();
}
}
public class AnimalInfo()
{
private FoodSupply foodSupply;
private boolean sleeping;
private boolean hunting;
public FoodSupply getFoodSupply()
{
return foodSupply;
}
public void setFoodSupply(FoodSupply supply)
{
foodSupply = supply;
}
public boolean setSleeping(boolean sleep)
{
sleeping = sleep;
}
public boolean setHunting(boolean hunt)
{
hunting = hunt;
}
public boolean isHunting()
{
return hunting;
}
public boolean isSleeping()
{
return sleeping;
}
public AnimalInfo getInfo()
{
return animalInfo;
}
public void setInfo(AnimalInfo info)
{
animalInfo = info;
}
}
The impression I get is that these "throughline" methods are unnecessary. I only added them in the interest of readability, as one result of this strategy has been a heavy amount of multiple method calls on one line( getThis().getThat().doThis()), and I'm not certain that's best practice.
On a broader scale, am I off-base in my idea to implement an AnimalInfo class for SRP? Should the getters, setters, and variables just be part of Animal? It seems to me that I've sectioned off a class just to store the instance variables and getters/setters, but it's not actually reducing the total number of methods since I'm making more getters and setters to account for the extra method calls. Should it be encapsulated based on a different metric other than behavior/data? Should AnimalInfo be a nested class within Animal since the two will always exist together? I didn't think it was necessary since AnimalInfo never needs to access the methods in Animal, only the other way around.
Something about my current strategy seems wrong. What am I missing?