views:

582

answers:

5

Is there a specfic Gang Of Four Design Pattern that you frequently use, yet hardly see used in other peoples designs? If possible, please describe a simple example where this pattern can be useful. It doesn't have to necessarily be a Gang Of Four pattern, but please include a hyperlink to the pattern's description if you choose a non-GoF pattern.

Put another way:
What are some good/useful design patterns that I, or someone else who does have a passing knowledge of the main patterns, may not already know?

+4  A: 

Strategy pattern maybe? I see not a lot of person using it and it's quite useful when calculations change or can be accumulated together. I use it when a part of the calculation can be replaced by another calculation. Often in program that use for enterprise rate for product.

Here is some documentation :

Daok
+4  A: 

The Visitor pattern seems to be hard to understand for many new developers. I was using it for calculus when I had possibility to get value for Country>State>City>House. This way I haven't need to change how many data had in each sub collection. I just choose the right visitor and the final answer was get whatever the number of countries, states or cities.

Daok
+7  A: 

Steve Yegge wrote a (typically) long blog entry about the Interpreter Pattern, making the claim that this pattern is the only GoF pattern that can make code "smaller", and is criminally underutilized by programmers who otherwise are quite comfortable with the other GoF patterns. I am one of those programmers - I've never used the Interpreter pattern, although I recognize it's importance to things like DSL's. Anyway, it's a very thought-provoking essay if you have the intestinal fortitude to read an entire Yegge post.

Scott Bale
+4  A: 

Visitor has a bad reputation, partly due to some real problems

  • cyclic dependency between Vistor and Visited hierarchies
  • it's supposed to ruin encapsulation by exposing Visited classes internals

and partly due to the exposition in the GOF book, which emphasizes traversal of a structure rather than adding virtual functions to a closed hierarchy.

This means it doesn't get considered where appropriate, e.g for solving the double dispatch problem in statically typed languages. Example: a message or event passing system in C++, where the types of messages are fixed, but we want to extend by adding new recipients. Here, messages are just structs, so we don't care about encapsulating them. SendTo() doesn't know what type of Message or MessageRecipient is has.

#include <iostream>
#include <ostream>
using namespace std;

// Downside: note the cyclic dependencies, typically expressed in
// real life as include file dependency. 
struct StartMessage;
struct StopMessage;

class MessageRecipient
{
public:
    // Downside: hard to add new messages
    virtual void handleMessage(const StartMessage& start) = 0;
    virtual void handleMessage(const StopMessage& stop) = 0;
};

struct Message
{
    virtual void dispatchTo(MessageRecipient& r) const = 0;
};

struct StartMessage : public Message
{
    void dispatchTo(MessageRecipient& r) const
    {
        r.handleMessage(*this);
    }
    // public member data ...
};

struct StopMessage : public Message
{
    StopMessage() {}

    void dispatchTo(MessageRecipient& r) const
    {
        r.handleMessage(*this);
    }
    // public member data ...
};

// Upside: easy to add new recipient
class RobotArm : public MessageRecipient
{
public:
    void handleMessage(const StopMessage& stop)
    {
        cout << "Robot arm stopped" << endl;
    }

    void handleMessage(const StartMessage& start)
    {
        cout << "Robot arm started" << endl;
    }
};

class Conveyor : public MessageRecipient
{
public:
    void handleMessage(const StopMessage& stop)
    {
        cout << "Conveyor stopped" << endl;
    }

    void handleMessage(const StartMessage& start)
    {
        cout << "Conveyor started" << endl;
    }
};

void SendTo(const Message& m, MessageRecipient& r)
{
    // magic double dispatch
    m.dispatchTo(r);
}

int main()
{
    Conveyor c;
    RobotArm r;

    SendTo(StartMessage(), c);
    SendTo(StartMessage(), r);
    SendTo(StopMessage(), r);
}
fizzer
+2  A: 

If we're talking non-GOF patterns then Monitor Object is the 'Hello World' of concurrent OO programming. I'm amazed how many programmers manage not to have heard of it, or prefer to design their own ad hoc synchronization schemes.

fizzer

related questions