views:

228

answers:

9

From a bookish perspective, you might say that x design pattern is applicable in y scenario, but I want to dig a little deeper here. So here are my queries:

  1. When do you first decide that you'll use design patterns? Do all of you decide upon design patterns before coding?
  2. Are there any DPs that you apply after you're done coding (small refactorings)? Do you apply DP while maintaining code?
  3. What are the design patterns that are predominantly applied during design?
  4. What are the DPs that you apply while tweaking/refactoring code?
  5. Are there any hints in code (technical not functional stuff) that suggest that you should apply a DP (like too many ifs, double dispatch, multithreading)? If so, could you name the DPs and their catchpoints?
  6. Do you use any Micro-DPs that makes you feel good about the code you've written (even though others hate you for it :p)?

Edit:
I'd like to add that I read DPs through "Head First Design Patterns" and although it's one of the best books to understand the pattern. I don't think I've been able to transition the Pizza examples to real world scenarios.

I think this is one of the most influential books on DP but we can still have a book that may enumerate the various popular business scenarios that demand a particular pattern alongside that pattern. This knowledge is still implicit to a large extent I think. Such a book would be a very nice quick reference don't you think :))

+5  A: 

I think there is a tendency, at least for those who newly learn design patterns, to over-apply a pattern; when you have a hammer, everything starts to look like a nail. A better way to go about it is to consider the alternatives for an API and their respective advantages and tradeoffs, then select whichever is appropriate. A design pattern is more of a terminologic help that allows developers to effectively relay what they are doing than to provide a guideline of how one should write code. That is, some things recurr in code and it is easier to tell your coworker that you used a factory than to explain that you had some object that you passed around that created other objects.... but just because the notion of factories exist does not mean you should try to make everything you see into a factory. Make sense?

Michael Aaron Safyan
I'm not concerned so much with the tendency to use DP as I'm with "HOW" you decide that you want to use it. I'd love to know what you have to say about each question.
Sidharth Panwar
@Sidharth, well, I believe I answered the how... you have to consider all the different reasonable ways it might look, and then delve into the implications of each choice.
Michael Aaron Safyan
@Michael Thanks. But I'm looking for something more and that's why I came up with quite a few subquestions. Let's see if we can dig something more on this. :)
Sidharth Panwar
A: 

IMO, there aren't any rules or common situations. Design patterns are used when they are appropriate, sometimes you know it when designing, sometimes when coding, sometimes when refactoring.

Most of the time I don't "apply a design pattern" one to one. They need adaption. Design patterns are like a catalog of experience. You just know some common or typical patterns and change them to the solution you need. (Note: they are patterns, not solutions.)

Stefan Steinegger
Exactly. The biggest problem though is that everybody dismisses DP by saying it depends on the scenario and we don't ever talk about the scenario. Do you apply it on a gut feeling? No. You as a programmer see something in code and say yeah, I can apply a DP here. I want to know what prompts that. I know it can be situational but before DPs people thought that code itself was situational. When it appeared they went WHOA!!! This is awesome :)
Sidharth Panwar
+1  A: 

In my experience it depends on the methodology and level of up front design as to when patterns get applied. Typically in an agile process I will see a pattern emerge fairly quickly as the intent of the code develops then refactor accordingly.

At the risk of stating the obvious unit testing alleviates a lot of the risk but the earlier you do it the better. I've never done a major refactor of code in support to implement a new pattern as the effort involved has rarely shown significant benefit. Unless the project is about to move into a new phase of development.

Small refactorings contained to one or two methods are fairly common across the lifetime of a project but these come under the pretence of there being no such thing as "code complete" :)

Daz Lewis
Hell, is there a limit to "Code Complete" popularity!!!! :)
Sidharth Panwar
+3  A: 

A Design Pattern describes a general reusable solution to a recurrent problem in a given context. You apply a pattern when you identity design problem(s) a pattern can solve. This can happen during initial design, during coding, during maintenance, etc. There is no absolute recipe, IMO.

See also

Pascal Thivent
+1 Will definitely look into these :)
Sidharth Panwar
+5  A: 

Two good books which deal with the how and when (not) to use Design Patterns are:

Péter Török
Good recommendations +1
Pascal Thivent
+1 Good books. I already have the 2nd one and its awesome.
Sidharth Panwar
+3  A: 

1 & 2

I think it wrong approach to eiher just blindly decide on a favourite pattern, or first code and then refactor to a known pattern. When you see a problem you will have to recognize the similarity to other problems that might be solved using known patterns.

Patterns are not a cookbook for success; it's a rule of thumb. Reading about cases in a book about pattern may help you to recognise problems, saving you from a misstake or two.

3: What patterns that are predominant depends very much on the domain. State patterns, proxies and facades are very common when doing applications that communicates alot to other systems. GUI application have different requirements, etc.

In my industry (Banking): I see a lot of the following GOF patterns: Factory Method, Singleton, Adapter, and Facade. Behaviour patterns are more or less killed by the predominant java-ee 14 layers of antipatterns that were mode du jour 10 years ago.

