Slideshare uses cookies to improve functionality and performance, and to provide you with relevant advertising. If you continue browsing the site, you agree to the use of cookies on this website. See our User Agreement and Privacy Policy.

Slideshare uses cookies to improve functionality and performance, and to provide you with relevant advertising. If you continue browsing the site, you agree to the use of cookies on this website. See our Privacy Policy and User Agreement for details.

Paulking dlp

2.
Introduction …
• Developer practices
– Well understood and documented for
traditional and agile approaches such
as Java, C++ and C# development
– But dynamic languages like Groovy,
Ruby, Python, Boo, JavaScript and
(c) ASERT 2006-2009
others change the ground rules
– Many of the rules and patterns we
have been taught no longer apply

4.
Examples to ponder
• What does Immutability mean?
– When even constants can be changed
• What does encapsulation
mean?
– When I can peek at anything
(c) ASERT 2006-2009
under the covers
• How can I devise tests
at development time?
– When my system can change in
unknown ways at runtime
• How can IDEs help me?
– If I no longer spoon feed it static-typing information
or if my language now only allows checks at runtime

6.
Static vs Dynamic Typing …
• The Debate
– Static vs dynamic typing
• Static: the type of each variable
(or expression) must be known
at compile time
like wearing a straight-jacket?
• Dynamic: type information is
(c) ASERT 2006-2009
known only at runtime
like tightrope walking with no net?
– Strong vs weak typing
• Strong: List<Integer> myList
• Weak: Object myList
– Type safety
• How is this provided if at all?
– Type inference
• Is this supported?

7.
…Static vs Dynamic Typing …
• Static Typing Pros
– Errors are often detected earlier and with better error
messages
– Code can sometimes be clearer – you don‟t need to infer
the types to understand the code – especially when
revisiting the code later
(c) ASERT 2006-2009
– Safer because certain kinds of injection hacks don‟t apply
– Code can be more declarative
– Better IDE support: refactoring, editing and other forms
of source processing support is often possible
– Better optimisations are often possible
– Often easier to understand a system from the outside
(“self-documenting” statically-typed APIs and interfaces)
– With generics support you can start to nail down even
complex cases

8.
… Static vs Dynamic Typing …
• Dynamic Typing Pros
– Speed development through duck-typing
and less boiler-plate code
– Clearer more concise code is easier to
read and maintain
– Allow more expressiveness through DSLs
(c) ASERT 2006-2009
– You should have comprehensive tests anyway, why not
cover off types as part of those tests
– Enforced healthy practices:
• Static language developers may get a false sense of
security and not design/test for runtime issues
• Less likely to neglect good documentation and/or good
coding conventions on the grounds that your static
types make everything “inherently” clear

9.
… Static vs Dynamic Typing …
• MYTH or TRUTH?
Static typing is just spoon feeding the
compiler. It represents the old-school way
of thinking and requires extra work while
providing no real value.
(c) ASERT 2006-2009

22.
… Language features instead of Patterns …
SquarePeg.metaClass.getRadius =
{ Math.sqrt(((delegate.width/2)**2)*2) }
(4..7).each { w -> pretty(hole, new SquarePeg(width:w)) }
Adapter Pattern
(c) ASERT 2006-2009
Do I create a whole
new class or just add
the method I need
on the fly?
SquarePeg with width 4 fits in RoundHole with radius 4.0
SquarePeg with width 5 fits in RoundHole with radius 4.0
SquarePeg with width 6 does not fit in RoundHole with radius 4.0
SquarePeg with width 7 does not fit in RoundHole with radius 4.0
Further reading: James Lyndsay, Agile is Groovy, Testing is Square

23.
Adapter Pattern Verdict
• Dynamic languages can make it easier to
apply the adapter pattern to the extent that
its use may not even be apparent:
– Express intent more clearly and improves readability
– Aids refactoring
–
(c) ASERT 2006-2009
Can help with test creation
– Avoids class proliferation
– But you still need testing

25.
Visitor Pattern Verdict
• Dynamic languages can make it easier to
apply the visitor pattern to the extent that
its use may not even be apparent:
– Express intent more clearly and improves readability
– Aids refactoring
–
(c) ASERT 2006-2009
Avoids class proliferation
– But you still need testing

28.
Strategy Pattern Verdict
• Dynamic languages can make it easier to
apply the strategy pattern to the extent
that its use may not even be apparent:
– Express intent more clearly and improves readability
– Closures open up whole new possibilities for solving
problems
(c) ASERT 2006-2009
– Aids refactoring
– Can help with test creation
– Avoids class proliferation
– But you still need testing

38.
… Delegation Pattern …
• Downside of delegation is maintenance issues
– Refactoring overhead if we change the base class
– Meta-programming allows us to achieve inheritance
like behavior by intercepting missing method calls
(invokeMethod or method_missing)
– You could take this further with Groovy using named
(c) ASERT 2006-2009
parameters rather than the traditional positional
parameters shown here (future versions of Ruby may
have this too)

