Sign in to follow this  

Design Patterns

This topic is 3861 days old which is more than the 365 day threshold we allow for new replies. Please post a new topic.

If you intended to correct an error in the post then please contact us.

Recommended Posts

OK, I've just finished writing a 10 page paper on design patterns (specifically, the Gang of Four patterns) and I'm left wondering ... how relevant are they? Keep in mind, I've not yet gotten my hands on the GoF book. However, as my professor thrusts these ideas down my throat, I realized that I've gotten by just fine without many of the patterns presented. Which patterns are most relevant to game design? Which patterns do you like/dislike? Any thoughts from the pulpit?

Share this post


Link to post
Share on other sites
Using this site as a reference: http://www.tml.tkk.fi/~pnr/GoF-models/html/

Behavioral patterns
-------------------

Command: used heavily in threading/scheduling. Java's Runnable interface is a prime example.

Iterator: Java's enumerator, C++ stdlib iterators, etc. It's also a good idea to build your own iterators sometimes, to traverse non-linear structures (e.g. permutations of numbers).

Mediator: essential for complying with the rule of demeter ("delegating").

Observer: this is so often used it should require no further elaboration.

Strategy: used in modular algorithms (an example from AI: separating the search algorithm from search strategy).

Template method: an alternative to the Strategy pattern, used e.g. in Java's ResourceBundle (most of the implementation is given, you just need to plug in some of your own).

Visitor: a rather complex pattern IMHO, but allows doing type-safe multiple dispatch.

Share this post


Link to post
Share on other sites
Creational patterns
-------------------

Abstract factory / Factory method: these are often a useful and preferred way of constructing objects, since they allow making the newly constructed objects "context sensitive". For example, if you let your Company object create Employee objects, the Company can automatically set some of the the Employee's fields to comply with the Company's policies. Java's XML frameworks use these patterns.

Singleton: ah, the infamous Singleton... IMHO it's used too widely ;) Basically, using global objects destroys modularity, since clients of the Singleton must agree about its state - or in other words, each client must be kind of "aware" of each client. Used quite a bit in Java: for example, class XXX { public XXX getXXX(); } or class YYY { public YYY getInstance(); } speaks of the Singleton pattern.

[Edited by - uttumuttu on May 20, 2007 5:51:42 AM]

Share this post


Link to post
Share on other sites
I'm a noob when it comes to design patterns, but once I tried out the Decorator pattern, I was very pleased with it. I'm looking forward to using more of the patterns when the need arises.

Share this post


Link to post
Share on other sites
Structural patterns
-------------------

Adapter: used when you want to used legacy software to a new framework. Using an adapter is better than rewriting, since it respects the open/closed principle.

Composite: useful in modular frameworks. For example, if some class supports only a single Observer, you can still write a BroadcastObserver class that broadcasts the observations to multiple Observers.

Decorator: my favorite pattern! Used e.g. in Java's stream framework, where you can make any kind of InputStream buffered by creating a BufferedInputStream that uses the original InputStream as its source.

Flyweight: caches can often be described as Flyweight factorys.

Proxy: essential for complying with the rule of demeter.

[Edited by - uttumuttu on May 20, 2007 5:04:45 AM]

Share this post


Link to post
Share on other sites
Some afternotes
---------------

Clearly, design patterns are as relevant as ever. The motivation for design patterns can be traced back to a few simple "meta principles":

* Automatic dispatch: this is the pinnacle of all object oriented languages. Instead of having huge switch clauses, frameworks based on sound patterns implement dispatch automatically.

* Static over dynamic (explicit over implicit): instead of using the Command pattern, we could have simply used a function pointer (in C++, at least). But using the Command pattern makes our program more explicit. Named abstractions are a powerful, self-documenting tool.

* Open/closed principle: this principle says, essentially, that you should never "modify" old classes, but only add new classes that help old classes interwork in new ways. For example, the Adapter pattern is a great example.

