Improving The Quality of Existing Software
-
Upload
steven-smith -
Category
Technology
-
view
1.829 -
download
1
description
Transcript of Improving The Quality of Existing Software
![Page 1: Improving The Quality of Existing Software](https://reader038.fdocuments.us/reader038/viewer/2022110118/554f866eb4c905d25b8b4cd5/html5/thumbnails/1.jpg)
Improving the Quality of Existing Software
Steve SmithTelerikardalis.com @ardalis
![Page 2: Improving The Quality of Existing Software](https://reader038.fdocuments.us/reader038/viewer/2022110118/554f866eb4c905d25b8b4cd5/html5/thumbnails/2.jpg)
Software Rots
![Page 3: Improving The Quality of Existing Software](https://reader038.fdocuments.us/reader038/viewer/2022110118/554f866eb4c905d25b8b4cd5/html5/thumbnails/3.jpg)
![Page 4: Improving The Quality of Existing Software](https://reader038.fdocuments.us/reader038/viewer/2022110118/554f866eb4c905d25b8b4cd5/html5/thumbnails/4.jpg)
Technical Debt
• Low quality code and shortcuts in our applications
• Technical debt, like real debt, has direct cost and interest
![Page 5: Improving The Quality of Existing Software](https://reader038.fdocuments.us/reader038/viewer/2022110118/554f866eb4c905d25b8b4cd5/html5/thumbnails/5.jpg)
http://www.jimhighsmith.com/
![Page 6: Improving The Quality of Existing Software](https://reader038.fdocuments.us/reader038/viewer/2022110118/554f866eb4c905d25b8b4cd5/html5/thumbnails/6.jpg)
Preventive Maintenance
• Refactoring– Eliminate Duplication– Simplify Design
• Automated Tests– Verify correctness– Avoid regressions– Increase Confidence
![Page 7: Improving The Quality of Existing Software](https://reader038.fdocuments.us/reader038/viewer/2022110118/554f866eb4c905d25b8b4cd5/html5/thumbnails/7.jpg)
When should you refactor?
• While delivering value
![Page 8: Improving The Quality of Existing Software](https://reader038.fdocuments.us/reader038/viewer/2022110118/554f866eb4c905d25b8b4cd5/html5/thumbnails/8.jpg)
![Page 9: Improving The Quality of Existing Software](https://reader038.fdocuments.us/reader038/viewer/2022110118/554f866eb4c905d25b8b4cd5/html5/thumbnails/9.jpg)
Refactoring Should Not Change System Behavior
![Page 10: Improving The Quality of Existing Software](https://reader038.fdocuments.us/reader038/viewer/2022110118/554f866eb4c905d25b8b4cd5/html5/thumbnails/10.jpg)
Refactoring Process
• Verify existing behavior• Write Characterization Tests if none
exist– Find test points– Break dependencies
• Apply Refactoring• Confirm existing behavior is
preserved
![Page 11: Improving The Quality of Existing Software](https://reader038.fdocuments.us/reader038/viewer/2022110118/554f866eb4c905d25b8b4cd5/html5/thumbnails/11.jpg)
Characterization Tests
Process1. Write a test you know will fail2. Use the output of the failing test to
determine the existing behavior to assert
3. Update the test with the new value/behavior
4. Run the test again – it should pass
![Page 12: Improving The Quality of Existing Software](https://reader038.fdocuments.us/reader038/viewer/2022110118/554f866eb4c905d25b8b4cd5/html5/thumbnails/12.jpg)
![Page 13: Improving The Quality of Existing Software](https://reader038.fdocuments.us/reader038/viewer/2022110118/554f866eb4c905d25b8b4cd5/html5/thumbnails/13.jpg)
![Page 14: Improving The Quality of Existing Software](https://reader038.fdocuments.us/reader038/viewer/2022110118/554f866eb4c905d25b8b4cd5/html5/thumbnails/14.jpg)
S O L I DPrinciples
http://flickr.com/photos/kevinkemmerer/2772526725/
![Page 15: Improving The Quality of Existing Software](https://reader038.fdocuments.us/reader038/viewer/2022110118/554f866eb4c905d25b8b4cd5/html5/thumbnails/15.jpg)
Principles of OO Design
0. Don’t Repeat Yourself (DRY)
1.Single Responsibility2.Open/Closed3.Liskov Substitution4.Interface Segregation5.Dependency Inversion
![Page 16: Improving The Quality of Existing Software](https://reader038.fdocuments.us/reader038/viewer/2022110118/554f866eb4c905d25b8b4cd5/html5/thumbnails/16.jpg)
![Page 17: Improving The Quality of Existing Software](https://reader038.fdocuments.us/reader038/viewer/2022110118/554f866eb4c905d25b8b4cd5/html5/thumbnails/17.jpg)
Don’t RepeatRepeat Yourself
• Duplication in logic calls for abstraction
• Duplication in process calls for automation
![Page 18: Improving The Quality of Existing Software](https://reader038.fdocuments.us/reader038/viewer/2022110118/554f866eb4c905d25b8b4cd5/html5/thumbnails/18.jpg)
Common Refactorings
• Replace Magic Number/String• Parameterize Method• Pull Up Field• Pull Up Method• Replace Conditional With
Polymorphism• Introduce Method
![Page 19: Improving The Quality of Existing Software](https://reader038.fdocuments.us/reader038/viewer/2022110118/554f866eb4c905d25b8b4cd5/html5/thumbnails/19.jpg)
Role Checks
if(user.IsInRole(“Admins”){ // allow access to resource}
// favor privileges over role checks// ardalis.com/Favor-Privileges-over-Role-Checks
var priv = new ContentPrivilege(user, article);if(priv.CanEdit()){ // allow access}
![Page 20: Improving The Quality of Existing Software](https://reader038.fdocuments.us/reader038/viewer/2022110118/554f866eb4c905d25b8b4cd5/html5/thumbnails/20.jpg)
![Page 21: Improving The Quality of Existing Software](https://reader038.fdocuments.us/reader038/viewer/2022110118/554f866eb4c905d25b8b4cd5/html5/thumbnails/21.jpg)
Single Responsibility PrincipleThe Single Responsibility Principle states that every
object should have a single responsibility, and that responsibility should be entirely encapsulated by the class.
Wikipedia
There should never be more than one reason for a class to change.
Robert C. “Uncle Bob” Martin
![Page 22: Improving The Quality of Existing Software](https://reader038.fdocuments.us/reader038/viewer/2022110118/554f866eb4c905d25b8b4cd5/html5/thumbnails/22.jpg)
Example Responsibilities
• Persistence• Validation• Notification• Error Handling• Logging• Class Selection / Construction• Formatting• Parsing• Mapping
![Page 23: Improving The Quality of Existing Software](https://reader038.fdocuments.us/reader038/viewer/2022110118/554f866eb4c905d25b8b4cd5/html5/thumbnails/23.jpg)
Dependency and Coupling
• Excessive coupling makes changing legacy software difficult
• Breaking apart responsibilities and dependencies is a large part of working with existing code
![Page 24: Improving The Quality of Existing Software](https://reader038.fdocuments.us/reader038/viewer/2022110118/554f866eb4c905d25b8b4cd5/html5/thumbnails/24.jpg)
Common Refactorings
• Extract Class• Extract Method• Move Method
![Page 25: Improving The Quality of Existing Software](https://reader038.fdocuments.us/reader038/viewer/2022110118/554f866eb4c905d25b8b4cd5/html5/thumbnails/25.jpg)
Heuristics and Code Smells
• Visual Studio Metrics
![Page 26: Improving The Quality of Existing Software](https://reader038.fdocuments.us/reader038/viewer/2022110118/554f866eb4c905d25b8b4cd5/html5/thumbnails/26.jpg)
Code Smell: Regions
?More on Regions: http://ardalis.com/regional-differences
![Page 27: Improving The Quality of Existing Software](https://reader038.fdocuments.us/reader038/viewer/2022110118/554f866eb4c905d25b8b4cd5/html5/thumbnails/27.jpg)
![Page 28: Improving The Quality of Existing Software](https://reader038.fdocuments.us/reader038/viewer/2022110118/554f866eb4c905d25b8b4cd5/html5/thumbnails/28.jpg)
Open / Closed Principle
The Open / Closed Principle states that software entities (classes, modules, functions, etc.) should be open for extension, but closed for modification.
Wikipedia
![Page 29: Improving The Quality of Existing Software](https://reader038.fdocuments.us/reader038/viewer/2022110118/554f866eb4c905d25b8b4cd5/html5/thumbnails/29.jpg)
Open / Closed Principle
Open to ExtensionNew behavior can be added in the future
Closed to ModificationChanges to source or binary code are not required
Dr. Bertrand Meyer originated the OCP term in his 1988 book, Object Oriented Software Construction
![Page 30: Improving The Quality of Existing Software](https://reader038.fdocuments.us/reader038/viewer/2022110118/554f866eb4c905d25b8b4cd5/html5/thumbnails/30.jpg)
Common Refactorings
• Extract Interface / Apply Strategy Pattern
• Parameterize Method• Form Template Method
![Page 31: Improving The Quality of Existing Software](https://reader038.fdocuments.us/reader038/viewer/2022110118/554f866eb4c905d25b8b4cd5/html5/thumbnails/31.jpg)
OCP Fail
![Page 32: Improving The Quality of Existing Software](https://reader038.fdocuments.us/reader038/viewer/2022110118/554f866eb4c905d25b8b4cd5/html5/thumbnails/32.jpg)
OCP OK
![Page 33: Improving The Quality of Existing Software](https://reader038.fdocuments.us/reader038/viewer/2022110118/554f866eb4c905d25b8b4cd5/html5/thumbnails/33.jpg)
OCP Fail
public bool IsSpecialCustomer(Customer c){ if(c.Country == “US” && c.Balance < 50) return false; if(c.Country == “DE” && c.Balance < 25) return false; if(c.Country == “UK” && c.Balance < 35) return false; if(c.Country == “FR” && c.Balance < 27) return false; if(c.Country == “BG” && c.Balance < 29) return false;
if(c.Age < 18 || c.Age > 65) return false; if(c.Income < 50000 && c.Age < 30) return false; return true;}
![Page 34: Improving The Quality of Existing Software](https://reader038.fdocuments.us/reader038/viewer/2022110118/554f866eb4c905d25b8b4cd5/html5/thumbnails/34.jpg)
OCP OK
private IEnumerable<ICustomerRule> _rules;
public bool IsSpecialCustomer(Customer c){ foreach(var rule in _rules) { if(rule.Evaluate(c) == false) return false; } return true;}
![Page 35: Improving The Quality of Existing Software](https://reader038.fdocuments.us/reader038/viewer/2022110118/554f866eb4c905d25b8b4cd5/html5/thumbnails/35.jpg)
![Page 36: Improving The Quality of Existing Software](https://reader038.fdocuments.us/reader038/viewer/2022110118/554f866eb4c905d25b8b4cd5/html5/thumbnails/36.jpg)
Liskov Substitution Principle
The Liskov Substitution Principle states that Subtypes must be substitutable for their base types.
Agile Principles, Patterns, and Practices in C#
Named for Barbara Liskov, who first described the principle in 1988.
![Page 37: Improving The Quality of Existing Software](https://reader038.fdocuments.us/reader038/viewer/2022110118/554f866eb4c905d25b8b4cd5/html5/thumbnails/37.jpg)
Common Refactorings
• Collapse Hierarchy• Pull Up / Push Down Field• Pull Up / Push Down Method
![Page 38: Improving The Quality of Existing Software](https://reader038.fdocuments.us/reader038/viewer/2022110118/554f866eb4c905d25b8b4cd5/html5/thumbnails/38.jpg)
Liskov Substitution Fail
foreach(var employee in employees){ if(employee is Manager) { Helpers.PrintManager(employee as Manager); break; } Helpers.PrintEmployee(employee);}
![Page 39: Improving The Quality of Existing Software](https://reader038.fdocuments.us/reader038/viewer/2022110118/554f866eb4c905d25b8b4cd5/html5/thumbnails/39.jpg)
Liskov Substitution OK
foreach(var employee in employees){ employee.Print(); // or Helpers.PrintEmployee(employee);}
![Page 40: Improving The Quality of Existing Software](https://reader038.fdocuments.us/reader038/viewer/2022110118/554f866eb4c905d25b8b4cd5/html5/thumbnails/40.jpg)
![Page 41: Improving The Quality of Existing Software](https://reader038.fdocuments.us/reader038/viewer/2022110118/554f866eb4c905d25b8b4cd5/html5/thumbnails/41.jpg)
Interface Segregation PrincipleThe Interface Segregation Principle states
that Clients should not be forced to depend on methods they do not use.
Agile Principles, Patterns, and Practices in C#
Corollary:Prefer small, cohesive interfaces to “fat”
interfaces
![Page 42: Improving The Quality of Existing Software](https://reader038.fdocuments.us/reader038/viewer/2022110118/554f866eb4c905d25b8b4cd5/html5/thumbnails/42.jpg)
Common Refactorings
• Extract Interface
![Page 43: Improving The Quality of Existing Software](https://reader038.fdocuments.us/reader038/viewer/2022110118/554f866eb4c905d25b8b4cd5/html5/thumbnails/43.jpg)
Keep Interfaces Small and Focused
![Page 44: Improving The Quality of Existing Software](https://reader038.fdocuments.us/reader038/viewer/2022110118/554f866eb4c905d25b8b4cd5/html5/thumbnails/44.jpg)
Membership Provider
![Page 45: Improving The Quality of Existing Software](https://reader038.fdocuments.us/reader038/viewer/2022110118/554f866eb4c905d25b8b4cd5/html5/thumbnails/45.jpg)
ISP Fail (sometimes)
public IRepository<T>{ T GetById(int id); IEnumerable<T> List(); void Create(T item); void Update(T item); void Delete(T item);}
![Page 46: Improving The Quality of Existing Software](https://reader038.fdocuments.us/reader038/viewer/2022110118/554f866eb4c905d25b8b4cd5/html5/thumbnails/46.jpg)
ISP OK (for CQRS for example)public IRepository<T> : IReadRepository<T>, IWriteRepository<T>{ }public IReadRepository<T>{ T GetById(int id); IEnumerable<T> List();}public IWriteRepository<T> void Create(T item); void Update(T item); void Delete(T item);}
![Page 47: Improving The Quality of Existing Software](https://reader038.fdocuments.us/reader038/viewer/2022110118/554f866eb4c905d25b8b4cd5/html5/thumbnails/47.jpg)
![Page 48: Improving The Quality of Existing Software](https://reader038.fdocuments.us/reader038/viewer/2022110118/554f866eb4c905d25b8b4cd5/html5/thumbnails/48.jpg)
Dependency Inversion PrincipleHigh-level modules should not depend on
low-level modules. Both should depend on abstractions.
Abstractions should not depend on details. Details should depend on abstractions.
Agile Principles, Patterns, and Practices in C#
![Page 49: Improving The Quality of Existing Software](https://reader038.fdocuments.us/reader038/viewer/2022110118/554f866eb4c905d25b8b4cd5/html5/thumbnails/49.jpg)
Dependency Inversion Principle• Depend on Abstractions– Interfaces, not concrete types
• Inject Dependencies into Classes
• Structure Solution so Dependencies Flow Toward Core– Onion Architecture (a.k.a. Ports and
Adapters)
![Page 50: Improving The Quality of Existing Software](https://reader038.fdocuments.us/reader038/viewer/2022110118/554f866eb4c905d25b8b4cd5/html5/thumbnails/50.jpg)
Application Layers
![Page 51: Improving The Quality of Existing Software](https://reader038.fdocuments.us/reader038/viewer/2022110118/554f866eb4c905d25b8b4cd5/html5/thumbnails/51.jpg)
Data Access EvolutionNo separation of concerns:
Data access logic baked directly into UI ASP.NET Data Source Controls Classic ASP scripts
Data access logic in UI layer via codebehind ASP.NET Page_Load event ASP.NET Button_Click event
User Interface
Database
Compile Time
Runtime
![Page 52: Improving The Quality of Existing Software](https://reader038.fdocuments.us/reader038/viewer/2022110118/554f866eb4c905d25b8b4cd5/html5/thumbnails/52.jpg)
Data Access : Helper Classes Calls to data made through
a utility
Example: Data Access Application Block (SqlHelper)
Logic may still live in UI layer
Or a Business Logic Layer may make calls to a Data Access Layer which might then call the helper
User Interface
Database
Compile Time
Runtime
Helper Class
![Page 53: Improving The Quality of Existing Software](https://reader038.fdocuments.us/reader038/viewer/2022110118/554f866eb4c905d25b8b4cd5/html5/thumbnails/53.jpg)
What’s Missing? Abstraction! No way to abstract
away data access
Tight coupling
Leads to Big Ball of Mud system
Solution: Depend on interfaces, not
concrete implementations What should we call such
interfaces? Repositories!
User Interface
Database
Compile Time
Runtime
CoreIFooRepository
InfrastructureSqlFooRepository
![Page 54: Improving The Quality of Existing Software](https://reader038.fdocuments.us/reader038/viewer/2022110118/554f866eb4c905d25b8b4cd5/html5/thumbnails/54.jpg)
DIP Architecture (aka Ports and Adapters)
![Page 55: Improving The Quality of Existing Software](https://reader038.fdocuments.us/reader038/viewer/2022110118/554f866eb4c905d25b8b4cd5/html5/thumbnails/55.jpg)
Common Dependencies
• Framework• Third Party Libraries• Database• File System• Email• Web Services• System Resources (Clock)• Configuration• The new Keyword• Static methods• Thread.Sleep• Random
See also responsibilities:• Persistence• Validation• Notification• Error Handling• Logging• Class Selection /
Construction• Formatting• Parsing• Mapping
![Page 56: Improving The Quality of Existing Software](https://reader038.fdocuments.us/reader038/viewer/2022110118/554f866eb4c905d25b8b4cd5/html5/thumbnails/56.jpg)
Common Refactorings
• Extract Class• Extract Interface / Apply Strategy
Pattern• Extract Method• Introduce Service Locator / Container
![Page 57: Improving The Quality of Existing Software](https://reader038.fdocuments.us/reader038/viewer/2022110118/554f866eb4c905d25b8b4cd5/html5/thumbnails/57.jpg)
DIP Fail
![Page 58: Improving The Quality of Existing Software](https://reader038.fdocuments.us/reader038/viewer/2022110118/554f866eb4c905d25b8b4cd5/html5/thumbnails/58.jpg)
Some Improvement (Façade)
![Page 59: Improving The Quality of Existing Software](https://reader038.fdocuments.us/reader038/viewer/2022110118/554f866eb4c905d25b8b4cd5/html5/thumbnails/59.jpg)
DIP OK (Strategy)
![Page 60: Improving The Quality of Existing Software](https://reader038.fdocuments.us/reader038/viewer/2022110118/554f866eb4c905d25b8b4cd5/html5/thumbnails/60.jpg)
DIP OK (Strategy)
![Page 61: Improving The Quality of Existing Software](https://reader038.fdocuments.us/reader038/viewer/2022110118/554f866eb4c905d25b8b4cd5/html5/thumbnails/61.jpg)
Self-Improvement and Quality• How fast can you produce:– Code you believe to be of high quality– Code that maybe gets the job done, but you
believe to be of low quality
• Which one can you produce more quickly?• Why?• How can we develop our skills and our
tools so that building quality is natural and easier than not doing so?
![Page 62: Improving The Quality of Existing Software](https://reader038.fdocuments.us/reader038/viewer/2022110118/554f866eb4c905d25b8b4cd5/html5/thumbnails/62.jpg)
Week 1 Week 2 Week 3 Week 4 Week 5 Week 6 Week 7 Week 8 Week 90
2
4
6
8
10
12
14
16
User Stories Completed
High Quality Low Quality Column1
![Page 63: Improving The Quality of Existing Software](https://reader038.fdocuments.us/reader038/viewer/2022110118/554f866eb4c905d25b8b4cd5/html5/thumbnails/63.jpg)
Week 1 Week 2 Week 3 Week 4 Week 5 Week 6 Week 7 Week 8 Week 90
2
4
6
8
10
12
14
16
18
20
User Stories Completed
High Quality Low Quality Column1
![Page 64: Improving The Quality of Existing Software](https://reader038.fdocuments.us/reader038/viewer/2022110118/554f866eb4c905d25b8b4cd5/html5/thumbnails/64.jpg)
Summary
• Maintain / Improve Application Code• Follow DRY/SOLID Principles• Use Characterization Tests to “fix”
behavior• Apply Common Refactorings• Re-run Tests After (and during)
Refactorings• Train and Practice to Write Better
Code Faster
![Page 65: Improving The Quality of Existing Software](https://reader038.fdocuments.us/reader038/viewer/2022110118/554f866eb4c905d25b8b4cd5/html5/thumbnails/65.jpg)
References
http://bit.ly/SFkpmq
Refactoring Catalog http://www.refactoring.com/catalog/index.html
Onion Architecture http://jeffreypalermo.com/blog/the-onion-architecture-pa
rt-1/
![Page 66: Improving The Quality of Existing Software](https://reader038.fdocuments.us/reader038/viewer/2022110118/554f866eb4c905d25b8b4cd5/html5/thumbnails/66.jpg)
Books
Refactoring http://amzn.to/110tscA
Refactoring to Patterns http://amzn.to/Vq5Rj2
Working Effectively with Legacy Code http://amzn.to/VFFYbn
Code Complete http://amzn.to/Vq5YLv
Clean Code http://amzn.to/YjUDI0
![Page 67: Improving The Quality of Existing Software](https://reader038.fdocuments.us/reader038/viewer/2022110118/554f866eb4c905d25b8b4cd5/html5/thumbnails/67.jpg)
Thank you!
@ardalis
ardalis.com
http://facebook.com/stevenandrewsmith