Upload
lionel-murphy
View
223
Download
0
Tags:
Embed Size (px)
Citation preview
Module 1. Introducing
Course: Refactoring
Overview
Definition
Principles
Building Tests
Bad Smells in Code
Definition
Refactoring is the process of changing a software system in such a way that it does not alter the external behavior of the code yet improves its internal structure.
It is a disciplined way to clean up code that minimizes the chances of introducing bugs.
In essence when you refactor you are improving the design of the code after it has been written.
Defining Refactoring
Refactoring (noun): a change made to the internal structure of software to make it easier to understand and cheaper to modify without changing its observable behavior.
Refactor (verb): to restructure software by applying a series of refactorings without changing its observable behavior.
Individuals and interactions over processes and tools
Working software over comprehensive documentation
Customer collaboration over contract negotiation documentation
Responding to change over following a plan
http://www.agilemanifesto.org/
Building on the Foundations Laid by Others
Ward Cunningham
Kent Beck
Ralph Johnson
Bill Opdyke
John Brant
Don Roberts
Martin Fowler
Demo: IDE
Conduct Refactoring with IDE
Lesson: Principles in Refactoring
Why? When? What?
Indirection and Refactoring
Problems with Refactoring
Refactoring and Design and Performance
The Environment for Refactoring
Two approaches
Thinking in Refactoring
Why Should You Refactor?
Refactoring Improves the Design of Software
Refactoring Makes Software Easier to Understand
Refactoring Helps You Find Bugs
Refactoring Helps You Program Faster
Refactoring Makes coding less annoying
When Should You Refactor?
Refactor When You Add Function
Refactor When You Need to Fix a Bug
Refactor As You Do a Code Review
The Rule of Three (Don Roberts)
What Do I Tell My Manager?
Good Manager
Bad Manager
Design Debt (Ward Cunningham)
“Not fix what ain't broken“
Ask: "How many months in a row do you not pay down your debt?" (show your credit card)
Indirection and Refactoring
To enable sharing of logic
To explain intention and implementation separately
To isolate change
To encode conditional logic
Problems with Refactoring
Hard to see that greatly improves your productivity
Databases
Changing Interfaces
Design Changes That Are Difficult to Refactor
When Shouldn't You Refactor?
Refactoring and Design and Performance
Upfront design vs Extreme Programming
Only refactoring does work, it is not the most efficient
A greater movement toward simplicity of design
How difficult is it going to be to refactor a simple solution into the flexible solution?
Refactoring and Performance
“With design I can think very fast, but my thinking is full of little holes”
Alistair Cockburn
Breakthrough
The Environment for Refactoring
Team or Partner
Tests
Testing Framework
CRC Cards or UML Sketches
Configuration and Version Control
Sophisticated IDE
Two approaches
Code-First Refactoring
Test-First Refactoring
Combination method
Thinking in Refactoring
november(20, 2005) java.util.Calendar c = java.util.Calendar.getInstance();
c.set(2005, java.util.Calendar.NOVEMBER, 20);
c.getTime();
Many Eyes
Human-Readable Code
Rules
Keeping It Clean
Small Steps
Design Debt
«Any fool can write code that a computer can understand. Good programmers write code that humans can understand»
Martin Fowler, Refactoring: Improving the Design of Existing Code
Exercise: Inside a Refactoring
Create Extract Method Refactoring
Pick a refactoring and identify a place where the approach builds in small steps even though larger steps could work.
Exercise Discussion
Small Steps
Simple Design
passes all tests communication no duplication fewest classes and methods
Lesson: Building Tests
The Value of Self-testing Code
The xUnit Testing Framework
Test Location
Tips
The Value of Self-testing Code
The essential precondition is time
Greatly speeds your programming
Fully automatic
A powerful bug detector
Prime technique for Refactoring
Type: inline, friend, reflection
JUnit
import junit.framework.TestCase;
public class MyTest extends TestCase {
public void test () {
…
public class MyMain {
public static void main (String[] args) {
new junit.textui.TestRunner().doRun(new MatcherTest());
NUnit
using NUnit.Framework;
[TestFixture]
public class DatabaseFixture
{
[SetUp]
public void CreateDatabaseObjects() { ... }
…
[Test]
public void ReadOneObject() { ... }
}
The NUnit Testing Framework
Test Location
Within Classes
Another Solution + public interfaces
Another Solution + Reflection
Tips
Run your tests frequently
Testing should be risk driven
It is better to write and run incomplete tests than not to run complete tests
Think of the boundary conditions
Use exceptions
Testing can't catch all bugs, but most ones
Demo: jUnit test
Demonstration
Lesson: Bad Smells in Code
Definition
Simple Design
Design Principles
Smells Catalog
Database Smells
Architectures Smells
Bad Smells in Code
Smells (especially code smells) are warning signs about potential problems in code.
If it stinks, change it.
Grandma Beck, discussing
child-rearing philosophy
Simple Design
Runs all the tests.
Has no duplicated logic. Be wary of hidden duplication like parallel class hierarchies.
States every intention important to the programmers.
Has the fewest possible classes and methods.—Beck, Extreme Programming Explained, p. 57
Design Principles
DRY : Don’t Repeat Yourself
SCP : Speaking Code
OCP : Open Closed
LSP : Liskov Substitution
DIP : Dependency Inversion
ISP : Interface Segregation
REP : Reuse/Release Equivalency
CRP : Common Reuse
CCP : Common Closure
ADP : Acyclic Dependencies
SDP : Stable Dependencies
SAP : Stable Abstractions
TDA : Tell, Don’t Ask
SOC : Separation Of Concerns
Stefan Rock. Refactoring in Large Software. 2006
Some depends
Methods <= 30 code lines
A Class <= 30 methods
A Package <= 30 classes
Subsystems <= 30 packages
System <= 30 subsystems
3-10 Layers
Methods <= 10 code lines
A Class <= 10 methods
A Package <= 10 classes
Subsystems <= 10 packages
System <= 10 subsystems
3-10 Layers
Smells CatalogW
ith
inNames
Type Embedded in Name (including Hungarian)Uncommunicative NameInconsistent Names
Dead CodeSpeculative Generality
Unnecessary Complexity
Magic NumberDuplicated CodeAlternative Classes with Different Interfaces
Duplication Conditional Logic
Null CheckComplicated Boolean ExpressionSpecial CaseSimulated Inheritance (Switch Statement)
Bet
wee
n
Data
Primitive ObsessionData ClassData ClumpTemporary Field
Refused BequestInappropriate Intimacy (Subclass Form)Lazy ClassSimulated Inheritance (Switch Statement)Parallel Inheritance HierarchiesCombinatorial Explosion
Inheritance
Feature EnvyInappropriate Intimacy (General Form)Message ChainsMiddle Man
Responsibility Accommodating Change Library Classes
Divergent ChangeShotgun SurgeryParallel Inheritance HierarchiesCombinatorial Explosion
Incomplete Library Class
Database Smells
Architecture Smells
Dependency Graphs Inheritance Hierarchies Packages LayersSubsystems
Cla
sses
Measured
CommentsLong MethodLarge ClassLong Parameter List
Test Smells (Code)
Obscure test
Conditional test logic
Hard to test code
Test code duplicated
Test Logic in Production
…Visit “Test-Driven
Development Course”
Database Smells
Multipurpose column.
Multipurpose table.
Redundant data.
Tables with too many columns.
Tables with too many rows.
"Smart" columns.
Fear of change.
Visit “Database Refactoring Course”
Architectures Smells
visible dependencygraphs
cycle betweenclasses
unused classes
tree-likedependency graphs
parallel inherencehierarchies
inheritance hierarchy
without polymorphicassignments
inherence hierarchies
to deep
like-listinherence
hierarchies
type query
subclasses withoutredifinitions
unused packages
too smallpackages
cycle betweenpackages
too largepackages
packagesunclearly named
packagestoo deep or nesting
unbalanced
subsystem overgeneralized subsystem API
bypassed
subsystem too small
cycle betweensubsystems
subsystem APItoo large
too manysubsystems
subsystemtoo large
no subsystems
inheritance betweenprotocol oriented
layers
upward referencesin layers
too many layers
no layersstrict layers violated
reference betweenvertically separate
layers
Dependency graphs
Inheritance hierarchies
Packages
Subsystems
Layers
SA4J: Dependencies
NDepend
Software visualization
Sotograph
JDepend / NDepend
Eclipse Metrics Plugin , JDepend4Eclipse
Dr. Freud
SonarJ
ClassCycle
SA4J
http://en.wikipedia.org/wiki/Software_visualization
Management Smells
Absentee Manager
All you have is a Hammer
Golden Child
Leader not Manager / Manager not Leader
Metric Abuse
Road to Nowhere
…
Smell - its name
Symptoms — cues that help you spot it
Causes — notes on how it might happen
What to do — possible refactorings
Payoff — the ways your code will improve
Contraindications — when not to fix it
Exercise: Real Project
Review real project
Smells list
Review
Definition
Principles
Building Tests
Bad Smells in Code