DEV Community

Cover image for Design Patterns Cheat Sheet
Ali Sherief
Ali Sherief

Posted on • Originally published at Medium

Design Patterns Cheat Sheet

No matter which programming language you are proficient in, it is always important that you know a few basic design patterns that will make your code architecture look better. After all, nothing beats a well-written program that's easily maintainable by others.

Software engineers invented design patterns to templatize common concepts in software engineering. Most of these patterns naturally occur in many programs, and the templates were specifically designed to be as efficient when used in a particular setting as possible.

As I'm expecting developers from all kinds of languages to be reading this, I will refrain from citing code examples for each design pattern since those who don't understand the language will find it difficult to understand. UML diagrams are the way to go here.

Proxy Pattern

proxy pattern UML diagram Image from wikipedia.org

The proxy pattern is used when we want a resource to be managed by a surrogate instead of directly. A scenario where the proxy pattern is particularly effective is during web content loading, by displaying a box with a moving gradient on the screen while a network request is downloading the actual content. Other uses of the proxy pattern are to act as a middleman between a remote resource, abstract expensive parts of the code into another class, implement access control to a resource, or implement resource locking.

The proxy pattern consists of an interface with all the resource methods and two different classes that implement the interface concretely. The classes should have a protected constructor, virtual get & set methods, and a static function that calls the constructor itself. If your language doesn't support interfaces, use an abstract class and make the two classes' subclasses. Ensure you override all the methods that are part of the "interface" (actually the abstract class).

One of these subclasses should be the real resource manager, and the other subclass should be the proxy surrogate that acts as the resource manager.

The proxy pattern makes the most sense to use when your resource management is being done inside your program's main functions instead of in the background.

Flyweight

flyweight pattern UML diagram Image from wikipedia.org

The Flyweight pattern is used for acting on several objects at once, which all have almost identical properties. The flyweight uses just one class for all the effectively constant class properties - the rest of the state that has to change is passed as an argument to the methods the flyweight objects must support, implemented inside the Flyweight class itself.

The rule of thumb for flyweight classes is never to update the internal state. It is supposed to remain constant to preserve the memory savings it gives us. Consequentially, all intrinsic state should be marked as private.

The mutable state should always be passed via a method argument and stored in a context manager object that corresponds to but is not a member of its flyweight class.

You can still use hierarchical relationships inside flyweight classes, but this will have to be represented in the class hierarchy of the context objects you pass as arguments.

Strategy

strategy pattern UML diagram Image from wikipedia.org

The strategy pattern lets you define different ways to execute a task based on user input, hence the same strategy. It is one of the most commonly used patterns. Whenever a method uses an abstract class or interface to compute the result differently, it's using the strategy pattern. The strategy pattern is meant to make code more extensible and easier to test.

A strategy is constructed using an interface full of actions a strategy must support, followed by multiple different class implementations of that interface. A context is a callable object reference pointing to the interface but is actually using one of the implementation classes.

The strategy pattern is particularly effective for writing tests because you can make an interface with your class functions, an implementation with your real class, and another "mock" implementation that has all the functions but does not affect external state such as databases. You can substitute the real class for the mock class on the fly.


Thanks for reading. If you have any comments about the design patterns used here, leave them below.

Cover Image by sianstock from Envato Elements

Top comments (0)