50.
Pattern Summary
• Patterns can be replaced by language
features and libraries
(c) ASERT 2006-2009
• So patterns aren‟t important any more!
...

51.
Refactoring Refactoring
• Out with the Old
– Some refactorings no longer make sense
• In with the New
– There are some new refactorings
• Times … they are a changin‟
(c) ASERT 2006-2009
– Some refactorings are done differently

52.
Encapsulate Downcast Refactoring
• Description
– Context: A method returns an object that
needs to be downcasted by its callers
– Solution: Move the downcast to within the method
• Is there a point in a dynamic language?
– Maybe but not usually
(c) ASERT 2006-2009
// Before refactoring
Object lastReading() {
return readings.lastElement()
}
// After refactoring
Reading lastReading() {
return (Reading) readings.lastElement()
}

78.
...Open-Closed Principle...
• Following the Rules
– Encapsulation: Make anything that shouldn‟t be seen
private
– Polymorphism: Force things to be handled using
abstract classes or interfaces
• When making class hierarchies:
(c) ASERT 2006-2009
– Make anything that shouldn‟t be open final
– Polymorphism: Always follow weaker pre stronger
post (object substitutability in the static world)
• When making changes that might break
existing clients
– Add a new class into the hierarchy
– No compilation of existing code! No breakages!

79.
...Open-Closed Principle...
• Part I: If I violate the Open part of OCP in
static languages
– I can‟t make the future enhancements I need
• Part II: If I violate the Closed part of OCP
– Client applications using my libraries might
(c) ASERT 2006-2009
break or require recompilation in the future
Class A Extendible Class A
Interface User Class A User
Class A‟ Class A‟
User Class A‟
User
Optional Optional
Class A Class A‟
Factory Factory
...

82.
...Open-Closed Principle...
def shapes = [
new Square(side: 3),
new Square(side: 2),
new Circle(radius: 1.5)
]
def calc = new AreaCalculator()
shapes.sort().each {s ->
println "Area of $s.class.name is ${calc.area(s)}"
(c) ASERT 2006-2009
}
• What‟s wrong
– If we wanted to introduce a Triangle, the
AreaCalculator would need to be recompiled
– If we wanted to change the order the shape
information was displayed, there might be many
changes to make

84.
...Open-Closed Principle...
• Dynamic sorting using Closures
– As long as we are happy having our sort “code”
within a closure we have complete freedom
– Sometimes representing our abstractions within
classes is appropriate; many times closures will do
Area of Square is 4.0
(c) ASERT 2006-2009
Area of Circle is 7.0685834705770345
// sorted by area Area of Square is 9.0
def byArea = { s -> s.area() }
shapes.sort(byArea).each(prettyPrint) Note: Make sure your
closures are testable.
// sorted circles before squares but otherwise by area
def byClassNameThenArea = { sa, sb ->
sa.class.name == sb.class.name ? Area of Circle is 7.06858...
sa.area() <=> sb.area() : Area of Square is 4.0
Area of Square is 9.0
sa.class.name <=> sb.class.name
}
shapes.sort(byClassNameThenArea).each(prettyPrint)
...

86.
...Open-Closed Principle...
• “Clean code” [23] states it this way:
– Procedural code (i.e. using data structures) makes it
easy to add new functions without changing existing
data structures but when new data structures are
added, all existing procedures may need to change
– OO code makes it easy to add new classes without
(c) ASERT 2006-2009
changing existing functions but when new functions
are added, all classes must change
• Recommendation?
– Choose procedural or OO approach based on
whether anticipated evolution of system involves
functions or data
– Use Visitor (dual dispatch) Pattern if you think both
functions and data might change

90.
...Open-Closed Principle...
• “Clean code” [23] recommendation:
– Choose procedural or OO approach or Visitor
• Agile variation:
– Defer moving to complicated solutions, e.g. Visitor
Pattern, but have in place sufficient tests so that you
can confidently refactor to use one later if needed
(c) ASERT 2006-2009
• Dynamic language variation:
– You won‟t need an explicit visitor (more on this later)
– Duck typing lets you add functions or data without
changing existing classes at the expense of static
type safety
– If you add a function you might need additional tests
for each class associated with that function
– If you add a new class you might need additional
tests for each function associated with that class

95.
Dependency Injection vs Metaprogramming …
• Dependency Injection
– Dependencies are explicitly declared and allowed to
be set externally (typically via constructor or setters)
• Transparent injection of dependent service objects into other
service objects by a controlling container hence the name
inversion of control
• Why?
(c) ASERT 2006-2009
– More flexible
• Central configuration of service objects
– Can be less work to do
• Service objects are instantiated by the dependency injection
framework
– Improves testability
– Improves reusability
– Improved lifecycle control