2

A few years ago I designed a class which had two properties. The two classes ChildA and ChildB had a rich protocol with many properties and methods, but were only distantly related in my model. They both descend from a class DatabaseEntity, which stores a GUID ID. However, there are several different base classes in between in the hierarchy and this relationship is quite trivial. A lot of my classes descend from DatabaseEntity. Over time, two more classes were added to this pattern, so today we have something like this:

public class Parent
{
  public ChildA TheChildA { get; set;}
  public ChildB TheChildB { get; set;}
  public ChildC TheChildC { get; set;}
  public ChildD TheChildD { get; set;}
}

The properties are mutually exclusive: an instance of Parent must have one ONLY of either TheChildA, TheChildB, TheChildC or TheChildD; else these are set to null. The properties are backed by private fields and when one it set to an object, the others are set to null.

My question is this: is it better to plod on as it is, perhaps adding another class to this pattern every 2 years, or refactor and replace the property with a single interface like this:

public class Parent
{
  public IChild TheChild { get; set; }
}

I can then make each of ChildA, ChildB etc implement this interface. It would not be a marker interface; the interface would have perhaps only two members though, and those members wouldn't be that important. In contrast, the Parent and child classes have a hundred or more members.

Does my original pattern represent a particular type of 'code smell'? And does my proposed refactoring conform or represent any particular design pattern or recommended software practice? It strikes me that having maybe two mutually exclusive properties may be acceptable, but having several means the code is quite messy.

  • How important type of child is to parent? Is parent's behavior significantly affected by replacing a child of one type with another? – Basilevs Jul 16 '18 at 19:28
  • @Basilevs yes the type of child is crucial to the behaviour of the parent – user2882061 Jul 16 '18 at 20:03
2

I decided to create an interface which all four child classes implement. I then replaced the four properties with a single property. Unfortunately 350+ references to the child classes had to be manually changed.

This design ensures that it is not possible for invalid states to occur such as two children being non-null (they are mutually exclusive). It allows for more polymorphic behavior as the child classes had common functionality. This resulted in more elegant and less repetitive code.

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service, privacy policy and cookie policy

Not the answer you're looking for? Browse other questions tagged or ask your own question.