For most of the software projects there comes a time, when you need to spend some time over improving its structure. You start to seeing, that classes which you are changing cause you need to change totally unrelated ones too (from the first point of view) and some side effects could be really surprised for you. It is still easier to manage if you have a good unit tests coverage, but with the time it become more and more painful to change something.
In this case, I even don’t want to touch object design of the project. I would like to focus on problems with wrongly distributed classes between namespaces (assemblies). Ideally, one namespace is focused around a particular part of your domain. If changes which happen in this area affects different areas, that’s sounds like problems which could come quickly, especially if that happens often. The most problematic dependencies are circular dependencies between classes or namespaces (guideline about good approach about namespaces and components inside assembly you can find in NDepend WhiteBook).
Let’s take a look on how it’s looking like in NDatabase 3.6:
If you take a look closer, then you will find not all namespaces are expanded! It means, you can see a lot of dependency cycles (namespaces, classes) in above cut of whole NDatabase 3.6 structure!
I felt this technical debt every time I’ve changed something a bit more sophisticated. Fortunately, I got the chance to use great software which handles well such problems – Restructure 101.
The first general view for NDatabase 3.6 was following:
In terms of project’s structure, it looks good. The main problem is (as I mentioned before) the coupled structure – namespaces, classes.
For less than 1 day, I played with Restructure 101 to achieve better design in terms of classes and namespaces. The process was following:
- Find the problem, usually caused by dotted arrow (lot of them you could see on the first picture).
- Look into the code, what is causing the problem.
- If there was no clear solution in code, I played with Restructure to move class / namespace into other place to disentangle dependencies.
- If problem was easily fixed in the code, I applied it and then refreshed project in Restructure.
- Go back to step 1 up to obtain satisfactory results.
Final solution looks pretty good:
If we take a look on the same cut of the NDatabase structure, we could easily see the improvement:
There are only two dotted arrows on this level! The more important thing we could see if we compare high level diagrams:
Yes indeed, now we could see internal components divided into namespaces in NDatabase structure.
There is last thing, which I want to mention regarding the NDatabase structure. In NDatabase I really care about what is public, and where we could find it. In NDatabase 3.7 the structure of NDatabase public elements has further improvements.
Now, only 3 namespaces has public elements:
- NDatabase.Api (+ NDatabase.Api.Query, + NDatabase.Api.Triggers)
If we take a look deeper on them, we could see there are mainly interfaces. The only classes I made public are:
- OdbFactory – start point for NDatabase
- OIDFactory – allows us on create object or class id based on a given long number
- NonPersistentAttribute – attribute which allows on omitting fields during storage process
- OdbConfiguration – small configuration point for NDatabase
- OrderByConstants – constants used for ordering queries and creating ordered collection iterators
- Triggers classes (Trigger, DeleteTrigger, UpdateTrigger, SelectTrigger, InsertTrigger) – triggers api
- Concrete exceptions used by NDatabase
And that’s all in terms of classes.
If you want to see more about public API, please see the documentation page here.
Finally, I would like to thanks Structure 101 team for giving me a chance to use their great software:)