Based on my years of experience refactoring Spring Based applications using Emergent Design Principles, I have come up with a game plan. This game plan summarizes what I have found to work when evolving a code base.
- Start with simple shell modules based on functional attributes to hold your existing business logic.
- Initial modules are empty and only have app context and property file support
- Be sure to include support for setting properties via Spring abstractions that allow upgrade path to Spring cloud config
- Ensure that each module contains it's own configuration classes and xml config
- Ensure that unit tests prove ability to startup application context containing only the beans located in the module
- Migrate existing algorithms to service classes
- do not get overly concerned with Object Hierarchy - that is something that probably should be left to last responsible moment. (See Emergent Design)
- Join service classes together via composition
- I still prefer setter composition for starters (can change to constructor via Emergent Design Principles)
- Establish IDE configuration as First Class citizen. IDE should have ability to build and report errors on the fly - no manual intervention or scripts. A properly setup IDE should be able to import the dependencies natively.
- Continue to migrate algorithms making sure that each module can load its application context when it has it's dependencies app contexts loaded too.
- Abstract Base Classes to standardize data flow.
- Base classes should not know about children for logic.. Its not just about having one spot for code... its about going from general to specific. That is why base classes should only flesh out generalizations for data flow not act as areas to hold common code. Use utility classes or other services for that.
- See execute method in Spring JdbcTemplate of a good example of a method that could exist in Base Class
- When service classes and modules recreate the functional behavior of the existing application, create a wrapper for aggregation of the modules using Spring Boot. (Last responsible moment - Emergent Design) This should keep the focus on modules and not the application until the code takes proper shape.
- Don't be afraid to create new modules or abstractions as you learn more about how your modules interact. The right time to do this is as you move along... not at the very start. Emergent design is about learning how your modules interact and refining the design as you go.
- The key to this whole process is that you decompose the big problem into pieces that you continually test from the ground up. There are no surprises at the end of the tunnel.
- NOTE: legacy code does not need to be totally re-written to integrate with spring... the key parts to making an application comply are:
- Property file support using conventions that will comply with Spring Cloud Config
- Access to application context for "non spring beans" - this can be accomplished by creating a class that contains the spring application context as a static member and importing this class into your non-spring classes. If this is done, you can at least "pull" spring services into these classes to bridge the gap between spring and non spring classes
- you don't want to migrate code to get to the same functional position (barring ability to annotate and apply AOP)
- although it's a hack - it might be easiest way to bridge the two worlds
NOTE: As it turning out there is a book on this. I had been listening to the New Stack Podcast but didn't realize there was a book:
http://pivotal.io/platform/migrating-to-cloud-native-application-architectures-ebook
No comments:
Post a Comment