I started learning design patterns a good number of years ago. I learned a few. Probably around half. But others I just kept forgetting. Or I should say, never learned.
C’mon, you did not learn design patterns!
Knowing design patterns is important. Very important. It’s probably the best “tool” in your toolbox as the developer. Not only the Gang of Four (GoF) patterns, which are the most known, but others as well.
But learning design patterns is hard.
It’s not that the design patterns are hard, it’s the process of learning and retaining that’s hard. Why? If you don’t use it… you’ll forget it.
So a month or two ago, I decided to revisit the subject. I decided to learn the Gang of Four (GoF) patterns. Learn it in a way so I can remember. As I said, not an easy thing to do. (I guess I will really know if I learned it after a few months. )
There is probably only one way to really “learn” it. Use it in code. That’s when you see the context, problem, solution, etc. That’s when you really know all the details about the pattern. And most likely it will “stick” with you and you will not forget it.
If you really want to learn a pattern, use it!
If you can…
I have a few that I have used: Observer, Factory, Builder, Singleton, Facade, Strategy, Template Method, Iterator, Command… I think that’s about it.
OK, that’s less than half of the 23 GoF patterns. What happened to the others?
Blame it on my memory.
On the other hand, I don’t want to just use it because it would be cool. It has to be the right fit. And that does not happen often… But when you do see the opportunity, you should be ready!
BE PREPARED
How do you prepare? Here are some ways.
Read the GoF book several times. OK, that might work for you. For others, it probably will not.
Read multiple books. Yes, that’s probably better, but it still could not work for some of the patterns.
Read multiple books and other references at the same time. Yes, I think this is better. Much better. Why? In How To Read A Book the author explains that this is the highest level of reading, Syntopical Reading. By reading multiple authors on the same subject you have trouble understanding, in this case, it might be a particular pattern, you gain the highest level of understanding.
So that’s what I did: I started reading mutliple resources on GoF Patterns at the same time.
Of course, it would be ideal to have ALL the books available on the subject. I don’t. But I have several and that’s a big help. I also have a subscription to Safari (as part of being ACM.org member), and they have a few books there as well. And of course there is the Internet, loaded with many great references.
I started with the classic GoF book. As I read a pattern, let’s say Abstract Factory, I picked up another book or looked at another website. I read a few until I really “got it.” I also looked at code samples. I read some more. Eventually, I got the “aha” moment.
I’d like to share the resources I have used and that I find valuable on the subject of the Design Patterns. Just so your learning will be, let’s say, a bit simpler.
It’s already taken me a long time to get to this point. So without further ado, here they are.
BOOKS
Design Patterns by Gamma,Helm,Johnson,Vlissides
There is a reason it’s the classic book. Start your learning from this book. The explanations, reasoning and usages are the best in this book. But it’s not an easy book to read. In fact, I think it’s hard if you’re not a C++ programmer. Still, it’s a great book.
Refactoring to Patterns by Kerievsky
I appreciate this book more now than when I first bought it. Filled with very good advice. However, it only covers a few of the GoF patterns.
Agile Software Development by Martin
My favorite book. Not on Design Patterns in specific, as it also does not cover all GoF patterns, but still worth checking out the few that it does cover.
Head First Design PatternsAvailable on Safari, this book is loved by many, not so by others (including me). But still a great book on the subject.
WEBSITES
Wikipedia: Design Patterns
More than anything, it contains great examples.
dofactory
(claims to be #1 in design patterns). Valuable resource.
Houston Design Patterns
Great resource on design patterns.
Examples of GoF Patterns
Lists places in the JDK where the patterns are implemented.
INDIVIDUAL PATTERNS
Bridge vs Strategy
If you get stuck like I did, check out this url.
Factory Method
Good examples on how to implement the pattern.
Uncle Bob listed a few Design smells — the odors of rotting software in his book Agile Software Development. Take the inverse of that and what do you get? Criteria for good design — that’s the approach that the author of the book PHP in Action took.
Here are the characteristics of good design.
Very good criteria, in my opinion.
Constructing a good architecture is a tough task. In my developer’s career, I have not come across too many architects that really do a decent job creating good – cohesive – architectures. That just reiterates my point that architecting a system is not an easy task.
What is a good architecture, though? What are its characteristics? I found some definite answers to this question in a book I’m reading now, Object Oriented Analysis and Design with Applications, 3rd edition. These are some of the best definitions and views on software architecture I have come across.
“A system that has a sound architecture is one that has conceptual integrity. Having a “clean internal structure” is essential to constructing a system that is understandable, can be extended and reorganized, and is maintainable and testable.”
“There is no right way to craft the architecture of a given system.”
Architectures constructed in this way tend to be less complex and more robust and resilient. They also enable more effective reuse.
What is it? I don’t know. I think it’s communication skills, the ability to see the big picture, staying abreast of new technologies, and learning quickly. Plus, the ability to dive into new technologies and leave your comfort zone — leave the old technologies behind.
But who am I to answer a question like this. I’m not an architect. Yet. It’s something I’m preparing myself for.
Anyway, this question, “what is the most valuable IT architecture skill?,” was answered by some distinguished IBM architects, Grady Booch being one of them. It’s a very good article.
ReferenceWhat is the most valuable IT architecture skill and how can you learn it?,developerWorks
I’ve been inthe dark as far as the Decorator pattern is concerned. I knew, inprinciple, how it works, but I can see that my understanding was veryincomplete. Plus, I never had a chance to useit. While reading the Head First Design Patternsbook, Idiscovered something basic that: when you wrap an object several timesand then call a method on it, it will be called as many times as it waswrapped. The trick? Keepa reference to the object — you’re creating a chain.
<font
Let me gothrough this step by step. By example. This is thebook’s example, the Starbuzz Coffee decorator.
<font
A simpleinterface.
<fontpublic interfaceBeverage {
<fontpublic String getDescription();
<fontpublic BigDecimal getCost();
<font}
We have severalcoffee types, Dark Roast being one of them.
<fontpublic classDarkRoast implementsBeverage {
<font public BigDecimal getCost() {
<font return newBigDecimal(“1.55″);
<font }
<font public String getDescription() {
<font return“Dark Roast”;
<font }
<font}
When orderingcoffee, you can pick a coffee type (Dark Roast, Latte, etc), and youcan also add on to the coffee. For instance, you can add a whip creamon top, or add a shot of expresso to it. Which, of course, adds to theprice. You could extend Beverage with all of the types, but that’s toomany classes. Here’swhere the decorator pattern comes into play.
Here’sthe solution. You define the AddOnDecorator and extend it with thedifferent add ons.
<font/** It’sjust an empty class */
<fontpublic abstractclassAddOnDecorator implementsBeverage { }
<font
<fontpublic classExpresso extendsAddOnDecorator {
<fontBeveragebeverage;
<fontpublic Expresso(Beverage beverage) {
<font this.beverage =beverage;
<font}
<fontpublic BigDecimal getCost() {
<font return newBigDecimal(“0.25″).add(beverage.getCost());
<font}
<fontpublic String getDescription() {
<font return beverage.getDescription()+ “, with Expresso”;
<font }
}
<font
<fontpublic classWhip extendsAddOnDecorator {
<fontBeveragebeverage;
<fontpublic Whip(Beverage beverage) {
<fontthis.beverage =beverage;
<font }
<fontpublic BigDecimal getCost() {
<fontreturn newBigDecimal(“0.10″).add(beverage.getCost());
<font }
<fontpublic String getDescription() {
<fontreturn beverage.getDescription()+ “, Whipped”;
<font}
<font}
<font
<fontpublic classStarbuzzCoffee {
<fontpublic staticvoidmain(String[] args) {
<fontBeveragedarkRoast = newDarkRoast();
<fontdarkRoast= newExpresso(darkRoast);
<fontdarkRoast= newWhip(darkRoast);
<fontSystem.out.println(darkRoast.getDescription()+ ” costs “
<font+darkRoast.getCost());
<font}
<font}
WhenI first looked at the code, I was confused. I thought that newWhip(…) would just override it,right?
Thisis what gets printed: Dark Roast, with Expresso, Whippedcosts 1.90
You get the beverage you want(DarkRoast), you pass it to the Expresso wrapper, which in turn passesit to the Whip wrapper.
Firstthe Expressowrapper is called, itreceives the dark roast beverage. Then the dark roast is passed againto the Whip wrapper. If you look closely (and this isa little confusing), when an Expresso is instantiated, it receives the beverage andmakes a local copy (so it is never lost). Essentially, a chain is made.When the action on the final object is made, the chain is traversed andthe beverage object is passed around. That’s how this patternworks. (Wow, I learn something (basic) every day. )
The Decoratorpattern is cool. It rocks. It lets you keep adding functionality and still keep the objectscohesive (as you’re not bloating the objects). No coupling as well.Nice.
Reference
Head First Design Patterns, the example above was taken from the book
When building web applications, everybody seems to be using the Model View Controller (MVC) pattern. We all use it. It’s a fundamental pattern. However, a lot of people use it incorrectly. Actually, in my six years of programming, I have never seen it done the proper way. From what I’ve seen, the majority of the MVC implementations have a major flow: too much “model” in the controller. That’s a critical error and a no-no in proper usage of the pattern.
So how should it work? The critical thing is not to have any business logic in the controller, and have a separate business layer that is not aware of the view technology.
Here are fundamental characteristics of MVC:
Model: encapsulates all of the business logic. It is not aware of the view technology.
Controller: fetches the information needed from the view, puts it together and calls the appropriate models for processing. It contains no business logic.
View: displays the model that it gets from the controller.
I just thought of a good analogy for the Model. Think of it as the brain. It’s the most important thing. You don’t want to distribute its knowledge into other parts. What if you lose the other part, a finger let’s say, do you want to be dumber as a result? I certainly would not like that.
Martin Fowler, in Patterns of Enterprise Architecture, says that the proper definition for the Controller is “input controller.” He has a good explanation of MVC.
“A request comes in to an input controller, which pulls information off the request. It then forwards the business logic to an appropriate model object. The model object talks to the data source and does everything indicated by the request as well as gather information for the response. When it’s done it returns control to the input controller, which looks at the results and decides which view is needed to display the response. It then passes control, together with the response data, to the view.”
“Ensure that the models are completely separated from the Web presentation,” says Fowler.
How can I test whether I have a good MVC? It is not always easy. Here’s a good test: can I add a different view technology without duplicating any business logic?
The biggest benefit of proper implementation of the MVC pattern is that you have a separate business layer. Because it is seperate, it is easier to test — you don’t need a container to test. It is easier to understand. You don’t have duplication. And you are well prepared to add a different view technology to it without a major effort.
Another great benefit is that your architecture remains simple. Your controllers are simple. The business logic might be complicated, but it is in a separate layer and encapsulated in one place.
It is tempting to put business logic into the controller or the view (we all did it). Stop. Don’t do that. (I should yell here. ) Refactor the architecture if you have to. Putting business logic into the controller makes the application harder to maintain, it makes the business logic almost impossible to test, and it also spreads the business logic into several layers. All smells of a bad design.
The Spring framework gives you a skeleton MVC out of the box. But if you look at it, it only gives you the VC part, without the M. You have to add the M, the business logic yourself. It is very easy just to add it into the controller. I that’s what a lot of people do. Then you really have a VC pattern. Make sure you add the missing M and make sure it sits in a different room than the VC.
You will benefit in a big way if you followed the MVC principles. And no exceptions. You are hurting yourself if you follow an ad-hoc approach — a little logic here, a little there.
If you want to be a good coder, when using the MVC pattern, never break its principles.
Simplicity always wins, in my opinion. The following two quotes from Programming Pearls (book I’m reading now) need no further comment: they nail it.
|
A designer knows he has arrived at perfection not when there is no longer anything to add, but wen there is no longer anything to take away.
–Antoine de Saint-Exupery
the French writer and aircraft designer (quoted in Programming Pearls) |
|
More programmers should judge their work by this criterion. Simple programs are usally more reliable, secure, robust and efficient than their complex cousins, and easier to build and maintain.
–Jon Bentley
in Programming Pearls |
That’s an exact title from Johanna Rothman’s blog post. I totally agree: architects must code. If you an architect you need feedback. You need feedback because you want to make a better architecture in the future, to make improvements, and to see what doesn’t work. How do you get that feedback? You need to write code. There is no other way. There might be, of course, but most of the time it does not work.
I want to move into architecture in the next couple of years, I like to code: perfect marriage. But architecture is hard, it requires a lot of knowledge in a lot of areas. Most of all, it requires a lot of experience so you know what works and does not work. That’s why I’m learning a lot, keeping an eye on how to improve.
This point from Johanna says it best:
I’ve been a part of projects for 30 years. I’ve been assessing projects for 10 years. And every time I’ve seen an architect who doesn’t participate in the code-writing part of the project, I’ve seen an architecture that doesn’t do what it’s supposed to do, never mind extend to inevitable changes in requirements that occur during the project.Architects need feedback about their architecture. The only way to get feedback is to write the code, integrate it, and see what happens.
RelatedCharacteristics of a Software Architect, my previous post
ReferenceArchitects Must Write Code, Johanna Rothman
Are you thinking of becoming an architect someday? What are your plans for future? Maybe you are just a hard-core programmer and want to stay that way? There are people in each group. I would like to become an architect, a technical leader, and a manager. What? All three? Actually, I would like to become a manager, but I think a software manager should also be a technical leader and have at least some of the architect’s skills. I’d say, by the end of 2008, I would like to be a manager. Those are my goals for next couple of years. I am still not 100% on it, but more and more, that’s the direction I want to pursue.
Back to architecture. Being a software architect is not easy. It is only for the select few.
But I know, now, what software architect is, and what it entails. I found out from this excellent article, Characteristics of a software architect, by Peter Eeles, a Senior IT Architect at IBM. It’s an excellent read. A must read if you would like to go in that direction.
Software Architect is (I’m putting my comments for each major point; quotes are taken from the article)..
The architect is a technical leaderNo question about it. You have to know your stuff. You have to be an expert in a lot of different areas.
The architect role may be fulfilled by a teamThis is an interesting point. I think that’s how I would like it to be: a team effort.
The architect understands the software development processThis is a must. A software process needs to be continuously improved. You have to understand it first, to make improvements. Thus, you need to know others processes as well.
The architect has a knowledge of the business domainVery important. One interesting point in the article, by knowing the domain you can foresee some of the problems or extension to the system.
The architect has technology knowledgeOf course.
The architect has design skillsA big part of architecting is designing flexible, easy to understand, maintainable systems.
The architect has programming skillsAs an architect, you will oversee other programmers, you have to know.
The architect is a good communicatorAn architect has to be able to communicate with a lot of stakeholders; he has to share his vision clearly. Plus, he has to defend his decisions.
The architect makes decisionsVery good point.
The architect is aware of organizational politicsYou cannot avoid politics, as much as I don’t like it, that’s the truth.
The architect is a negotiatorYou have to talk to programmers, testers, business people. You have to negotiate.
What do you think? A lot of skills and knowledge required.
Excellent article. This is the best summary I’ve read. Written in a clean manner. Nice, pragmatic approach.
Do you still want to be an architect?
ReferenceCharacteristics of a software architect, The Rational Edge Newsletter, March 2005, my recommended resource
To learn design patterns is not easy. It’s one thing to just read about them and think you know them. It’s another thing to actually know how to use them, and to remember them as time passes by. I must admit, there is only a couple of the GoF patterns I remember. I read about them and after a while I forget them. However, that might be changing, as I have a different approach: I read several books on patterns at the same time.
A while back, I read Robert Martin’s Agile Software Development, Principles, Patterns, and Practices (a great book). I also read portions of the first edition of Design Patterns Explained (ok), portions of the classic Design Patterns, and the whole Holub on Patterns (I did not like it at all). I own all of the books I mentioned (except Holub on Patterns). And I recently bought Refactoring to Patterns by Kerievski. This latest book is what prompted me to change how I study design patterns. (I also own Martin Fowler’s Refactoring, which is a classic book that every developer should have by his side.)
I started reading Refactoring to Patterns. So far, about a third into the book, the book is very good. But I feel that the design patterns are starting to click. Why? As you might guess, the book tries to combine Fowler’s Refactoring and the GoF’s Design Patterns. So, whenever I read about a particular refactoring, I jump into Martin’s book. Not only that helps me understand the text better, I also get more info about the refactoring. (Plus, you get some good advice from Fowler, which I admire as a developer.) Same with patterns, whenever he mentions a GoF pattern (almost every refactoring), I go to the Design Patterns book.
However, the GoF book is not easy, and the book by itself is not enough sometimes. That’s when I turn to Robert Martin’s book, which contains simple Java code for a lot of patterns he mentions. And because he doesn’t mention all of them, I hit the web. This site, Design Patterns, contains code about all GoF patterns — very good resource.
And if that was not enough, I try to write practice code in Eclipse. I created a learn patterns project, and I create a new package for each pattern. This is very useful when, down the road, you forget about the pattern and want a quick reminder (I learn by example). Design patterns are hard to learn because we don’t get to use them right away. By practicing them, you see them in real world. You see them from a different angle. This is very valuable.
Have I found the ultimate solution for learning patterns. I don’t think so. But it makes a big difference to me. Yesterday, I learned about a Composite pattern, today I learned about the Boulder pattern. And I think the knowledge is deeper this time. I think this is a very good way. Little more involved and time consuming, but at the end, it’s what stays with you. Try it and learn.