SOE bottom-up design - refactoring and patterns

SOE
bottom-up design - refactoring and patterns
the design problem:
• the software design inadequately
solves the problem, creating issues
such as performance, usability,
maintainability, adaptivity,
portability, security, ……………
• software erosion
• leads to: (the quality problem: the
system is delivered with bugs,
service and usability problems that
make it difficult to use)
SOE: refactoring and patterns
2
architecture
components
modules
architecture
screen sketch
object model
ERM
design as model
design as code
screen code
object code
database tables
design style
algorithm design
data validation
exception handling
detailed design
abstraction level
SOE: refactoring and patterns
3
top-down v.
evolutionary design
architecture
traditional
agile
design as model
design as code
detailed design
SOE: refactoring and patterns
4
top down design - MDA
(Model Driven Architecture)
executable UML
compiler
J2EE
.NET
archetype
SOE: refactoring and patterns
5
bottom-up design – refactoring
‟Refactoring: improving the design of existing code‟
Marting Fowler, Addison Wesley
bottom up design: 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
• refactoring is not:
• debugging
• mending business logic
• adding new functionality
Martin Fowler (and Kent Beck, John Brant, William Opdyke, Don Roberts), Refactoring - Improving the
Design of Existing Code, Addison Wesley, 1999
SOE: refactoring and patterns
7
simple refactoring example
case 0:
activePiece = RightHookgetRightHook();
case 0:
activePiece = RightHookgetRightHook();
ml = new MoveListener(activePiece);
gameBoardaddKeyListener(ml);
break;
case 1:
case 1:
activePiece = LeftHookgetLeftHook();
activePiece = RightRisegetRightRise();
activePiece = RightRisegetRightRise();
activePiece = LeftRisegetLeftRise();
case 3:
break;
case 4:
activePiece = HillgetHill();
case 5:
break;
activePiece = StraightPiecegetStraightPiece(); break;
ml = new MoveListener(activePiece);
gameBoardaddKeyListener(ml);
break;
break;
case 3:
gameBoardaddKeyListener(ml);
break;
case 2:
break;
case 2:
activePiece = LeftHookgetLeftHook();
ml = new MoveListener(activePiece);
break;
case 6:
activePiece = SquaregetSquare();
break;
}
activePiece = LeftRisegetLeftRise();
ml = new MoveListener(activePiece);
ml = new MoveListener(activePiece);
gameBoardaddKeyListener(ml);
gameBoardaddKeyListener(ml);
break; //more
SOE: refactoring and patterns
8
why refactor?
refactoring improves design
without refactoring, even a well designed program will decay („go sour‟) as
programmers make changes
refactoring makes software easier to understand
understandable code is easier to update and maintain
refactoring helps find bugs
refactoring involves clarification and re-shaping through better
understanding
refactoring speeds up programming
good design ensures comprehensibility and fewer changes as new
functionality is added
SOE: refactoring and patterns
9
bad smells
•
•
•
•
•
•
•
•
•
•
•
•
duplicate code: identical or very similar code exists in more than one location
large method: a method, function, or procedure that has grown too large
large class: a class that has grown too large (god object)
feature envy: a class that uses methods of another class excessively
inappropriate intimacy: a class that has dependencies on implementation details of
another class
data clumps: a set of variables that seem to “hang out” together – e.g. often passed as
parameters, changed/accessed at the same time
primitive obsession: all subparts of an object are instances of primitive types (int, string,
bool, double, etc)
refused bequest: a class that overrides a method of a base class in such a way that the
contract of the base class is not honored by the derived class
lazy class: a class that does too little
duplicated method: a method, function, or procedure that is very similar to another
contrived complexity: forced usage of overly complicated design patterns where simpler
design would suffice
…………
SOE: refactoring and patterns
10
refactoring (n): a standard way of improving poor code
bad smell
SOE: refactoring and patterns
Add Parameter
Change Bidirectional Association to Unidirectional
Change Reference to Value
Change Unidirectional Association to Bidirectional
Change Value to Reference
Collapse Hierarchy
Consolidate Conditional Expression
Consolidate Duplicate Conditional Fragments
Convert Dynamic to Static Construction by Gerard M. Davison
Convert Static to Dynamic Construction by Gerard M. Davison
Decompose Conditional
Duplicate Observed Data
Eliminate Inter-Entity Bean Communication (Link Only)
Encapsulate Collection
Encapsulate Downcast
Encapsulate Field
Extract Class
Extract Interface
Extract Method
Extract Package by Gerard M. Davison
Extract Subclass
Extract Superclass
Form Template Method
Hide Delegate
Hide Method
Hide presentation tier-specific details from the business tier (Link
Only)
Inline Class
Inline Method
Inline Temp
Introduce A Controller (Link Only)
Introduce Assertion
Introduce Business Delegate (Link Only)
Introduce Explaining Variable
Introduce Foreign Method
Introduce Local Extension
Introduce Null Object
Introduce Parameter Object
Introduce Synchronizer Token (Link Only)
Localize Disparate Logic (Link Only)
Merge Session Beans (Link Only)
Move Business Logic to Session (Link Only)
Move Class by Gerard M. Davison
Move Field
Move Method
Parameterize Method
Preserve Whole Object
Pull Up Constructor Body
Pull Up Field
Pull Up Method
Push Down Field
Push Down Method
Reduce Scope of Variable by Mats Henricson
Refactor Architecture by Tiers (Link Only)
Remove Assignments to Parameters
Remove Control Flag
Remove Double Negative by Ashley Frieze and Martin Fowler
Remove Middle Man
Remove Parameter
Remove Setting Method
Rename Method
Replace Array with Object
Replace Assignment with Initialization by Mats Henricson
Replace Conditional with Polymorphism
Replace Conditional with Visitor by Ivan Mitrovic
Replace Constructor with Factory Method
Replace Data Value with Object
Replace Delegation with Inheritance
Replace Error Code with Exception
Replace Exception with Test
Replace Inheritance with Delegation
Replace Iteration with Recursion by Dave Whipp
Replace Magic Number with Symbolic Constant
Replace Method with Method Object
Replace Nested Conditional with Guard Clauses
Replace Parameter with Explicit Methods
Replace Parameter with Method
Replace Record with Data Class
Replace Recursion with Iteration by Ivan Mitrovic
Replace Static Variable with Parameter by Marian Vittek
Replace Subclass with Fields
Replace Temp with Query
Replace Type Code with Class
Replace Type Code with State/Strategy
Replace Type Code with Subclasses
Reverse Conditional by Bill Murphy and Martin Fowler
Self Encapsulate Field
Separate Data Access Code (Link Only)
Separate Query from Modifier
Split Loop by Martin Fowler
Split Temporary Variable
Substitute Algorithm
Use a Connection Pool (Link Only)
Wrap entities with session (Link Only)
11
very simple example
title
titleText
titleX
titleY
titleColour
bad smell: data clump
refactoring: extract class
SOE: refactoring and patterns
12
class Customer extends DomainObject
{
public Customer(String name) {
_name = name;
}
public String statement() {
double totalAmount = 0;
int frequentRenterPoints = 0;
Enumeration rentals = _rentals.elements();
String result = "Rental Record for " + name() + "\n";
while (rentals.hasMoreElements()) {
double thisAmount = 0;
Rental each = (Rental) rentals.nextElement();
//determine amounts for each line
switch (each.tape().movie().priceCode()) {
case Movie.REGULAR:
thisAmount += 2;
if (each.daysRented() > 2)
thisAmount += (each.daysRented() - 2) * 1.5;
break;
case Movie.NEW_RELEASE:
thisAmount += each.daysRented() * 3;
break;
case Movie.CHILDRENS:
thisAmount += 1.5;
if (each.daysRented() > 3)
thisAmount += (each.daysRented() - 3) * 1.5;
break;
Fowler’s video shop
example
}
totalAmount += thisAmount;
// add frequent renter points
frequentRenterPoints ++;
// add bonus for a two day new release rental
if ((each.tape().movie().priceCode() == Movie.NEW_RELEASE) && each.daysRented()
> 1) frequentRenterPoints ++;
//show figures for this rental
result += "\t" + each.tape().movie().name()+ "\t" + String.valueOf(thisAmount) +
"\n";
refactor: replace condition with polymorphism
points";
}
//add footer lines
result +=Movie
"Amount owed is " + String.valueOf(totalAmount)
Price + "\n";
result += "You earned " + String.valueOf(frequentRenterPoints)
+ " frequent renter
1
return
result;
charge()
}
public void addRental(Rental arg) {
_rentals.addElement(arg);
}
public static Customer get(String name) {
<<code>>
1
return (Customer) Registrar.get("Customers",
name);
ChildrensPrice
return} priceCode.charge()
public void persist() {
Registrar.add("Customers", this); charge()
}
private Vector _rentals = new Vector();
SOE: refactoring and patterns
charge()
RegularPrice
charge()
1
NewRelease 1
Price
charge()
13
common refactorings
• push down method - behaviour on a super class is relevant only for some of
its subclasses‟ - the method is moved to those subclasses
• extract subclass - „a class has features that are used only in some instances‟
- a subclass is created for that subset of features
• encapsulate field - the declaration of a field is changed from public to
private
• hide method - „a method is not used by any other class‟ - the method
should be made private
• pull up field - „two subclasses have the same field‟ - the field in question
should be moved to the super class
• extract super class – „two classes with similar features‟ - in this case, create
a super class and move the common features to the super class
SOE: refactoring and patterns
14
common refactorings
• push down field - a field is used only by some subclasses‟ - the field is
moved to those subclasses
• pull up method - methods with identical results in subclasses‟ - methods
should be moved to the super class
• move method - a method is, or will be, using or used by more features of
another class than the class on which it is defined‟
• move field - a field is, or will be, used by another class more than the class
on which it is defined‟
• rename method - a method is renamed to make its purpose more obvious.
• rename field - field is renamed to make its purpose more obvious
SOE: refactoring and patterns
15
refactoring principles
• make changes small and methodical
• follow design patterns
• have your test suites ready
• refactoring introduces new bugs
• sometimes in unrelated parts of the
programme
• run test suites each time you refactor
• clean before you add new functionality
SOE: refactoring and patterns
16
two dubious refactoring practices
refactoring the architecture
refactoring: „extract package‟, „refactor architecture by tiers‟
• large scale decisions about the organisation of the program taken too late in
the construction because of insufficient overview
• liable to cause chaos unless extremely well thought out
the refactoring sprint(s)
• some weeks in the life of the project, paid for by the customer, where the
only purpose is to rectify relatively serious design problems caused by lack of
real understanding of the user domain and too early commitment to
programming
SOE: refactoring and patterns
17
traditional view of refactoring
• refactoring reflects poor analysis and design
work – do it right first time
• refactoring is expensive – all prior
documentation must be altered
• refactoring introduces new errors in
unpredictable places
• refactoring threatens architectural integrity
• customers expect new functionality and will
not pay for rework
• refactoring does not extend value – if it ain‟t
broke don‟t fix it
SOE: refactoring and patterns
18
bottom-up design: patterns
the pattern movement
pattern
•
•
•
•
•
•
•
•
a pattern addresses a recurring problem that arises in specific
situations
patterns document existing, well-proven design experience
patterns identify and specify abstractions that are above the level of
single classes and instances
patterns provide a common vocabulary and understanding for design
principles
patterns are a means of documenting software architectures
patterns support the construction of software with defined properties
patterns help you build complex and heterogeneous software
architectures
patterns help you manage software complexity
SOE: refactoring and patterns
20
standard documentation form
pattern name and classification: a descriptive and unique name that helps in identifying and
referring to the pattern
intent: a description of the goal behind the pattern and the reason for using it
also known as: other names for the pattern
motivation (forces): a scenario consisting of a problem and a context in which this pattern can be
used
applicability: situations in which this pattern is usable; the context for the pattern
structure: a graphical representation of the pattern – class diagrams and interaction diagrams may
be used for this purpose
participants: a listing of the classes and objects used in the pattern and their roles in the design
collaboration: a description of how classes and objects used in the pattern interact with each
other
consequences: a description of the results, side effects, and trade offs caused by using the pattern
implementation: a description of an implementation of the pattern; the solution part of the
pattern
sample code: an illustration of how the pattern can be used in a programming language
known uses: examples of real usages of the pattern
related patterns: other patterns that have some relationship with the pattern; discussion of the
differences between the pattern and similar patterns
SOE: refactoring and patterns
21
types of patterns
•
•
•
•
analysis patterns
design patterns/GRASP
software architecture patterns
organizational and process patterns
SOE: refactoring and patterns
22
analysis patterns
•
•
patterns that reflect
the generic conceptual
structure of business
processes rather than
actual software
implementations
simple, specialized
notation (very similar
to entity-relationship
diagram notation)
‘Analysis Patterns: Reusable
Object Models’, Martin Fowler
SOE: refactoring and patterns
analysis problem
analysis pattern
23
organisational and process patterns
• research into social and
behavioural patterns in
software firms which lead to
successful outcomes
Coplien‟s top ten patterns
•
•
•
•
•
•
•
•
•
•
SOE: refactoring and patterns
unity of purpose
engage customers
domain expertise in roles
architect controls product
distribute work evenly
function owner and
component owner
mercenary analyst
architect also implements
firewalls
developer controls process
24
design anti-patterns
•
•
•
•
•
•
•
•
•
•
big ball of mud: a system with no recognizable structure
database-as-ipc: using a database as the message queue for routine inter-process
communication where a much more lightweight mechanism would be suitable
gas factory: an unnecessarily complex design
gold plating: continuing to work on a task or project well past the point at which
extra effort is adding value
inner-platform effect: a system so customizable as to become a poor replica of the
software development platform
input kludge: failing to specify and implement handling of possibly invalid input
interface bloat: making an interface so powerful that it is extremely difficult to
implement
magic pushbutton: coding implementation logic directly within interface code,
without using abstraction
race hazard: failing to see the consequence of different orders of events
stovepipe system: a barely maintainable assemblage of ill-related components
SOE: refactoring and patterns
25
design patterns
•
•
•
•
•
design patterns provide abstract, reusable “micro-architectures” that
can be applied (“instantiated”) to resolve specific design issues
(forces) in previously-used, high-quality ways
GoF (Gang of Four)
creational - manage instantiation - can be further divided into classcreation (use inheritance effectively) patterns and object-creational
(use delegation) patterns
structural - concern class and object composition - use inheritance to
compose interfaces and define ways to compose objects to obtain new
functionality
behavioural - concerned with communication between objects
GAMMA, E., HELM, R., JOHNSON, R. & VLISSIDES, J. (1995)
Design Patterns, Boston, Addison-Wesley.
SOE: refactoring and patterns
26
GoF creational patterns:
• abstract factory groups object factories that have a common
theme
• builder constructs complex objects by separating construction
and representation
• factory method creates objects without specifying the exact
class to create
• prototype creates objects by cloning an existing object
• singleton restricts object creation for a class to only one
instance
SOE: refactoring and patterns
27
GoF structural patterns:
• adapter allows classes with incompatible interfaces to work together by
wrapping its own interface around that of an already existing class
• bridge decouples an abstraction from its implementation so that the two
can vary independently
• composite composes zero-or-more similar objects so that they can be
manipulated as one object
• decorator dynamically adds/overrides behaviour in an existing method of
an object
• façade provides a simplified interface to a large body of code
• flyweight reduces the cost of creating and manipulating a large number of
similar objects
• proxy provides a placeholder for another object to control access, reduce
cost, and reduce complexity
SOE: refactoring and patterns
28
GoF behavioral patterns: concerned with communication
between objects
•
•
•
•
•
•
•
•
•
•
•
chain of responsibility delegates commands to a chain of processing objects
command creates objects which encapsulate actions and parameters
interpreter implements a specialized language
iterator accesses the elements of an object sequentially without exposing its
underlying representation
mediator allows loose coupling between classes by being the only class that has
detailed knowledge of their methods
memento provides the ability to restore an object to its previous state (undo)
observer is a publish/subscribe pattern which allows a number of observer objects
to see an event
state allows an object to alter its behavior when its internal state changes
strategy allows one of a family of algorithms to be selected on-the-fly at runtime
template method defines the skeleton of an algorithm as an abstract class, allowing
its subclasses to provide concrete behavior
visitor separates an algorithm from an object structure by moving the hierarchy of
methods into one object
SOE: refactoring and patterns
29
pattern use example
Movie
1
charge()
<<code>>
return priceCode.charge()
Price
charge()
ChildrensPrice1
charge()
RegularPrice
charge()
1
NewRelease 1
Price
charge()
state pattern
singleton pattern
SOE: refactoring and patterns
30
GRASP (General Responsibility Assignment Software Patterns)
•
•
•
•
information expert: allocating responsibilities (methods, computed fields etc.) by
determining which class has the most relevant data variables
creator: determines which class should govern creation of new instances of classes
in non-trivial situations. Given two classes (A,B), class B should be responsible for
the creation of A if class B contains or compositely aggregates, records, closely
uses or contains the initializing information for class A (see also factory)
controller: assigns the responsibility of dealing with system events to a non-UI class
that represents a use case scenario(s) - the first object beyond the UI layer that
receives and coordinates a system operation. The controller should delegate to
other objects the work that needs to be done
low coupling: determines low dependency between classes, low impact in a class of
changes in other classes and high reuse potential
SOE: refactoring and patterns
31
GRASP 2
•
•
•
•
•
high cohesion: the responsibilities of a given element are strongly related and highly
focused
polymorphism: responsibility for defining the variation of behaviors based on type is
assigned to the types for which this variation happens
pure fabrication: a class that does not represent a concept in the problem domain
but is added to achieve low coupling, high cohesion, and the reuse potential thereof
indirection: supports low coupling between two elements by assigning the
responsibility of mediation between them to an intermediate object e.g. controller
in MVC.
protected variations: protects elements from variations on other elements by
wrapping the focus of instability with an interface and using polymorphism to
create various implementations of this interface.
SOE: refactoring and patterns
32
architectural patterns
“.....an architectural pattern expresses a fundamental structural organisation
schema for software systems. It provides a set of predefined subsystems,
specifies their responsibilities, and includes rules and guidelines for
organizing the relationships between them”
• from mud to structure
• layers
• pipes and filters
• blackboard
• distributed systems
• broker
• interactive systems
• model-view-controller
• presentation-abstractioncontrol
• adaptable systems
• microkernel
• reflection
BUSCHMAN, F., MEUNIER, R., ROHNERT, H., SOMMERLAD, P. & STAL, M. (1996) Patternoriented Software Architecture, Chichester, Wiley.
SOE: refactoring and patterns
33
architectural patterns: from mud to structure
layers
pipes and filters
example
OSI model
problem
large system with high and low
level functions requiring
decomposition
example
problem
process or transform a data
stream
structure
layer j provides services used by
j+1, delegates subtasks to j-1
structure
known use
TCP protocol, IS
•filter: collects, transforms and
outputs data supplied by pipe
•pipe: transfers, buffers data
and synchronizes with
neighbours
•data source: delivers data to
pipe
•data sink: consumes output
known use
UNIX program compilation
and documentation creation
presentation
application logic
domain layer
database
SOE: refactoring and patterns
34
architectural patterns: from mud to structure
blackboard
problem
no feasible deterministic
solution for transforming data
into high level structures
(diagrams, tables, language
phrases)
structure
a collection of independent
programs that work cooperatively on common data
•blackboard: central data store
•knowledge source: evaluates
its own applicability, computes
a result, updates blackboard
known use
speech and image recognition,
vision, surveillance
SOE: refactoring and patterns
35
architectural patterns: distributed systems
broker
problem
manage distributed and possibly
heterogeneous systems with
independent operating components
structure
•client: implements user functionality
•server: implements services
•broker: locates, registers and
communicates with servers,
interoperates with other brokers
through bridges
•client side proxy: mediates between
client and broker
•server side proxy: mediates between
server and broker
•bridge: mediates between local broker
and bridge of a remote broker
known
use
CORBA, WWW
SOE: refactoring and patterns
36
architectural patterns: interactive systems
model-view-controller
problem
interactive systems with flexible
and change prone user interface
structure
•model: provides central data and
function logic
•view: displays information to the
user
•controller: accepts inputs and
makes service requests for the
model, display requests for view
known
use
Smalltalk systems
SOE: refactoring and patterns
37
architectural patterns: interactive systems
presentation-abstractioncontrol
problem
interactive systems as a set of
cooperating agents
structure
tree hierarchy of PAC agents,
with one top level agent –
each agent has:
•presentation: visible
behaviour of the agent
•abstraction: maintains data
and provides core
functionality
•control: connect
presentation and abstraction
and communicate with other
agents
known use
network traffic control
SOE: refactoring and patterns
38
architectural patterns: adaptable systems
microkernal
problem
application domains with broad spectrums of standards and programming technologies,
continuous hardware and software evolution. Software should be portable, extensible,
adaptable
structure
•microkernal: provides core services, manages resources and communication
•internal server: implements additional services
•external server: provides programming interfaces for clients
•client: represents an application
•adapter: hides system dependencies, invokes methods of external servers on behalf of
clients
known use
Windows NT
SOE: refactoring and patterns
39
architectural patterns: adaptable systems
reflection
problem
systems exposed to changing
technology and requirements, and
support their own modification
structure
•base level: implements the application
logic using information from meta level
•meta level: encapsulates system
internals that may change and provides
interface to facilitate modifications to
meta-level
•metaobject protocol: interface for
specifying and performing changes to
meta level
known
use
OLE 2.0
SOE: refactoring and patterns
40
potential benefits of patterns
•
•
•
•
provides a common vocabulary and
understanding of design elements for software
designers
increases productivity in design process due to
design reuse
promotes consistency and high quality of system
designs and architectures due to application of
tested design expertise and solutions embodied
by patterns
allows all levels of designers, from novice to expert,
to gain these productivity, quality and consistency
benefits
SOE: refactoring and patterns
41
concerns
•
•
•
•
benefits are dependent upon architects, analysts and
designers understanding the patterns to be used – the
common “design vocabulary”
such training can be costly, and in many cases is
proprietary and cannot be obtained externally
specific funding and effort must be directed toward
maintenance and evolution of patterns as reusable assets
or they tend to devolve into project/application-specific
artifacts with dramatically reduced reusability
characteristics
promotes design culture at the expense of analysis culture
– less focus on responding adequately and accurately to
specific user domains
SOE: refactoring and patterns
42
patterns and refactoring work together:
bottom up design
refactoring
to
pattern
development
SOE: refactoring and patterns
patterns
through
refactoring
43
design style,
abstraction level
architecture
architectural
patterns
design as model
agile
GRASP
refactoring
design as code
design
patterns
detailed design
SOE: refactoring and patterns
44
traditional and agile design styles compared
design assumptions
traditional
agile
style
top down
bottom up
starts with
modelling
programming
process
grand design up front
evolutionary design
responsible
architect, designers
programmers
based upon
user domain analysis
models
generic design patterns
outcome
design document
program
weakness
separation of design and
programming
absence of early
overview, unspecific
user domain
understandings
SOE: refactoring and patterns
45