Inversion of Control in Legacy Applications

Complete Developer Podcast - A podcast by BJ Burns and Will Gant - Thursdays

Categories:

When you get dropped into a legacy project, one of the main things you’ll miss is the use of more modern development practices, such as testing, inversion of control, proper object models, and configuration management. However, you probably can’t simply stop active development for six months to re-architect your entire application. This is especially risky if you don’t have a proven track record of reworking applications in this fashion. The code is never the most important aspect of a business, no matter how important it is to the developers. While working on old crappy systems is generally stressful and doesn’t help your career much, it’s really hard to get the business people to care. However, you can usually get away with making incremental system improvements. If you plan these improvements well, refactoring can make your work easier, giving you time for further improvements. Adding dependency injection and inversion of control is one of the first things you’ll probably do as you refactor a legacy application to make it more maintainable. Cleaning up code in older applications is a lot of work, and you simply cannot do it all in a short period of time. There is a bit of art and science to the process of cleaning up legacy systems to make them more maintainable. You have to be smart about the way you handle this work, both because of the risk of breaking things and because of the way office politics tend to work. However, if you do it well, you can drastically improve the functioning of nearly any old crusty app that you run across. Episode Breakdown Why you would want to do this. Improved ability to quickly change the app. When components are pluggable, it’s easier to switch implementations across the application as needed. You can even control this configuration dynamically from settings, which simplifies your code. This can also be a critical component of your strategy if you plan to support a plugin architecture. Improved object lifecycle management. Your app may not be properly managing things like network sockets, database connections, etc. A lot of this stuff is encapsulated in objects that you use and getting rid of those objects gets rid of the underlying resource. Sloppy development practices tend to mean that these objects hang around longer than they should, especially in garbage collected languages. This is also a good way to manage lifetimes of objects using policies to make sure that they are kept around for the length of a logical unit of work. Easier testing. Because you can switch the implementation being used, it’s easier to use mocks and stubs. This tends to simplify testing code, because instead of fully implementing the object you are trying to mock, you only really need to mock the methods that you are actually using. It’s also nice to be able to mock some of the slower objects with faster code that returns more quickly. This makes tests run faster. Necessary precursor for modern application development. Most modern object-oriented development frameworks make fairly heavy use of dependency injection and inversion of control. Additionally most modern frameworks can be configured to use IOC in a relatively transparent fashion when communicating with your application components. Prerequisites to this process. Data access layer While you certainly can proceed without having a data access layer, having one makes this process easier because you can abstract those calls away. Database calls, network calls, interactions with the file system, and interactions with other APIs often add a lot of complexity that you really don’t want to deal with just yet.

Visit the podcast's native language site