This is very basic stuff, but here goes. I find that I am never able to agree with myself whether the way I split large classes into smaller ones make things more maintainable or less maintainable. I am familiar with design patterns, though not in detail, and also with the concepts of object oriented design. All the fancy rules and guidelines aside, I am looking to pick your brains with regards to what I am missing with a very simple, sample scenario. Essentially along the lines of: "...this design will make it more difficult to", etc... All the things I don't anticipate because of lack of experience essentially.
Say you need to write a basic "file reader / file writer" style class to process a certain type of file. Let's call the file a YadaKungFoo file. The contents of YadaKungFoo files is essentially similar to INI Files, but with subtle differences.
There are sections and values:
[Sections]
Kung,Foo
Panda, Kongo
[AnotherSection]
Yada,Yada,Yada
Subtle,Difference,Here,Yes
[Dependencies]
PreProcess,SomeStuffToPreDo
PreProcess,MoreStuff
PostProcess,AfterEight
PostProcess,TheEndIsNear
PostProcess,TheEnd
OK, so this can yield 3 basic classes:
public class YadaKungFooFile
public class YadaKungFooFileSection
public class YadaKungFooFileSectionValue
The two latter classes are essentially only data structures with a ToString() override to spit out a string list of values stored using a couple of Generic lists. This is sufficient to implement the YadaKungFooFile save functionality.
So over time the YadaYadaFile starts growing. Several overloads to save in different formats, including XML etc, and the file starts pushing towards 800 lines or so. Now the real question: We want to add a feature to validate the contents of a YadaKungFoo file. The first thing that comes to mind is obviously to add:
var yada = new YadaKungFooFile("C:\Path");
var res = yada .Validate()
And we're done (we can even call that method from the constructor). Trouble is the validation is quite complicated, and makes the class very large, so we decide to create a new class like this:
var yada = new YadaKungFooFile("C:\Path");
var validator = new YadaKungFooFileValidator(yada);
var result = validator.Validate();
Now this sample is obviously terribly simple, trivial and insignificant. Either of the two ways above probably won't make too much difference, but what I don't like is:
- The YadaKungFooFileValidator class and the YadaKungFooFile class seem to be very strongly coupled by this design. It seems a change in one class, would likely trigger changes in the other.
- I am aware that phrases such as "Validator", "Controller", "Manager" etc... indicates a class that is concerned with the state of other objects as opposed to its "own business", and hence violates separation of concern principles and message sending.
All in all I guess I feel that I don't have the experience to understand all the aspects of why a design is bad, in what situations it doesn't really matter and what concern carries more weight: smaller classes or more cohesive classes. They seem to be contradictive requirements, but perhaps I am wrong. Maybe the validator class should be a composite object?
Essentially I am asking for comments on likely benefits / problems that could result from the above design. What could be done differently? (base FileValidator class, FileValidator Interface, etc.. u name it). Think of the YadaKungFooFile functionality as ever growing over time.