1.26k likes | 1.27k Views
Discover detailed strategies for life insurance migration, detecting duplicated code, and redistributing responsibilities. Learn how to transform conditionals to polymorphism and set the right direction using object-oriented reengineering patterns.
E N D
Tests: Your Life Insurance Migration Strategies Detailed Model Capture Detecting Duplicated Code Initial Understanding Redistribute Responsibilities First Contact Transform Conditionals to Polymorphism Setting Direction Object-Oriented Reengineering Patterns A Map of Reengineering Patterns
Tests: Your Life Insurance Migration Strategies Detailed Model Capture Detecting Duplicated Code Initial Understanding Redistribute Responsibilities First Contact Transform Conditionals to Polymorphism Setting Direction Object-Oriented Reengineering Patterns A Map of Reengineering Patterns
Object-Oriented Reengineering Patterns The Reengineering Life-Cycle (0) requirement analysis Requirements (2) problem detection (3) problem resolution • (0) req. analysis • (1) model capture • issues • scale • speed • accuracy • politics Designs (1) model capture Code (4) program transformation
Object-Oriented Reengineering Patterns Forces — Setting Direction • Conflicting interests (technical, ergonomic, economic, political) • Presence/absence original developers • Legacy architecture • Which problems to tackle? • Interesting vs important problems? • Wrap, refactor or rewrite?
Object-Oriented Reengineering Patterns Setting Direction Set direction Where to start Agree on Maxims Maintaindirection Coordinatedirection Most Valuable First Speak to the Round Table Appoint aNavigator What not to do What to do If It Ain't BrokeDon't Fix It Fix Problems,Not Symptoms How to do it Principles & Guidelines for Software project management especially relevant for reengineering projects Keep it Simple
Object-Oriented Reengineering Patterns Most Valuable First • Problem: Which problems should you focus on first? • Solution: Work on aspects that are most valuable to your customer • Maximize commitment, early results; build confidence • Difficulties and hints: • Which stakeholder do you listen to? • What measurable goal to aim for? • Consult change logs for high activity • Play the Planning Game • Wrap, refactor or rewrite? — Fix Problems, not Symptoms
Tests: Your Life Insurance Migration Strategies Detailed Model Capture Detecting Duplicated Code Initial Understanding Redistribute Responsibilities First Contact Transform Conditionals to Polymorphism Setting Direction Object-Oriented Reengineering Patterns A Map of Reengineering Patterns
Object-Oriented Reengineering Patterns Forces — First Contact • Legacy systems are large and complex • Split the system into manageable pieces • Time is scarce • Apply lightweight techniques to assess feasibility and risks • First impressions are dangerous • Always double-check your sources • People have different agendas • Build confidence; be wary of skeptics
Object-Oriented Reengineering Patterns First Contact Feasibility assessment (one week time) System experts Talk with end users Talk withdevelopers Talk about it Interviewduring Demo Chat with theMaintainers Software System Verify whatyou hear Read about it Read it Compile it Read All the Code in One Hour Skim theDocumentation Do a MockInstallation
Object-Oriented Reengineering Patterns Interview during Demo • Problem: What are the typical usage scenarios? • Solution: Ask the user! • ... however • Which user ? • Users complain • What should you ask ? • Solution: interview during demo • select several users • demo puts a user in a positive mindset • demo steers the interview
Object-Oriented Reengineering Patterns Chat with the Maintainers • Problem: What are the history and politics of the legacy system? • Solution: Discuss the problems with the system maintainers. • Documentation will mislead you (various reasons) • Stakeholders will mislead you (various reasons) • The maintainers know both the technical and political history
Object-Oriented Reengineering Patterns Chat with the Maintainers • Questions to ask: • Easiest/hardest bug to fix in recent months? • How are change requests made and evaluated? • How did the development/maintenance team evolve during the project? • How good is the code? The documentation? • Why was the reengineering project started? What do you hope to gain? • The major problems of our work are no so much technological as sociological. • DeMarco and Lister, Peopleware ‘99
Object-Oriented Reengineering Patterns Read all the Code in One Hour • Problem: How can you get a first impression of the quality of the source code? • Solution: Scan all the code in single, short session. • Use a checklist (code review guidelines, coding styles etc.) • Look for functional tests and unit tests • Look for abstract classes and root classes that define domain abstractions • Beware of comments • Log all your questions! • I took a course in speed reading and read “War and Peace” in twenty minutes. It’s about Russia. • Woody Allen
Object-Oriented Reengineering Patterns First Project Plan • Use standard templates, including: • project scope • see "Setting Direction" • opportunities • e.g., skilled maintainers, readable source-code, documentation • risks • e.g., absent test-suites, missing libraries, … • record likelihood (unlikely, possible, likely)& impact (high, moderate, low) for causing problems • go/no-go decision • activities • fish-eye view
Tests: Your Life Insurance Migration Strategies Detailed Model Capture Detecting Duplicated Code Initial Understanding Redistribute Responsibilities First Contact Transform Conditionals to Polymorphism Setting Direction Object-Oriented Reengineering Patterns A Map of Reengineering Patterns
Object-Oriented Reengineering Patterns Forces — Initial Understanding • Data is deceptive • Always double-check your sources • Understanding entails iteration • Plan iteration and feedback loops • Knowledge must be shared • “Put the map on the wall” • Teams need to communicate • “Use their language”
Object-Oriented Reengineering Patterns Initial Understanding Top down Recover design Speculate about Design understand higher-level model Analyze the Persistent Data Study the Exceptional Entities Compile it Read it Bottom up
Object-Oriented Reengineering Patterns Speculate about Design • Problem: How do you recover design from code? • Solution: Develop hypotheses and check them • Develop a plausible class diagram and iteratively check and refine your design against the actual code. • Variants: • Speculate about Business Objects • Speculate about Design Patterns • Speculate about Architecture
Object-Oriented Reengineering Patterns Study the Exceptional Entities • Problem: How can you quickly identify design problems? • Solution: Measure software entities and study the anomalous ones • Use simple metrics • Visualize metrics to get an overview • Browse the code to get insight into the anomalies
Object-Oriented Reengineering Patterns Visualizing Metrics Use simple metrics and layout algorithms height colour (x,y) width Visualizes up to 5 metrics per node
ITERATION Object-Oriented Reengineering Patterns Initial Understanding (revisited) Top down Recover design Speculate about Design understand higher-level model Analyze the Persistent Data Study the Exceptional Entities Recover database Identify problems Bottom up
Tests: Your Life Insurance Migration Strategies Detailed Model Capture Detecting Duplicated Code Initial Understanding Redistribute Responsibilities First Contact Transform Conditionals to Polymorphism Setting Direction Object-Oriented Reengineering Patterns A Map of Reengineering Patterns
Object-Oriented Reengineering Patterns Forces — Detailed Model Capture • Details matter • Pay attention to the details! • Design remains implicit • Record design rationale when you discover it! • Design evolves • Important issues are reflected in changes to the code! • Code only exposes static structure • Study dynamic behaviour to extract detailed design
Object-Oriented Reengineering Patterns Detailed Model Capture Tie Code and Questions Expose the design & make sure it remains exposed Expose design Keep track of your understanding Refactor to Understand Expose collaborations Step through the Execution Write Tests to Understand Expose contracts Look for the Contracts Expose evolution • Use Your Tools • Look for Key Methods • Look for Constructor Calls • Look for Template/Hook Methods • Look for Super Calls Learn from the Past
Object-Oriented Reengineering Patterns Tie Code and Questions • Problem: How do you keep track of your understanding? • Solution: Annotate the code • List questions, hypotheses, tasks and observations • Identify yourself! • Use conventions to locate/extract annotations • Annotate as comments, or as methods
Object-Oriented Reengineering Patterns Refactor to Understand • Problem: How do you decipher cryptic code? • Solution: Refactor it until it makes sense • Goal (for now) is to understand, not to reengineer • Work with a copy of the code • Refactoring requires an adequate test base • If this is missing, Write Tests to Understand • Hints: • Rename attributes to convey roles • Rename methods and classes to reveal intent • Remove duplicated code • Replace condition branches by methods
Object-Oriented Reengineering Patterns Step Through the Execution • Problem: How do you uncover the run-time architecture? • Solution: Execute scenarios of known use cases and step through the code with a debugger • Tests can also be used as scenario generators • If tests are missing Write Tests to Understand • Put breakpoints in the code • Difficulties • OO source code exposes a class hierarchy, not the run-time object collaborations • Collaborations are spread throughout the code • Polymorphism may hide which classes are instantiated • Focused use of a debugger can expose collaborations
Object-Oriented Reengineering Patterns Look for the Contracts • Problem: Which contracts does a class support? • Solution: Look for common programming idioms • Look for “key methods” • Intention-revealing names • Key parameter types • Recurring parameter types represent temporary associations • Look for constructor calls • Look for Template/Hook methods • Look for super calls • Use your tools!
Object-Oriented Reengineering Patterns Learn from the Past • Problem: How did the system get the way it is? • Solution: Compare versions to discover where code was removed • Removed functionality is a sign of design evolution • Use or develop appropriate tools • Look for signs of: • Unstable design — repeated growth and refactoring • Mature design — growth, refactoring and stability
Object-Oriented Reengineering Patterns Conclusion • Setting Direction + First Contact • First Project Plan • Initial Understanding + Detailed Model Capture • Plan the work … and Work the plan • Frequent and Short Iterations • Issues • scale • speed vs. accuracy • politics
Tests: Your Life Insurance Migration Strategies Detailed Model Capture Detecting Duplicated Code Initial Understanding Redistribute Responsibilities First Contact Transform Conditionals to Polymorphism Setting Direction Object-Oriented Reengineering Patterns A Map of Reengineering Patterns
Object-Oriented Reengineering Patterns What and Why ? Definitions • Restructuring refers to transforming a system from one representation to another while remaining at the same abstraction level. — Chikofsky & Cross, ’90 • Refactoring is the process of changing a software system in such a way that it does not alter the external behaviour of the code, yet improves its internal structure — Fowler, ’99 Motivation • Alter the source-code to • solve problems identified earlier • without introducing new defects • and while the system remains in operation
Object-Oriented Reengineering Patterns The Reengineering Life-Cycle (0) requirement analysis Requirements (2) problem detection (3) problem resolution Designs • (3) problem resolution • (4) program transformation • issues • reliability • time • risk (1) model capture Code (4) program transformation
Object-Oriented Reengineering Patterns Forces — Testing • Many legacy systems don’t have tests • Software changes introduce new bugs • You can’t test everything • Concurrency and user interfaces are hard to test • Testing is usually everyone’s lowest priority • Knowledge concentration poses high risk • Customers pay for features, not tests • Customers don’t want buggy systems • Good programmers don’t need tests • New tools and techniques are more fun than testing • Testing is akin to street-cleaning
Object-Oriented Reengineering Patterns Tests: Your Life Insurance Write Tests to Enable Evolution Use a Testing Framework Managing tests Designing tests Grow Your TestBase Incrementally Record BusinessRules as Tests Test the Interface, Not the Implementation • Test Fuzzy features • Test Old Bugs • Retest Persistent Problems Write Tests to Understand Regression Testafter Every Change Migration Strategies
Object-Oriented Reengineering Patterns Write Tests to Enable Evolution Problem: How do you minimize the risks of change? Solution: Introduce automated, repeatable, stored tests Long-term evolution System documentation Architectural evolution System Confidence Turnover Risk minimization Confidence in Change Automated Tests Automated tests are the foundation of reengineering
Object-Oriented Reengineering Patterns Grow Your Test Base Incrementally • Problem: When can you stop writing tests? • Solution: When your tests cover all the code! • … however • you're paid to reengineer, not to write tests • testing ALL the code is impossible • design documentation is out-of date » semi-automated black-box testing is not an option • Answer: Grow Your Test Base Incrementally • first test critical components(business value; likely to change; …) • keep a snapshot of old system(run new tests against old system) • focus on business values • test old bugs + new bugs that are reported
Object-Oriented Reengineering Patterns Use a Testing Framework • Problem: How do you encourage systematic testing? • Solution: Use a framework to structure your tests
Object-Oriented Reengineering Patterns Running tests
Object-Oriented Reengineering Patterns Test the Interface, Not the Implementation • Problem: How do you protect your investment in tests? • Solution: Apply black-box testing • Test interfaces, not implementations • Be sure to exercise the boundaries • Test scenarios, not paths • Use tools to check for coverage • Beware; • Enabling testing will influence your design!
Object-Oriented Reengineering Patterns Write Tests to Understand • Problem: How to decipher code without adequate tests or documentation? • Solution: Encode your hypotheses as test cases • Exercise the code • Formalize your reverse-engineering hypotheses • Develop tests as a by-product
Object-Oriented Reengineering Patterns Record Business Rules as Tests • Problem: How do you keep your system in sync with the business rules it implements? • A Solution: Good documentation + Good design • … however • business rules are too complex to design well • documentation & design degrades when the rules change • business rules become implicit in code and minds • Solution:Record Business Rules as Tests • canonical examples exist • can be turned into input/output tests
Object-Oriented Reengineering Patterns Example: Payroll Business Rule • A person or couple gets an amount of money for every child he, she or they raise. Basically parents get CHF 150,- per month for every child younger than 12 years, and CHF 180,- for every child between 12 and 18 and for every child between 18 and 25 as long as the child is not working and is still in the educational system. A single parent gets the full 100% of this money as long as he or she is working more than 50%. Couples get a percentage of the money that is equal to the summed working percentages of both partners.
Object-Oriented Reengineering Patterns Example: Payroll Test Case "--- input-cases are extracted from a database" singlePerson80WithOneKidOf5 := extract.... couplePerson40occupationWithOneKidOf5 := extract.... couplePerson100occupationWithOneKidOf5 := extract.... couplePersonWithOneKidOf14 := extract.... "--- tests compare expected output against actual output" self assert: singlePerson80occupationWithOneKidOf5 moneyForKid = 150. self assert: couplePerson40occupationWithOneKidOf5 moneyForKid = 150*4. self assert: couplePerson100occupationWith2KidsOf5 moneyForKid = 150*2. self assert: couplePersonWithOneKidOf14 moneyForKid = 180.
Object-Oriented Reengineering Patterns Other patterns • Retest Persistent Problems • Always tests these, even if you are making no changes to this part of the system • Test Fuzzy Features • Identify and write tests for ambiguous or ill-defined parts of the system • Test Old Bugs • Examine old problems reports, especially since the last stable release • DeLano and Rising, 1998