The Design Pattern In Ruby

Today I will talk something about design pattern in Ruby.

The design pattern know as by the book `Gang of Four` and include three major classification are Creational Structural Behavioral

In this article I will explain four pattern belong to Structural they are

Facade pattern, Adapter pattern, Proxy pattern, Decorator pattern, because these four patterns they’re similar in mental model and just different in context and purpose.

There are many articles use massive code to explain and make example for pattern, so over here I will use use just simple code but massive picture and imagination of life situation to explain pattern. The life situation used is you imagine you’re a computer(Client) and wanna to connect(call) the USB(object).

The computer(client) wanna get USB data

The example code :

Now, this is origin type in our code and diagram, you can see the computer wanna get USB data must by helps of elements, all it looks like messy in the code base and diagram. It make confusion that we don’t know what major task is that we wanna do.

So, we make a simple change and the new code base with diagram are :

Wrap all elements in a package

What magic we do for here? We just wrap all elements in a package and give it a interface can interact with computer. Then the code and diagram will looks clean and we know what it do majorly. The pattern named Facade pattern. Ya, all the ruby wrapper, gem, SDK are Facade pattern. They wrap complex task and function in a package then create a simple clean interface for you, so you don’t worry about detail and just focus what the interface you will use for your task.

Now, over here, we assume the USB interface changed for one day, like the diagram :

The interface changed so that we can’t use

What should we do? Maybe we can change client interface to let they are appropriate. If your code and product are small, it maybe work, but usually when the code grow to large level like the spec of computer’s USB socket are common for customers in the word, you can’t change the interface or socket easily, right?

The correct way is create a middle lay in the code to transfer the interface get appropriate, as in the life you will take a adaptor to transfer the socket to your computer.

The green stuff is a adaptor

Now, you will see they work fine, the pattern is Adapter pattern.

In the different situation, if the USB interface is not changed, but is put away from you so that you can’t connect them like the diagram :

Put away from you

What should we do, we should take a extension cord, right? So the diagram become that :

The green diagram is extension cord act on behalf of the task from USB

You can see the extension cord doesn’t change the interface but just act on behalf of the task from USB to itself. SO the pattern is named Proxy pattern. The code in the below :

Now, the latest pattern is Decorator pattern, the situation is if I wanna combine other function with USB like the diagram, we should add a new green hubs and add new interface to achieve it.

Add green hubs and add new interface

All the pattern Facade pattern, Adapter pattern, Proxy pattern, Decorator pattern are finished, what do you realize? It looks similar between all the four patterns, right?

Yes, cause the major trick and spirit all of the four patterns are using a middleware to isolate origin object for different context and purpose.

Facade pattern use the middleware to wrap complex task to a simple interface.

Adapter pattern use the middleware to transfer inappropriate interface to a appropriate interface.

Proxy pattern use the middleware didn’t transfer interface just pure designate the task out when some situation you can’t or you don’t want interact with the origin object directly.

Decorator pattern use the middleware creating new interface for adding new function that you wanna use.

One clap, two clap, three clap, forty?

By clapping more or less, you can signal to us which stories really stand out.