* Loosened coupling: by interworking through abstractions, programs can eliminate cyclic dependencies (see John Lakos' "Large Scale C++" for elaboration).

* Rule of demeter: essentially, objects should avoid "train code", such as engine->getObjectList()->getObjectAt(0)->setVisible(true); and replace it with code such as engine->setForegroundVisible(); This is really just a special case of loosing coupling. "Pragmatic Programmer" includes some further (non-academic) elaboration.

(Ah, isn't doing other people's homework the best way to avoid one's own? ;)

Take care,
- Mikko

[Edited by - uttumuttu on May 20, 2007 5:12:56 AM]

Share this post


Link to post
Share on other sites
I've found design patterns to be most helpful in *naming* a process/technique/concept that you want to implement. If I know what it's called finding standard/optimised/generic implementations in any particular language is going to be reasonably easy.

It's also a great communication tool - rather than having to draw annotated UML for a pattern you can just direct other developers to a particular pattern and the reference in GoF.

Sometimes it's also nice to be able to look at someone else's code and be able to identify 'code smells' (ala Martin Fowler 'Refactoring'), and use your knowledge of patterns to help provide direction for extracting pieces of code back to easily identifiable patterns.

Patterns are definitely something you should know about, they'll make you a better developer, and more useful in a team situation. But also be aware that design patterns aren't a silver bullet. One example is that sometimes features of a particular language can restrict your designs to a subset of patterns that are easy to implement. If you need to move languages, be prepared to accept that new paradigms/techniques and patterns may be more or less suitable than you are used to.

Share this post


Link to post
Share on other sites
Quote:
Original post by argonaut
However, as my professor thrusts these ideas down my throat, I realized that I've gotten by just fine without many of the patterns presented. Which patterns are most relevant to game design? Which patterns do you like/dislike?

If you're getting on fine without patterns, chances are you're:
1. Writing very small programs.
2. Writing bad code.
3. Using some less formal variant of patterns already without realising it.

Or any combination of the above.

IMHO if you start thinking "where can I put pattern X in my code" you'll get overengineered and generally bad results. But if you know the patterns then you can spot when they're naturally emerging from your code and formalise/improve the implementation.

Share this post


Link to post
Share on other sites
When I first read about design patterns, I couldn't make much sense of them. But the more programs I write, the more I find places where I can apply them. Perhaps some people can read the GOF book and understand it instantly, but I think one needs to have experienced at least some of the problems the patterns are meant to solve to appreciate them.

Share this post


Link to post
Share on other sites
Design patterns are just that: patterns. They're derived from empirical observations of the high-level data and control structures used in successful programs; they're not a set of prefabricated immutable components to be dogmatically imposed upon a system's design. In this context, "successful programs" refers to productively-developed, correct, reusable and maintainable programs.

The merit of design patterns is that they work. In general, if you're using a programming language with single-dynamic-dispatch object-orientation (e.g. C++, Java, C#) and you need your program to perform differently depending upon the types of a pair of objects, then a scheme of two-stage delegated dispatch - i.e. Visitor - has proven to be an effective implementation of that.

Design patterns are also useful because they can save you extra work in the long run. If you're using half of a pattern now, later on you may actually find you wanted the whole pattern.

Suppose you make an object with a PushState and PopState methods. That's half of the Memento pattern, and has the disadvantage that you can only manage the state on a FIFO stack, whilst the full Memento has (e.g.) RememberState and RestoreState methods which allow you to separate the mechanisms of state-management from the policy.

If you're aware of Memento, then writing a PopState method should make your thumbs prick: you'll think about whether it could be better to use the full Memento, knowing that enough other people have found Memento useful enough that it's been identified as a recurring pattern.

Design patterns will always be relevant, although if you're really good you shouldn't have to think about them: they'll happen instinctively.

Share this post


Link to post
Share on other sites
Quote:
Original post by OrangyTang
Quote:
Original post by argonaut
However, as my professor thrusts these ideas down my throat, I realized that I've gotten by just fine without many of the patterns presented. Which patterns are most relevant to game design? Which patterns do you like/dislike?

If you're getting on fine without patterns, chances are you're:
1. Writing very small programs.
2. Writing bad code.
3. Using some less formal variant of patterns already without realising it.


4. Using a programming language where the issue that the design pattern is intended to work around simply doesn't exist. [smile]

Share this post


Link to post
Share on other sites
It's definitely worthwhile learning about and really understanding design patterns. Even if you don't use them all the time and prefer to cook up your own solutions to the problems they solve, they will at very least help you avoid reinventing the wheel.

Design patterns also help you better explain your code to other people and make your code more readable. Instead of going on at length about a solution to a problem you invented, you can simply inform the person you are talking to that you used a mediator pattern. As you might imagine, this can save a lot of time in the long run.

Share this post


Link to post
Share on other sites
Quote:
Original post by Zahlman
Quote:
Original post by OrangyTang
Quote:
Original post by argonaut
However, as my professor thrusts these ideas down my throat, I realized that I've gotten by just fine without many of the patterns presented. Which patterns are most relevant to game design? Which patterns do you like/dislike?

If you're getting on fine without patterns, chances are you're:
1. Writing very small programs.
2. Writing bad code.
3. Using some less formal variant of patterns already without realising it.

4. Using a programming language where the issue that the design pattern is intended to work around simply doesn't exist. [smile]

"The design pattern"? OrangyTang wasn't talking about a particular pattern. Whilst obviously there are certain patterns which aren't needed in certain languages -- we all know Visitor isn't "needed"* in languages with multiple dynamic dispatch -- not all patterns are a workaround for language failings. For example, Façade isn't a workaround for language failings.

* Of course, in a certain sense it's never "needed" in a language without it. You can always switch on type. The question isn't "can it only be done using Visitor?" but "does using Visitor lead to better code?". As compared to switching on type, it almost always does. Even in languages with multiple dynamic dispatch, it is sometimes desirable to use Visitor.

Additionally, although there are languages where many of the GoF design patterns aren't needed or aren't applicable -- Memento, for example, just plain doesn't make sense in Haskell -- those languages have their own design patterns which in turn don't apply to Java/C++/C#.

Share this post


Link to post
Share on other sites
You really need to read the first chapter of the GoF book. It explains the motivations behind design patterns and studying them, rather than just shoving them down your throat.

Share this post


Link to post
Share on other sites
I'm going to have to agree with OrangeTang. GoF was perhaps one of the only books I've read where the informational content had obvious practical application. I'd used most of them to one degree or another already. Now they just had names and a better more formal definition.

Share this post


Link to post
Share on other sites
Quote:
Original post by OrangyTang
IMHO if you start thinking "where can I put pattern X in my code" you'll get overengineered and generally bad results.


QFT

Share this post


Link to post
Share on other sites
I think to start appreciating patterns, you need to be beyond the "n00b" stage, just because you'll be reading up on some pattern, and you'll think back to cases where that's exactly what would have been elegant (or, where that's exactly what you did, without realizing it was a documented pattern).

Share this post


Link to post
Share on other sites
Thanks all for the insight! I can't wait to get my hands on the book finally (ordered it last week).

So far, the most fun I've had learning about design patterns was when I realized that I was already using some of them. That made me realize I might actually be kinda good at this programming thing :)

Don't worry ... after the coffee kicked in I realized I'm still a n00b.

Share this post


Link to post
Share on other sites
Just want to further rate-up this book. I just got my copy last Friday, and haven't been able to put it down. I'm not a n00b as far as C++ goes, 5+ years experience, but not in game dev terms. I just wish I'd bought it years ago, as I'm learning a lot from it. There are so many 'eureka' moments, both for things I've known for years but never in a structured way, and completely new revelations that I just know will improve my development starting right now.

Share this post


Link to post
Share on other sites

This topic is 3861 days old which is more than the 365 day threshold we allow for new replies. Please post a new topic.

If you intended to correct an error in the post then please contact us.

Create an account or sign in to comment

You need to be a member in order to leave a comment

Create an account

Sign up for a new account in our community. It's easy!

Register a new account

Sign in

Already have an account? Sign in here.

Sign In Now

Sign in to follow this