When I try to follow the Open-Closed Principle (OCP), after number of implemented use cases I always end up with hierarchy of inherited classes. Usually it happens with ViewModels in MVVM structure, because they are being changed a lot. For example (C#, but could be any other class oriented language):
internal class MyAwesomeViewModel
{
private IDependency1 _dependency1;
public string Property1 { get; set; }
public ICommand Command1 { get; }
public MyAwesomeViewModel(IDependency1 dependency1)
{
_dependency1 = dependency1;
Command1 = new DelegateCommand(...);
}
}
internal class MyAwesomeViewModelWithAnotherProperty: MyAwesomeViewModel
{
public string Property2 { get; set; }
public MyAwesomeViewModelWithAnotherProperty(IDependency1 dependency1)
:base(dependency1)
{
}
}
internal class MyAwesomeViewModelWithNewCommandAndDependency: MyAwesomeViewModelWithAnotherProperty
{
private IDependency2 _dependency2;
public ICommand Command2;
public MyAwesomeViewModelWithNewCommandAndDependency(IDependency1 dependency1, IDependency2 dependency2)
: base(dependency1)
{
_dependency2 = dependency2;
Command2 = new DelegateCommand(...);
}
}
internal class MyAwesomeViewModelWithBunchNewProperties : MyAwesomeViewModelWithNewCommandAndDependency
{
public int IntProperty { get; }
public bool BoolProperty { get; }
public double DoubleProperty { get; }
public MyAwesomeViewModelWithBunchNewProperties(IDependency1 dependency1, IDependency2 dependency2)
: base(dependency1, dependency2)
{
}
}
The problem is, when it comes to inheritance depth of 4 and more levels it becomes very messy and difficult to read. Also I always encounter to naming problem, which is signal of wrong composition (like MainWindowViewModel, then MainWindowViewModelCloseCommand, then MainWindowViewModelUserRelatedProperties and so on).
Since only the last derived class is used (MyAwesomeViewModelWithBunchNewProperties in the example above), sometimes I consider to squash all the inheritance before release or other significant milestone into 1 class, like this:
internal class MyAwesomeViewModel
{
public int IntProperty { get; }
public bool BoolProperty { get; }
public double DoubleProperty { get; }
public string Property1 { get; set; }
public string Property2 { get; set; }
public ICommand Command1 { get; }
public ICommand Command2;
public MyAwesomeViewModelWithBunchNewProperties(IDependency1 dependency1, IDependency2 dependency2)
{
_dependency1 = dependency1;
_dependency2 = dependency2;
Command1 = new DelegateCommand(...);
Command2 = new DelegateCommand(...);
}
}
But it could violate Single Responsibility Principle (SRP) and lead to very large SuperClass.
The question: How to deal with lot of inheritance problem? Or it is not problem at all and it's OK to have this type of classes structure?