2. Why Rework a Functioning System? Make it more maintainable Reorganize and update structure Move to a more modern language or platform Modularization Data reengineering Enable Process Reengineering Add new functionality Improve Performance Improved response to required system changes Introduce quality and other measurable improvements Future labor savings (dev team and business team) System Consolidation You can Rewrite or Reengineer Brad Irby - Alobria Systems
3. Advantages of Reengineering Reduced Customer Impact No Feature Freeze – Plane Stays in the Air Fits well with Agile Release Schedules Reduced Risk Maintains existing business logic, processes, and side effects Fewer errors interpreting existing system Reduced Cost Can use outside talent Business logic already complete Shorter Timeline (about 6-9 months) Continuous QA 25% of the cost of a rewrite (Ulrich, 1990) Brad Irby - Alobria Systems
4. Before We See Code… Assumptions Winforms - Using Adapted Prism Unit Tests are rarely done now UI Requirements Winforms now ASP MVC near future WPF in the medium future Maybe Silverlight in far future Different UI’s But Single Controller Brad Irby - Alobria Systems
5. Preliminary Code Review Establish validity of MVC Everybody claims it, few have it Count Number of Static Classes Pure constant or enum classes don’t matter Count Activator Calls Count Average Num References per Project Look at validity of references Where is wizard controller logic? Know What You Are Up Against Brad Irby - Alobria Systems
6. Lay Groundwork (Basics) Decide Unit Test Framework External GUI runner Integrated into VS2008/2010 (TestDriven) Integrates with Code Coverage Integrates with TFS? Has Command Line Reporting with data export Nunit, MbUnit, MSTest Spend the time to do this right Brad Irby - Alobria Systems
7. Lay Groundwork (Basics) Divide Tests Integration tests Unit tests Install test runner TestDriven or Resharper are good Train Team TestDriven NUnit Training is an ongoing effort Brad Irby - Alobria Systems
8. Lay Groundwork (Basics) Setup Build Server Nightly build a must Email build Success/Fail Continuous Integration helps a lot Cruise Control and CCTray Nightly runs of integration tests Unit tests run on each checkin Peer Pressure Not To Break Builds Brad Irby - Alobria Systems
9. Lay Groundwork (Advanced) Decide on Code Coverage NCover or MS Team Coverage Stats should run nightly to develop trend Over time, decide on max Cyclomatic Complexity Decide on Mocking Framework Moq, Rhino mocks, Typemock Isolator (Big Daddy) Ensure data model is in project by itself Allows use from old and new code Get Team Buy-in on these Brad Irby - Alobria Systems
10. Let’s See Some Code! Project Structure Strategy Preliminary Code Cleanup Remove unneeded Using clauses and References VS PowerCommands for Usings References – brute force Update project target framework Clean up warnings “Warning as Errors” Careful of too many partial classes Code Changes Good for Junior Dev Brad Irby - Alobria Systems
11. Start Coding – Add Basics Dependency Injection Container Service Locator Message Aggregator Logger Module Manager Region Manager Toolbar Manager Repository (ORM?) Message Dialog Service Little Effect on Existing Code Brad Irby - Alobria Systems
12. Migrate Infrastructure Add Bootstrapper Establish first 2 modules Shared Smallest and Easiest Module Move Constants and Enums (Jr. Dev) Make these Static classes Look for Static Services classes Difficult to Mock and test (statics are sealed) Cause problems testing other things Search for “public static class” Change to normal class (singleton via container) Need Interface SearchPageFactory Small Changes Can Have Big Effects Brad Irby - Alobria Systems
13. Migrate Infrastructure Look for singleton patterns Search for “.Instance” Move to Service Locator BusinessObjectCacheManager Look for services with no Interfaces Can move to “everything” interface easily Put in ServiceLocator Watch your References Old to New = OK New to Old = Bad Slowly Move To New Infrastructure Brad Irby - Alobria Systems
14. Migrate Views & Controllers Start with Easiest Lots of infrastructure needed for first one Don’t complicate with difficult workflow Use views that don’t need data binding if possible Second – easy workflow with data binding Third – most complicated workflow Last – pass patterns on to team for implementation Build Example Patterns for Others Brad Irby - Alobria Systems
15. Testing Considerations Bootstrapper Add Extension methods to setup mocks Moq lets you get the Mock via an object Make plenty of Mocking examples for others to learn from Try for 75% or more coverage on new code Don’t overload TestSetup Common beginner mistake Unit Tests Difficult for Some Brad Irby - Alobria Systems
16. Parting Comments Don’t call old code “Legacy” Work closely with QA You will break things that were solid before Copy code to new projects where you can Unit Tests Difficult for Newbs Brad Irby - Alobria Systems
Editor's Notes
In this presentation we are going to be going through a typical reengineering engagement with a fictional client. We will walk through all the steps necessary to reengineer an existing system from the start to the finish.
There are many reasons to reengineer an existing system. These are only a few. We will talk to our client to find out what are the main reasons for the desire to reengineer their system.
These are the main advantages of reengineering over rewriting.A largely ignored factor is that reengineering retains the unintended side effects of the way the current code was implemented. Customer come to depend on the small artifacts in our software, and if we rewrite it those artifacts will be lost without us knowing it. By keeping as much of the business logic as possible, these artifacts are retained, and customers are kept happy.
We are assuming the project we will be working with is Winforms, and that the unit tests are few and far between.We also assume that our UI will be moving towards ASP MVC and also WPF. Silverlight is in the distant future.Note that we are going to be structuring the system so that all of the UI implementations will use the same business logic – without changes.
First, we analyze the existing code to see what we are up against. This helps us estimate how long the project will take, what infrastructure elements we will need to introduce, and which elements will need to be replaced.
Deciding on a proper unit test framework is an important first step. There are various options depending on various factors in the development environment.
It is best to divide out the integration tests up front since they take so much time to run.Note that training is never done! All new additions must be accompanied by team training to make sure the team adopts the new technology. New infrastructure that nobody uses is worthless.
Nightly builds are must. Builds on each checkin are helpful, but not required.
Code coverage is a very useful tool, helping to measure progress towards complete test coverage.Mocking frameworks can be complicated, so the team should be involved in this decision.