4: While refactoring - if a pattern will help you, use that. There isn't a class of patterns that are better suited when refactoring.

5: I think that the main indicator for a specific pattern is more related to the problem, and its similarity to other problems that have been solved by a particular pattern. Yes, If the code smells, that indicates that it might be needing a rewrite, and the problem should be analyzed again. While some problems are complicated, and can't be reduced, most can and a pattern may help to organize the problem a bit.

However. As a consequence of the observation that complex problems require complex solutions, thick people tend to write complex code; What out for that. Eg. State-patterns (which I am fond of) can complicate things to unimaginable levels if they are overused.

6: My collegues seems to like me, so I am probably not overdoing anything. I am myself rather annoyed by the overuse of Factories and Factory Methods in code that is not likely to change or exist in different implementations at the same time - and if it eventually will be changed, it will require a rewrite anyway. That's just a waste of time, and complicates the code and delays bug hunting.

KarlP
+1 You're the first one to actually answer each question. Thanks. :)
Sidharth Panwar
@Sidharth careful, just because someone complied to your question specs, doesn't mean its best addressing your question. I'd pay less attention to the following of your format :P ... +1 for #6 as an example of misuse of patterns in situations where the benefit isn't clear, and might not even be solving anything.
eglasius
@eglasius There is a reason I'm looking for each question's answer separately. And KarlP's post did deserve a +1, not just for the formatting but also for the content.
Sidharth Panwar
@Didhart I know, otherwise I wouldn't have +1 myself as I mentioned in my comment ;) Its just that imho these dilute the answer. Pascal have a simple answer (before the see also), and there is not much more to say about it. Other than that answers are overall guidance, those sub items aren't as relevant.
eglasius
+1  A: 
  1. It depends how you write the code. If it's a big project I decide before coding, then after I start writing the code, if I notice places where design patterns should be used, I refactor the code.

  2. Yes, as mentioned before.

  3. in 99.99% of the cases: Factory Pattern, Singleton (Like everyone I use it in many places because is simple to implement, and in practice I tend to remove it while refactoring the code). Then: Object Pool(if I have resources I want to reuse - some of my projects are games and I need a good management of resources), Strategy and Template Method (because they are great for decoupling and serve well the purpose to make the code easy to extend). Then the Adapter is something to use when you have a library you want to use, without relying on it(decoupling).

  4. Same as Above, if I didn't use them yet. It works also in the opposite way. If I don't find the reason to use a design pattern I remove it or skip it while writing the code (it happens all the time with singleton and from time to time with factories. Sometime I use a factory which is also a singleton to provide me those which were supposed to be singletons objects; not sure if it's wise thing to do, but it works for me).

  5. The only code hint I might think it the number of references you have to a class. You can also use PMD, jDepend and Architecture Rules to spot the places where the classes contains too many dependencies. I'm not sure it this is a coding tip. In the design phase and not only there when you decide to use a design pattern just think to the benefits. I found that Software Design Principles are extremely important to help you understand when and why (not) to use a design pattern, but they are unknown to many programmers who are using design patterns.

  6. I'm not sure what do you mean by Micro DP. I'm trying to use DPs only when I find reasons to use them and when the benefits seem to be bigger than the problems. I avoid the overuse because it leads you to loosing time implementing and maintaining factory patterns instead of real software.

php html
Sidharth Panwar
Some good things here... Thanks.
Sidharth Panwar
-1 for recommending Singleton. Singleton is an *anti-pattern* that ought to be avoided. There is no reason to ever use singleton; dependencies should be passed explicitly, and such refactors can be expensive.
Michael Aaron Safyan
1. It's true that singleton is a pattern that is overused. That doesn't mean there are not cases when it should be used. For example logger classes, applications properties or other factories that are themselves singleton. 2. I don't know if it's a good practice but I tend to use singletons as "temporary" classes, focusing on what I have to implement. Then when I solve the problem I can refactor the code and remove the singleton classes, replacing them with references or injected classes.
php html
3. As you mentioned the alternative to singletons is to refer directly the classes. This solution is unpractical if you don't have in place an injection mechanism. I personally I could not see how to pass a log class to virtually all the other classes/methods in a specific piece of code.
php html
A: 

Don't forget the book Design Patters, it may cover C++ but it doesn't matter, it's all patterns. Besides the book is very good.

And you don't learn patterns to implement them, that's the wrong way, you learn then so you can talk about code with other programmers. It's more a extension to your normal language then anything else. Use it in your code when needed, but not before :-)

UnixShadow
A: 

I'll take a different approach here and not mention books or address all those points separately.

In my case the single best impact I got it from getting to breathe SOLID. Imho you can relate a lot of scenarios & patterns to those principles, and following an evolving code base mindset along with it usually reveals the needs for all those other patterns for you.

As for hints, long methods => refactor. Even if its just moving to methods in the same class, since usually that intermediate step reveals the next move.

eglasius