Some Design Patterns in some JVM languages
Raúl Vázquez
@rvazquezglez
Agenda
- Introduction to Design Patterns
- Patterns
- Decorator
- Strategy
- Command
- Visitor
- Observer
- Builder
- For each of them
- Context and application
- Implementation in Java
- Alternative in other language
Patterns introduction
What is a Design Pattern?
A design pattern systematically names, motivates, and explains a general design that addresses a recurring design problem in object-oriented systems. It describes the problem, the solution, when to apply the solution, and its consequences. It also gives implementation hints and examples. The solution is a general arrangement of objects and classes that solve the problem. The solution is customized and implemented to solve the problem in a particular context.
What is a Design Pattern?
Templates that describe a design alternatives
Design patterns can be seen as a "play" or plan of action.
How it's implemented depends on the current game.
"Peter Norvig found that 16 of the 23 patterns in Design Patterns were 'invisible or simpler' in Lisp."
- Paul Graham, revenge of the nerds
http://www.paulgraham.com/icad.html
Decorator
Adds behavior to an individual object rather than to an entire class of objects—this allows us to change the behavior of an existing class.
Intent
To attach additional responsibilities to an object dynamically. Decorators provide a flexible alternative to subclassing for extending functionality.
Decorator class diagram
Alternatives
- The decorator pattern can be replaced with an AOP framework.
- At language level it can be replaced with function composition
- Groovy: https://goo.gl/cFPWQ7
Examples
- Java: https://goo.gl/fMmKhG
Strategy
Defines a family of algorithms, encapsulates each one, and makes them interchangeable. Strategy lets the algorithm vary independently from clients that use it.
Intent
Define an algorithm in abstract terms so it can be implemented in several different ways, and to allow it to be injected into clients so it can be used across several different clients.
Strategy class diagram
Alternative
- As with command, strategy interface and its concrete implementations can be replaced with a simple function
- Scala: https://goo.gl/6eQ4Dp
Examples
- Java: https://goo.gl/v24Tlt
Command
Command encapsulates an action along with the information needed to perform it.
Intent
To encapsulate a request as an object, thereby letting you parameterize clients with different requests, queue or log requests, and support undoable operations.
Command class diagram
The Client is responsible for creating a ConcreteCommand and setting its Receiver
The Invoker holds a command and at some point asks the command to carry out a request by calling its execute() method
Command declares an interface for all commands. A command is invoked through its execute() method, which asks a receiver to perform an action
void execute() {
receiver.action();
}
The Receiver knows how to perform the work needed to carry out the request. Any class can act as a Receiver
The ConcreteCommand defines a binding between an action and a Receiver. The Invoker makes a request by calling execute() and the ConcreteCommand carries it out by calling one or more actions on the Receiver
The execute method invokes the action(s) on the receiver needed to fulfill the request
Alternative
- The command interface and its concrete implementations can be replaced with a simple function
- Scala: https://goo.gl/2f3e8c
Examples
- Java: https://goo.gl/H5upK5
https://twitter.com/ID_AA_Carmack/status/53512300451201024
Visitor
When you want to add capabilities to a composite of objects and encapsulation is not important.
Intent
To encapsulate an action to be performed on a data structure in a way that allows the addition of new operations to the data structure without having to modify it.
Alternative
- The visitor pattern can be replaced with pattern matching
- Scala: https://goo.gl/ofjOnU
Examples
- Java: https://goo.gl/4HBBK8
Observer
Publishers + Subscribers = Observer Pattern
Intent
Define a one-to-many dependency between objects so that when one object changes state, all its dependents are notified and updated automatically.
Encapsulate the core (or common or engine) components in a Subject abstraction, and the variable (or optional or user interface) components in an Observer hierarchy.
The "View" part of Model-View-Controller.
Alternative
- The Observer Pattern can be replaced with an Event Bus
- Groovy + VertX: https://goo.gl/4RCE8F
Examples
- Java: https://goo.gl/44Hd1k
Builder
Encapsulates the construction of a product and allow it to be constructed in steps
Intent
Separate the construction of a complex object from its representation so that the same construction process can create different representations.
Solution to Telescoping Constructor anti-pattern
Create an immutable object using a friendly syntax
Telescopic constructor anti pattern
Refactor in conjunction with parameter object
Alternatives
- Any language that supports constructor with named parameters also addresses the telescoping constructor anti-pattern
- Scala: https://goo.gl/XzytYK
- Instead of using inmutable objects you can use a Clojure map, inmutable by default
- Clojure: https://goo.gl/sGj0dP
Examples
- Java: https://goo.gl/iEayu0
Sources
-
Design Patterns: Elements of Reusable Object-Oriented Software
by John Vlissides, Ralph Johnson, Richard Helm, Erich Gamma
https://www.safaribooksonline.com/library/view/design-patterns-elements/0201633612/
-
Functional Programming Patterns in Scala and Clojure
by Michael Bevilacqua-Linn
https://www.safaribooksonline.com/library/view/functional-programming-patterns/9781941222416/
-
Are patterns missing language features?
http://c2.com/cgi/wiki?AreDesignPatternsMissingLanguageFeatures
-
Deprecating the observer pattern
by Ingo Maier & Martin Odersky
http://infoscience.epfl.ch/record/176887/files/DeprecatingObservers2012.pdf - https://twitter.com/wdonet/status/678809939268141056
Some Design Patterns in some JVM languages
By Raúl Vázquez
Some Design Patterns in some JVM languages
- 629