A few days ago I had a brainwave while trying to sleep. One of the problems I have been having with the development of the moneyjar application is that all of the tools I was building were not integrating in a nice way. The packages and classes were tightly coupled, and I had a hard time trying to conceptualize where one package ended and another began. Suffice to say there was a lot of bleeding between packages.
While trying to break up the application into the MVC pattern I had a lot of model, view, and controller classes spread out over numerous packages. It was difficult to manage and hard to navigate, I knew something was up and I had to investigate. After a little research I found that I was packaging my application by layer separating the different class types into their own packages. This was not a good way to organize your packages for the reasons I had just described. A better way to package your classes is to package classes by feature.
Each feature would contain its own MVC classes and packaged together. This makes it clear where one feature starts and when it ends. After a little refactoring the benefits were immediate. The packages were isolated, decoupled, modularized, and easy to navigate and maintain. I instantly fell in love with packaging by feature.
Afterwards I had another brain wave. Organizing the packages had a major positive impact on the project, but some aspects of the application could still use a little decoupling and organization. So as well as packaging by feature, I decided to make each feature or tool a stand alone application.
This made this project an even better software development experiment. Since each package became essentially its own application, I could design/refactor each one separately with its own interfaces and APIs. This change pushed the application even further towards the collection of personal financial management tools I had envisioned a few weeks ago.
While each application contained its own executable GUI application, each package could be designed to work with other packages and communicate with each other over well designed interfaces. Sub-components can then be instantiated and the final application would be a composition of parts from the standalone-tools.
Another side-project would be to make each feature a pluggable component making the application even more flexible in the future.
In any case, the most recent breakup by feature is really paying off. And my pet project is turning into a real learning opportunity.