Two lessons which I personally have been familiar with for quite a long time, but other developers may not know:
- Singleton pattern is very dangerous and one should avoid using it unless he is absolutely sure that two instances of that class is a non-sense. And even in this case avoid accessing singleton and prefer passing that singleton object as a parameters to the methods where it is required.
In our case the instance of CustomColumnsStorage class was accessed as singleton from just everywhere. So when I decided to create another instance which would load custom fields from a file during import process, I had to patch all those places.
- Classes which represent user interface must not be used as a model for code that reads data from files (it is just a rephrased Model-View-Controller).
In our case code that handles tags storing custom fields in .gan files directly used instances of GanttTreeTable (a class that represents the table view). So if I want to keep in memory two .gan files (one is a project we work with and another is a project we import), I either have to create two UI tables or to refactor the smelling code and give that tag handler the interface it needs. I chose the second way.