refactoring for software architecture smells
TRANSCRIPT
Refactoring for Software Architecture Smells: Managing Architecture Debt
Ganesh Samarthyam, Corporate Trainer and Author www.designsmells.com
Agenda• Introduction &
motivation
• What is architectural refactoring?
• Case studies in architectural refactoring
• Challenges in architecture refactoring
Why care about this topic?
City metaphor
“Cities grow, cities evolve, cities have parts that simply die while other
parts flourish; each city has to be renewed in order to meet the needs of its populace… Software-intensive systems
are like that. They grow, they evolve, sometimes they wither away, and
sometimes they flourish…”
Grady Booch in the foreword for “Refactoring for Software Design Smells: Managing Technical Debt”, Girish Suryanarayana, Ganesh Samarthyam, Tushar Sharma, Morgan Kaufmann/Elsevier, 2014.
“Infrastructure debt”!
What is technical debt?When,&due&to&constraints,&I&design&quickly&and&dirty,&my&project&is&loaded&with&technical&debt&
What is architecture debt?
…
Architecture)debt)
Architecture)smells)
Architecture)viola2ons)
Design)debt)
Design)smells)
Viola2ons)of)design)rules)
Test)debt)
Lack)of)tests)
Inadequate)test)coverage)
Code)debt)
Sta2c)analysis)tool)viola2ons)
Inconsistent)coding)style)
Refactoring a city?
Is this refactoring?
Architecture vs. agility?
Key reasons for architecture refactoring
Business needs
Increase feature velocity
Address architecture
decay
Realizing NFRs
Modernize
Reduce costs
Increase feature velocity
Bubbles don’t crash!
Address NFRs
Reduce costs
Address architecture decay
Modernize and get more profitable
What if I don’t do architecture refactoring?
Agenda• Introduction & motivation
• What is architectural refactoring?
• Case studies in architectural refactoring
• Challenges in architecture refactoring
Code refactoring
margin = c.getMargin();
if (c instanceof AbstractButton) {
margin = ((AbstractButton)c).getMargin();
} else if (c instanceof JToolBar) {
margin = ((JToolBar)c).getMargin();
} else if (c instanceof JTextComponent) {
margin = ((JTextComponent)c).getMargin();
}
Example: Refactoring for design smells
Earlier (relatively) mature work
Natural extension: Refactoring for architectural smells
The$red$lines$in$this$dependency$diagram$shows$
circular$dependencies$
Example: Architectural refactoring
Remove one of the dependencies
Change dependency direction Move one of the dependencies
Illustration: Refactoring for layering smells
Layer&A&
Layer&B&
Layer&C&
Layer&A&
Layer&B&
Layer&C&
Open layering Closed layering
Refactoring “missing layer” smell
This smell arises when one of the layers is missing (or when no layers are provided at all when
needed)
Layer&A&
Layer&B&
DAL&
Layer&A&
Layer&B&
Refactoring “violated layering” smell
Layer&A&
Layer&B&
Layer&C&
Layer&A&
Layer&B&
Layer&C&
Architecture)smells)
Duplicate)design)ar3facts)
Unclear)role)of)en33es)
Inexpressive)or)complex)architecture)
Everything)centralized)
Over>generic)design)
Asymmetric)structure)or)behavior)
Dependency)cycles)
Unnecessary)dependencies)
Implicit)dependencies)
Conway’ lawThe structure of a system mirrors the
structure of the organisation that
designed it
“Any organization that designs a system (defined broadly) will produce a design whose structure is a copy of the organization's communication structure.”Melvin E. Conway. "How do committees invent?", Datamation, 14(4):28–31, April 1968
Structure of a compiler team
Front-end team
Back-end team
Front-end team
Back-end team
Platform I Platform 2
Component interfaces vs. team boundaries
“Don't publish interfaces prematurely.
Modify your code ownership policies to smooth refactoring.”
– Martin Fowler (Refactoring, Addison-Wesley, 1999)
A guideline for code refactoring
A guideline for architecture refactoring
“Respect code ownership and retain team boundaries to
ensure smooth refactoring.”
Code refactoring Architecture refactoring
A module-level or class-level concern A system level concern that cuts across modules or sub-systems
Impact of refactoring is within a team Impact of refactoring is often across teams
Typically performed to improve the internal structure of the code
Performed for various reasons: cost, legal, security, performance, availability, …
Management buy-in typically not required Management buy-in is typically required
Upfront planning is typically (relatively) limited
Upfront planning and co-ordination (sometimes between teams) is often required
Unit tests are important to ensure that “behaviour is preserved”
Unit tests, integration tests, system tests, NFR tests, … are required
Risk of breaking the working software is relatively low
Risk of breaking the working software is relatively high
Real-world analogy: “fixing potholes”
Real-world analogy: “metro construction”
Agenda• Introduction & motivation
• What is architectural refactoring?
• Case studies in architectural refactoring
• Challenges in architecture refactoring
Architecture represents the significant design decisions that shape a
system, where significant is measured by cost of change.
- Grady Booch (2006)
NFRs
Constraints
TechnologyCross-cutting concerns
Others (e.g.: overall
structure)
Dimensions of ADs
Case study: Skipping security layer
Case study: Platform L & F
The example of “how much effort & time” it requires to provide the feature
to change the color of a button!
Case study: OSS in a product
COTS(Commercial Off The Shelf)
FOSS(Free and Open Source Software)
Make Buy / Reuse
Proven Modern / Latest
Cross-cutting concerns
Error/Exception handling
ConcurrencyPersistence
Event handling
Interaction and presentation
Source: SWEBOK v3
Case study: Using Structured EH
Source: https://msdn.microsoft.com/en-us/library/windows/desktop/ms681409(v=vs.85).aspx
Structured Exception Handling in VC++
Standard Exception Handling supported in modern C++ compilers
bool SafeDiv(Number dividend, Number divisor, Number &result) {
try { result = dividend / divisor;
} catch(Number::divide_by_zero ex) { return false;
} return true;
}
BOOL SafeDiv(Number dividend, Number divisor, Number &result) {
__try { result = dividend / divisor;
} __catch(GetExceptionCode() == EXCEPTION_INT_DIVIDE_BY_ZERO ? EXCEPTION_EXECUTE_HANDLER : EXCEPTION_CONTINUE_SEARCH) { return FALSE;
} return TRUE;
}
Handling persistence
Oracle DB
Component-1
Component-2
Component-N
[establish connection, SQL
queries, close connection…]
No clone within a component, but
duplication of code across components
How to support different databases?
[establish connection, SQL
queries, close connection…]
[establish connection, SQL
queries, close connection…]
Handling persistence
Component-1
Component-2
Component-N
Service layer / DAL
Agenda• Introduction & motivation
• What is architectural refactoring?
• Case studies in architectural refactoring
• Challenges in architecture refactoring
Key challenges in architecture refactoring
Getting management
buy-in
Fear of breaking working software
Lack of tool support
Merge process problems
How to get management buy-in?
logger.severe(“details”)
errlog.log(“details”)logger.error(“details”)
System.err.println(“details”)
Since ROI (Return On Investment) is not clear, how to get
management buy-in for this architectural refactoring?
Log4j java.util.logging custom log library SOPs
Dealing with the fear of “breaking the working software”
Module 1 Module 2 Module N
How to validate architectural refactoring changes?
Currently through architecture, design, and code reviews + running system, integration, and unit tests =>
Can still break the working software!
Lack of tool support
Unlike code refactoring, most architectural refactoring is manual
due to lack of tool support!
Automated code smell detection and refactoring
Lack of tool support
Lack of automated support for architectural refactoring
Inadequate support for detecting smells
Limited support for quantifying architectural debt
…
Merge process problems
Challenge I: How to handle merges from distributed teams?
Challenge II: How to merge changes from long-running branches?
Illustration: How to co-ordinate changes in distributed teams?
Module 1
Country 1
Module 2
Country 2
Module N
Country N
How do co-ordinate refactoring when code ownership is distributed with
teams across the globe? (more pronounced in refactoring situations)
Illustration: How to deal with changes in long-running branches?
Module 1
Module 2
Module N
6 months
Key take-awaysArchitecture smells and violations contribute to technical debt (known as architecture debt)
Architecture refactoring plays a key role in enhancing agility and enables business success
Code refactoring and architecture refactoring are altogether different ballgames
Architecture smells can be viewed in terms of Architectural Decisions (ADs)
Refactoring for replaying architecture debt is an emerging topic
Image credits• http://sustainablecitiescollective.com/pratik-dave/244831/bangalore-exclusive-metro-india-having-profit-making-public-
transport-system
• http://www.medsoftwaresys.com/mss/wp-content/uploads/2012/04/reengineering.png
• http://topnews.in/files/Bangalore-Metro-Rail-Corporation-Ltd.jpg
• https://www.itdp.org/wp-content/uploads/2014/07/Chennai-Rendering.jpg
• http://www.vectors4all.net/preview/database-clip-art.jpg
• http://static.planetminecraft.com/files/resource_media/screenshot/1231/Windows-Vs-Mac_3072108.jpg
• http://manuel.midoriparadise.com/public_html/icons/linux-icon.png
• http://mortalpowers.com/posse/1280x1280/0DSC03205.JPG
• http://images.clipartpanda.com/server-computer-clipart-1216179635943364667jcartier_central_computer_1.svg.hi.png
• http://images.clipartpanda.com/cloud-icon-png-clouds.png
• http://www.clipartbest.com/cliparts/dc6/M5L/dc6M5LBc9.jpeg
• http://cdn.ttgtmedia.com/rms/computerweekly/refactor.jpg
• http://yellowairplane.com/Adventures/Falkland_Islands_War_Guestbook/Falkands_War_Malvinas_War_Photos/Jet_Fighter_Mirage_2000_Takeoff_Argentina.jpg