I am currently facing the following scenario:
- When defining the requirements of my system on a piece of paper, I described two different entities
A
andB
(e.g.Cat
andDog
) - After listing what
A
andB
should do, they ended up having the exact same behavior requirements (e.g. the behavior of anAnimal
). - To reflect that, I implemented
A
andB
as classes and both inheriting fromC
(e.g. the abstract classAnimal
).
Should A
and B
be kept as classes or should they be removed from the architecture altogether, only keeping C
? Is this a sign of a problem in the architecture of this solution?
Example:
Suppose I am implementing a pet shop system and I have the following requirements:
- My pet shop can groom cats and dogs
- When a cat is groomed the dead fur count should be zero
- When a dog is groomed the dead fur count should be zero
To solve this problem I implement the following tests:
[Test]
public void When_DogIsGroomed_Should_DeadFurCountBeZero()
{
PetShop petShop = new PetShop();
Dog dog = new Dog();
petShop.Groom(dog);
Assert.AreEqual(0, dog.DeadFurCount);
}
[Test]
public void When_CatIsGroomed_Should_DeadFurCountBeZero()
{
PetShop petShop = new PetShop();
Cat cat = new Cat();
petShop.Groom(cat);
Assert.AreEqual(0, cat.DeadFurCount);
}
With the following implementation code:
public abstract class Animal()
{
public int DeadFurCount { get; private set; }
internal void Groom()
{
this.DeadFurCount = 0;
}
}
public class PetShop()
{
public void Groom(Animal animal)
{
animal.Groom();
}
}
public class Dog(): Animal
{
}
public class Cat(): Animal
{
}
I this example, should Cat
and Dog
be removed, thus only remaining with Animal
for the solution final architecture? Are those empty classes a bad sign or design?
One thing I fear about removing is that my tests would be less representative of the system I am implementing. After all, my requirements talk about dogs and cats, not animals. But at the same time, empty classes are usually a smell.