Brian Du Preez, our JCG partner from Zen in the art of IT has made a very fine job of collecting the most common design patterns found in the JDK. The pattern list is indeed impressive and long, so let us babble no more and present it to you.
I saw an article (well more of a rant) the other day, by Rob Williams Brain Drain in enterprise Dev. I have to say, I do agree with some of what he is saying. I know from my personal experience, I had spent a good 2 or so years just wallowing in the enterprise development world, not learning anything and actually losing my skills I developed before. The corporate confront zone is not conducive to eager technologists.
In this article he also stated:
"1 in 10 cant even pass a simple test like ‘which design pattern is used in the streams library that makes BufferedReader interchangeable with a FileReader?'"
I also tested it at work and I only had 1 out of the 8 people asked that got it right
Without much confidence, I had guessed Decorator based on "interchangeable". I then decided that was actually some worth sneaking into future interviews, and probably a good time to revise a little.
So I went scouring the internet to find all I could on the topic and I didn't actually find as much as I thought I would. Most of it came from BalusC at Stackoverflow, the rest was very scattered between blog posts, java ranch, some old pdf's and articles I had. I didn't take every single example of every single pattern I found, but rather the common ones.
This may be a good way for people to learn about patterns, quite often they are using them everyday without realizing.
Structural
Adapter:
This is used to convert the programming interface/class into that of another.
Bridge:
This decouples an abstraction from the implementation of its abstract operations, so that the abstraction and its implementation can vary independently.
Composite:
Lets clients treat individual objects and compositions of objects uniformly. So in other words methods on a type accepting the same type.
Decorator:
Attach additional responsibilities to an object dynamically and therefore it is also an alternative to subclassing. Can be seen when creating a type passes in the same type. This is actually used all over the JDK, the more you look the more you find, so the list below is definitely not complete.
Facade:
To provide a simplified interface to a group of components, interfaces, abstractions or subsystems.
Flyweight:
Caching to support large numbers of smaller objects efficiently. I stumbled apon this a couple months back.
Proxy:
The Proxy pattern is used to represent with a simpler object an object that is complex or time consuming to create.
Creational
Abstract factory:
To provide a contract for creating families of related or dependent objects without having to specify their concrete classes. It enables one to decouple an application from the concrete implementation of an entire framework one is using. This is also found all over the JDK and a lot of frameworks like Spring. They are simple to spot, any method that is used to create an object but still returns a interface or abstract class.
Builder:
Used simplify complex object creation by defining a class whose purpose is to build instances of another class. The builder pattern also allows for the implementation of a Fluent Interface.
Factory method:
Simply a method that returns an actual type.
Prototype:
Allows for classes whose instances can create duplicates of themselves. This can be used when creating an instance of a class is very time-consuming or complex in some way, rather than creating new instances, you can make copies of the original instance and modify it.
Singleton:
This tries to ensure that there is only a single instance of a class. I didn't find an example but another solution would be to use an Enum as Joshua Bloch suggests in Effective Java.
Behavioral
Chain of responsibility:
Allows for the decoupling between objects by passing a request from one object to the next in a chain until the request is recognized. The objects in the chain are different implementations of the same interface or abstract class.
Command:
To wrap a command in an object so that it can be stored, passed into methods, and returned like any other object.
Interpreter:
This pattern generally describes defining a grammar for that language and using that grammar to interpret statements in that format.
Iterator:
To provide a consistent way to sequentially access items in a collection that is independent of and separate from the underlying collection.
Mediator:
Used to reduce the number of direct dependencies between classes by introducing a single object that manages message distribution.
Memento:
This is a snapshot of an object’s state, so that the object can return to its original state without having to reveal it's content. Date does this by actually having a long value internally.
Null Object:
This can be used encapsulate the absence of an object by providing an alternative 'do nothing' behavior. It allows you to abstract the handling of null objects.
Observer:
Used to provide a way for a component to flexibly broadcast messages to interested receivers.
State:
This allows you easily change an object’s behavior at runtime based on internal state.
Strategy:
Is intended to provide a means to define a family of algorithms, encapsulate each one as an object. These can then be flexibly passed in to change the functionality.
Template method:
Allows subclasses to override parts of the method without rewriting it, also allows you to control which operations subclasses are required to override.
Visitor:
To provide a maintainable, easy way to perform actions for a family of classes. Visitor centralizes the behaviors and allows them to be modified or extended without changing the classes they operate on.
Better is the enemy of good!
Byron
Related Articles:
I saw an article (well more of a rant) the other day, by Rob Williams Brain Drain in enterprise Dev. I have to say, I do agree with some of what he is saying. I know from my personal experience, I had spent a good 2 or so years just wallowing in the enterprise development world, not learning anything and actually losing my skills I developed before. The corporate confront zone is not conducive to eager technologists.
In this article he also stated:
"1 in 10 cant even pass a simple test like ‘which design pattern is used in the streams library that makes BufferedReader interchangeable with a FileReader?'"
I also tested it at work and I only had 1 out of the 8 people asked that got it right
Without much confidence, I had guessed Decorator based on "interchangeable". I then decided that was actually some worth sneaking into future interviews, and probably a good time to revise a little.
So I went scouring the internet to find all I could on the topic and I didn't actually find as much as I thought I would. Most of it came from BalusC at Stackoverflow, the rest was very scattered between blog posts, java ranch, some old pdf's and articles I had. I didn't take every single example of every single pattern I found, but rather the common ones.
This may be a good way for people to learn about patterns, quite often they are using them everyday without realizing.
Structural
Adapter:
This is used to convert the programming interface/class into that of another.
- java.util.Arrays#asList()
- javax.swing.JTable(TableModel)
- java.io.InputStreamReader(InputStream)
- java.io.OutputStreamWriter(OutputStream)
- javax.xml.bind.annotation.adapters.XmlAdapter#marshal()
- javax.xml.bind.annotation.adapters.XmlAdapter#unmarshal()
Bridge:
This decouples an abstraction from the implementation of its abstract operations, so that the abstraction and its implementation can vary independently.
- AWT (It provides an abstraction layer which maps onto the native OS the windowing support.)
- JDBC
Composite:
Lets clients treat individual objects and compositions of objects uniformly. So in other words methods on a type accepting the same type.
- javax.swing.JComponent#add(Component)
- java.awt.Container#add(Component)
- java.util.Map#putAll(Map)
- java.util.List#addAll(Collection)
- java.util.Set#addAll(Collection)
Decorator:
Attach additional responsibilities to an object dynamically and therefore it is also an alternative to subclassing. Can be seen when creating a type passes in the same type. This is actually used all over the JDK, the more you look the more you find, so the list below is definitely not complete.
- java.io.BufferedInputStream(InputStream)
- java.io.DataInputStream(InputStream)
- java.io.BufferedOutputStream(OutputStream)
- java.util.zip.ZipOutputStream(OutputStream)
- java.util.Collections#checked[List|Map|Set|SortedSet|SortedMap]()
Facade:
To provide a simplified interface to a group of components, interfaces, abstractions or subsystems.
- java.lang.Class
- javax.faces.webapp.FacesServlet
Flyweight:
Caching to support large numbers of smaller objects efficiently. I stumbled apon this a couple months back.
- java.lang.Integer#valueOf(int)
- java.lang.Boolean#valueOf(boolean)
- java.lang.Byte#valueOf(byte)
- java.lang.Character#valueOf(char)
Proxy:
The Proxy pattern is used to represent with a simpler object an object that is complex or time consuming to create.
- java.lang.reflect.Proxy
- RMI
Creational
Abstract factory:
To provide a contract for creating families of related or dependent objects without having to specify their concrete classes. It enables one to decouple an application from the concrete implementation of an entire framework one is using. This is also found all over the JDK and a lot of frameworks like Spring. They are simple to spot, any method that is used to create an object but still returns a interface or abstract class.
- java.util.Calendar#getInstance()
- java.util.Arrays#asList()
- java.util.ResourceBundle#getBundle()
- java.sql.DriverManager#getConnection()
- java.sql.Connection#createStatement()
- java.sql.Statement#executeQuery()
- java.text.NumberFormat#getInstance()
- javax.xml.transform.TransformerFactory#newInstance()
Builder:
Used simplify complex object creation by defining a class whose purpose is to build instances of another class. The builder pattern also allows for the implementation of a Fluent Interface.
- java.lang.StringBuilder#append()
- java.lang.StringBuffer#append()
- java.sql.PreparedStatement
- javax.swing.GroupLayout.Group#addComponent()
Factory method:
Simply a method that returns an actual type.
- java.lang.Proxy#newProxyInstance()
- java.lang.Object#toString()
- java.lang.Class#newInstance()
- java.lang.reflect.Array#newInstance()
- java.lang.reflect.Constructor#newInstance()
- java.lang.Boolean#valueOf(String)
- java.lang.Class#forName()
Prototype:
Allows for classes whose instances can create duplicates of themselves. This can be used when creating an instance of a class is very time-consuming or complex in some way, rather than creating new instances, you can make copies of the original instance and modify it.
- java.lang.Object#clone()
- java.lang.Cloneable
Singleton:
This tries to ensure that there is only a single instance of a class. I didn't find an example but another solution would be to use an Enum as Joshua Bloch suggests in Effective Java.
- java.lang.Runtime#getRuntime()
- java.awt.Toolkit#getDefaultToolkit()
- java.awt.GraphicsEnvironment#getLocalGraphicsEnvironment()
- java.awt.Desktop#getDesktop()
Behavioral
Chain of responsibility:
Allows for the decoupling between objects by passing a request from one object to the next in a chain until the request is recognized. The objects in the chain are different implementations of the same interface or abstract class.
- java.util.logging.Logger#log()
- javax.servlet.Filter#doFilter()
Command:
To wrap a command in an object so that it can be stored, passed into methods, and returned like any other object.
- java.lang.Runnable
- javax.swing.Action
Interpreter:
This pattern generally describes defining a grammar for that language and using that grammar to interpret statements in that format.
- java.util.Pattern
- java.text.Normalizer
- java.text.Format
Iterator:
To provide a consistent way to sequentially access items in a collection that is independent of and separate from the underlying collection.
- java.util.Iterator
- java.util.Enumeration
Mediator:
Used to reduce the number of direct dependencies between classes by introducing a single object that manages message distribution.
- java.util.Timer
- java.util.concurrent.Executor#execute()
- java.util.concurrent.ExecutorService#submit()
- java.lang.reflect.Method#invoke()
Memento:
This is a snapshot of an object’s state, so that the object can return to its original state without having to reveal it's content. Date does this by actually having a long value internally.
- java.util.Date
- java.io.Serializable
Null Object:
This can be used encapsulate the absence of an object by providing an alternative 'do nothing' behavior. It allows you to abstract the handling of null objects.
- java.util.Collections#emptyList()
- java.util.Collections#emptyMap()
- java.util.Collections#emptySet()
Observer:
Used to provide a way for a component to flexibly broadcast messages to interested receivers.
- java.util.EventListener
- javax.servlet.http.HttpSessionBindingListener
- javax.servlet.http.HttpSessionAttributeListener
- javax.faces.event.PhaseListener
State:
This allows you easily change an object’s behavior at runtime based on internal state.
- java.util.Iterator
- javax.faces.lifecycle.LifeCycle#execute()
Strategy:
Is intended to provide a means to define a family of algorithms, encapsulate each one as an object. These can then be flexibly passed in to change the functionality.
- java.util.Comparator#compare()
- javax.servlet.http.HttpServlet
- javax.servlet.Filter#doFilter()
Template method:
Allows subclasses to override parts of the method without rewriting it, also allows you to control which operations subclasses are required to override.
- java.util.Collections#sort()
- java.io.InputStream#skip()
- java.io.InputStream#read()
- java.util.AbstractList#indexOf()
Visitor:
To provide a maintainable, easy way to perform actions for a family of classes. Visitor centralizes the behaviors and allows them to be modified or extended without changing the classes they operate on.
- javax.lang.model.element.Element and javax.lang.model.element.ElementVisitor
- javax.lang.model.type.TypeMirror and javax.lang.model.type.TypeVisitor
Better is the enemy of good!
Byron
Related Articles:
Some classes are not part of JDK such as:
ReplyDelete# javax.servlet.http.HttpServlet
# javax.servlet.Filter#doFilter()
# javax.servlet.http.HttpSessionBindingListener
# javax.servlet.http.HttpSessionAttributeListener
# javax.faces.event.PhaseListener
Hello Haitham,
ReplyDeleteYou are right, of course! The original author uses the JDK term in its broader sense (e.g. Java ecosystem). Additionally the class lists should be treated as example lists only. There are in no way complete.
BRs
i am probably 7/8 people that can't answer that question "which design pattern is used in the streams library that makes BufferedFileReader interchangeable with a FileReader?". so, what's the answer to this question. thanks
ReplyDeleteHello all, thank you for your comments!
ReplyDelete@yaliu07, The Decorator pattern is used since we attach additional responsibilities to the FileReader object dynamically - in this case we apply buffering to the character-input stream.
The confusion over the inital question may be because it is badly asked. The 'pattern' that makes a BufferedReader interchangeable with a StreamReader is the Liskov Substitution Principle. Decorator is what allows us to compose Readers rather than having to have classes like BufferedZipFileReader.
ReplyDeleteSo, who had the ludicrous idea to list java.util.Collections#sort() as an example of a template method?
ReplyDeleteI doubt that this list is the final say. I did not read the full page, but why the hell should e.g. a Map or a List be a Composite? putAll or addAll are just convenience-methods to copy the elements contained in the argument to the actual list or map and the Javadocs say so as well.
ReplyDeleteYou forgot to mention the java.util.Observable und java.util.Observer as an example for the Observer design-pattern.
ReplyDeleteI agree that the questiom is badly phrased. Decorator is not about "interchangeability", but "Attach additional responsibilities to an object dynamically. Decorators provide a flexible alternative to subclassing for extending functionality." (quote from the pattern book).
ReplyDeleteOf course, Decorator must "comply" with the Liskov Substitution Principle or they will not be of any use.
"StringWriter" implements Writer interface and adapts it to StringBuilder, so adapter design pattern.
ReplyDeleteOn a second thought.... The answer to the original question as it is phrased could be "Strategy".
ReplyDeleteWow! A Map is an example of a Composite pattern?
ReplyDeleteThis shows that the author doesn't understand what patterns are. Amazing!
This article is crap.
Ravi
And Object.toString() is a Factory method?
ReplyDeleteI'm dumbfounded by the author's interpretation.
By his definition, if I write a method that returns any object (MyClass, for example) it becomes a Factory pattern. How silly!
Ravi
Dear Byron,
ReplyDeleteI read you definition for "Flyweight" and I try to understand how it developed in JDK comparing with other defintions like "the intent of this pattern is to use sharing to support a large number of objects that have part of their internal state in common where the other part of state can vary."
And I take a look for the examples in this link:
http://www.oodesign.com/flyweight-pattern-wargame-example-java-sourcecode.html
And I didn't find any match between the code.
please, Can you explain it to me?
Regards
Ahmad Alhaj Hussein
@yaliu07 BufferedFileReader is interchangeable with a FileReader because they implement the same interface. That's just OO. ;-)
ReplyDeleteThe decorator adds behavior to an existing class...
Just nitpicking.