Ayende @ Rahien

Refunds available at head office

Can you justify your actions with regards to this pattern?

image

Probably the most common problem with unintended complexity in software is the unthinking application of patterns. I see a lot more code that has became more complex through that practice than code that has became simpler.

David Wheeler said: “All problems in computer science can be solved by another level of indirection;” However, we tend to forget the extra bit that Kevlin Henney's tacked at the end, "...except for the problem of too many layers of indirection."

Most patterns templates come with a clearly defined sections for “when to use” and “what are the disadvantages”. The problem is that patterns has became hip and cool, so people are actively seeking to use them.

Memento is my favorite pattern.

Do you know why?

I have never had found any need to implement it.

Remember, patterns are just formalized ways to work around limitations in the programming language or environment. Despite all the coolness points associated with them, they represent a non trivial cost in time, complexity and implications on a code base.

When you use a pattern, you have to be able to justify that use. What does it buy you? Have you considered the ramifications? What does it cost you? Is it worth it?  I tend to use patterns quite a bit, but in the last year or so I force myself to make a conscious decision whenever I want to apply one. Quite often, there is nothing that really requires it.

If you can get by without patterns, it usually means that you have a simpler solution. If you have a problem that fits a pattern’s problem description, and the pattern is applicable for your programming language and environment, you should use it.

Just don’t apply patterns all over the place, it end up being an overly engineered codebase that has significant maintenance overhead because of the patterns. I have seen too many apps that could have been simple turn into a multi layer mess of indirect calls that no one could really follow.

When I was in the army, I usually follow the following maxim:

Think, then do. And you have better be able to explain you actions.

It worked for me then and since.

Comments

Jacob Stanley
05/21/2009 07:06 AM by
Jacob Stanley

Can you think of an example of a situation where you've seen people use the Memento pattern, but something simpler could have been done instead?

configurator
05/21/2009 09:13 AM by
configurator

Can you think of an example where you'd actually use the Memento pattern?

Ryan Roberts
05/21/2009 09:52 AM by
Ryan Roberts

Memento is usable when the persistent version of an object may not be valid when restored. Say an ecommerce basket or wishlist where the products may no longer be available to the customer. There's usually going simpler ways to implement that than using an actual memento however.

I believe Uri's are considered to be a form of the memento pattern too.

Ryan Roberts
05/21/2009 10:17 AM by
Ryan Roberts

Sorry for the apostrophe abuse.

Paco
05/21/2009 10:23 AM by
Paco

With an undo button?

Justin Etheredge
05/21/2009 12:01 PM by
Justin Etheredge

The simplest use of Memento would be a transactional object. Essentially resetting the objects state is the memento pattern. It is a little bit more involved than that, I believe. It is a rarely used pattern in business apps, because usually when we need to reset the state of an object, we just throw it away and then retrieve a new copy from persistence.

Matt T
05/21/2009 02:08 PM by
Matt T

i think the biggest problem is that patterns go a step beyond the principles, most bad applications of patterns ive seen are where the developer doesnt understand the underlying principles e.g. strategy is all about programming to an interface bridge uses composition to detach the interface from the implementation. I think understanding the underlying principles of patterns is much more useful. Most patterns are based on leveraging the principles of encapsulation, inheritance, composition and programming to interface rather than implementation, i think maybe if the principles were hammered home first (why they are good, what they get you) and then patterns were discussed in terms of the principles would be a big step. As for memento, i dont remember using that pattern :)

Dmitry
05/21/2009 04:27 PM by
Dmitry

Windows Forms data binding makes use of the IEditableObject interface which allows to save and restore object state. That's how it implements the Cancel/Undo button.

The easiest way in .NET to implement the Memento pattern is to serialize the object and deserialize it back when necessary. Things get more complex if the object is not serializable or has events that are used by non-serializable objects such as windows forms/web pages.

The point here is new platforms often have better ways to implement functionality that used to be implemented with more traditional design patterns. Another example of this is events/delegates vs. the Observer pattern.

Steve
05/21/2009 05:15 PM by
Steve

Your timing is impeccable.

After 3-4 days of muddling through my own 'highly engineered' solution to a problem that was actually just too complex - I realized I was really losing sight of the end goal of the problem I was solving.

'Too complex' to start I decided.

I scratched it, took my lessons learned and painfully started over.

However, it's cleaner & more to the point - easier to follow and understand.

I guess in my thinking - later if I need to refactor it to add a new layer, etc... then do it then, but for now - I made it work, it's clean and most importantly.... it's much SIMPLER.

So, KISS right? :)

Min H
05/21/2009 11:45 PM by
Min H

I have to agree with what Matt T wrote. There are few examples of good object oriented design that are distilled for learning. The principles are great, but I tend to learn by example. Design patterns helped my understanding of applying OOP principles by giving me examples of where and how to use those principles effectively.

I honestly think the main thing people forget is that design patterns are solutions to specific problems. A huge mistake would be trying to shoehorn a problem into a design pattern. I think that design patterns should emerge natrually from a codebase rather than being enforced upon them.

Dave
05/22/2009 07:32 AM by
Dave

So, patterns add some level of complexity. So What? Separating code from presentation often also adds more complexity. Does that mean we don't use abstraction layers? Ofcourse not. The trick here is to find a good balance of using patterns.

However I go totally ballistic when I see a developer try to write it's own implementation of the observer pattern. That one comes with the .net framework for free and it's called events (subject is the holder of the event, observer is the listener).

You know what really adds unneeded complexity? Features in a program that no one will ever use of trying to keep everything generic of 'universal'. If you ask why, you always get the answer that it would make later modifications easier. My response is than often: "Are you psychic? You know already what clients what in future?"

You ask: can you justify the used pattern, I always ask a developer if he can justify (almost defend) the way he/she wrote the code. And we have public executions (code reviews) ;-)

My most used pattern? I keep everything SOLID.

Comments have been closed on this topic.