Architecture: Proxy design pattern

I have written the working code based on the Architectural diagram, which can be downloaded from Github

Working code github link:



4_2-Proxy Design Pattern class diagram




Good Design vs Bad Design – Information overload

The Bad: Parking Signs in Los Angeles

Parking signs in Los Angeles (LA) have been the epitome of information overload for decades. They’ve always been notoriously hard to understand, because the traffic rules are complex, resulting in the need to convey a lot of information in a small area.

How confusing are these signs? Traditionally, very—look at this example from the 2010s:

Author/Copyright holder: Jorge Gonzalez. Copyright terms and licence: CC BY-SA 2.0

As LA parking signs go, this example is already a pretty simple one.

Imagine you are a driver along this road on a Tuesday morning at 9 a.m. Can you park at this spot? What sounds like a simple question takes a lot of mental processing to answer.

As designers, we’re often faced with situations where we have to design for a lot of information to be displayed in a small space. The parking signs in LA might be an extreme case, but many times designing for mobile apps means facing the same problems. Is there a way out—for both the parking signs and designers in general?

The Good: Nikki Sylianteng’s Parking Sign

Designing a sign to display all the information, while being easy to understand, sounds like an impossible task. But that’s exactly what Brooklyn designer Nikki Sylianteng did.

Author/Copyright holder: Nikki Sylianteng. Copyright terms and licence: CC BY-NC-SA 4.0

Nikki’s proposed parking sign was eventually used in LA as part of a trial run.

Part of why Nikki’s design1 works well is that it is user-centred: Nikki realised drivers simply want to know whether they can park at a spot. Yes or no—that’s all drivers needed, and that’s all the parking sign shows.

Her design also made use of visuals, rather than text, to convey information. The result is incredibly intuitive: green for OK, red for No Parking. It’s even designed for the colour blind, with stripes for No Parking.

Now when you look at the sign, you’ll know that on Tuesday at 9 a.m., parking is not allowed. The bars show what’s what at a glance—simple.

Lessons Learnt: Best Practice

  • Understand what your users need, then design based on that. This helps reduce information overload.
  • Have lots of information to convey to your users? Try using visuals instead of text. Learn more about data visualisation here.

Software Development AntiPatterns

Good software structure is essential for system extension and maintenance. Software development is a chaotic activity, therefore the implemented structure of systems tends to stray from the planned structure as determined by architecture, analysis, and design.

Software refactoring is an effective approach for improving software structure.

The resulting structure does not have to resemble the original planned structure.

The structure changes because programmers learn constraints and approaches that alter the context of the coded solutions. When used properly, refactoring is a natural activity in the programming process.

For example, the solution for the Spaghetti Code AntiPattern defines a software development process that incorporates refactoring. Refactoring is strongly recommended prior to performance optimization. Optimizations often involve compromises to program structure. Ideally, optimizations affect only small portions of a program. Prior refactoring helps partition optimized code from the majority of the software.

Development AntiPatterns utilize various formal and informal refactoring approaches. The following summaries provide an overview of the Development AntiPatterns found in this chapter and focus on the development AntiPattern problem. Included are descriptions of both development and mini-AntiPatterns. The refactored solutions appear in the appropriate AntiPattern templates that follow the summaries.

  • The Blob
    Procedural-style design leads to one object with a lion’s share of the responsibilities, while most other objects only hold data or execute simple processes. The solution includes refactoring the design to distribute responsibilities more uniformly and isolating the effect of changes.
  • Continuous Obsolescence
    Technology is changing so rapidly that developers often have trouble keeping up with current versions of software and finding combinations of product releases that work together. Given that every commercial product line evolves through new releases, the situation is becoming more difficult for developers to cope with. Finding compatible releases of products that successfully interoperate is even harder.
  • Lava Flow
    Dead code and forgotten design information is frozen in an ever-changing design. This is analogous to a Lava Flow with hardening globules of rocky material. The refactored solution includes a configuration management process that eliminates dead code and evolves or refactors design toward increasing quality.
  • Ambiguous Viewpoint
    Object-oriented analysis and design (OOA&D) models are often presented without clarifying the viewpoint represented by the model. By default, OOA&D models denote an implementation viewpoint that is potentially the least useful. Mixed viewpoints don’t allow the fundamental separation of interfaces from implementation details, which is one of the primary benefits of the object-oriented paradigm.
  • Functional Decomposition
    This AntiPattern is the output of experienced, nonobject-oriented developers who design and implement an application in an object-oriented language. The resulting code resembles a structural language (Pascal, FORTRAN) in class structure. It can be incredibly complex as smart procedural developers devise very “clever” ways to replicate their time-tested methods in an object-oriented architecture.
  • Poltergeists
    Poltergeists are classes with very limited roles and effective life cycles. They often start processes for other objects. The refactored solution includes a reallocation of responsibilities to longer-lived objects that eliminate the Poltergeists.
  • Boat Anchor
    A Boat Anchor is a piece of software or hardware that serves no useful purpose on the current project. Often, the Boat Anchor is a costly acquisition, which makes the purchase even more ironic.
  • Golden Hammer
    A Golden Hammer is a familiar technology or concept applied obsessively to many software problems. The solution involves expanding the knowledge of developers through education, training, and book study groups to expose developers to alternative technologies and approaches.
  • Dead End
    A Dead End is reached by modifying a reusable component if the modified component is no longer maintained and supported by the supplier. When these modifications are made, the support burden transfers to the application system developers and maintainers. Improvements in the reusable component are not easily integrated, and support problems can be blamed upon the modification.
  • Spaghetti Code
    Ad hoc software structure makes it difficult to extend and optimize code. Frequent code refactoring can improve software structure, support software maintenance, and enable iterative development.
  • Input Kludge
    Software that fails straightforward behavioral tests may be an example of an input kludge, which occurs when ad hoc algorithms are employed for handling program input.
  • Walking through a Minefield
    Using today’s software technology is analogous to walking through a high-tech mine field. Numerous bugs are found in released software products; in fact, experts estimate that original source code contains two to five bugs per line of code.
  • Cut-and-Paste Programming
    Code reused by copying source statements leads to significant maintenance problems. Alternative forms of reuse, including black-box reuse, reduce maintenance issues by having common source code, testing, and documentation.
  • Mushroom Management
    In some architecture and management circles, there is an explicit policy to keep system developers isolated from the system’s end users. Requirements are passed second-hand through intermediaries, including architects, managers, or requirements analysts.

Interpreter Design Pattern

Download the working example demo code in java from my GIT repository –

Example Code Description :
1. Date interpreter example : The main cause of Y2K virus was interpretaiton of date format, in this example code I tried to address the same so that system can intrepret any date given in any formats. we have a interpreter for DD, MM and YYYY (rule to pick the date from context) so you provide the format and system gives you the conversion. Straight forward. 
2. And Or Expression : This example taks a string where in it should match the expression based on rule which accomplies And / Or expression. Code is simple and small but a bit triky to get hold of. Feel free to downlaod and play with it.

Direct link :

  • Given a language, define a representation for its grammar along with an interpreter that uses the representation to interpret sentences in the language.
  • Map a domain to a language, the language to a grammar, and the grammar to a hierarchical object-oriented design.


Problem Area

This interpreter design pattern does not give solution for building a whole large interpreter for a language. It can be applicable for smaller chunks where grammar and interpretation is applicable. We can consider scenarios like regular expressions and interpreting mathematical expression.


The Interpreter pattern discusses: defining a domain language (i.e. problem characterization) as a simple language grammar, representing domain rules as language sentences, and interpreting these sentences to solve the problem. The pattern uses a class to represent each grammar rule. And since grammars are usually hierarchical in structure, an inheritance hierarchy of rule classes maps nicely.


An abstract base class specifies the method interpret(). Each concrete subclass implements interpret() by accepting (as an argument) the current state of the language stream, and adding its contribution to the problem solving process.


The Intepreter pattern defines a grammatical representation for a language and an interpreter to interpret the grammar. Musicians are examples of Interpreters. The pitch of a sound and its duration can be represented in musical notation on a staff. This notation provides the language of music. Musicians playing the music from the score are able to reproduce the original pitch and duration of each sound represented.

Example of Interpreter

Check list
  1. Decide if a “little language” offers a justifiable return on investment.
  2. Define a grammar for the language.
  3. Map each production in the grammar to a class.
  4. Organize the suite of classes into the structure of the Composite pattern.
  5. Define an interpret(Context) method in the Composite hierarchy.
  6. The Context object encapsulates the current state of the input and output as the former is parsed and the latter is accumulated. It is manipulated by each grammar class as the “interpreting” process transforms the input into the output.

Memento Design Pattern

Download the working example demo code in java from my GIT repository –

Example Code Description :
1. Video Game Example : You can pick your player name, its mask and other details. You earn few more points and get the option to save the games state. Later you can restore your games state as well. The memento is used basically which clones your domain object and keeps it with itself. Care taker is the class which interects with client and talks to Originator. Originator component detals with domain object to save and restore the momento. Download, run and enjoy the game 🙂

Direct link :

  • Without violating encapsulation, capture and externalize an object’s internal state so that the object can be returned to this state later.
  • A magic cookie that encapsulates a “check point” capability.
  • Promote undo or rollback to full object status.

Need to restore an object back to its previous state (e.g. “undo” or “rollback” operations).



The client requests a Memento from the source object when it needs to checkpoint the source object’s state. The source object initializes the Memento with a characterization of its state. The client is the “care-taker” of the Memento, but only the source object can store and retrieve information from the Memento (the Memento is “opaque” to the client and all other objects). If the client subsequently needs to “rollback” the source object’s state, it hands the Memento back to the source object for reinstatement.

An unlimited “undo” and “redo” capability can be readily implemented with a stack of Command objects and a stack of Memento objects.


The Memento design pattern defines three distinct roles:

  1. Originator – the object that knows how to save itself.
  2. Caretaker – the object that knows why and when the Originator needs to save and restore itself.
  3. Memento – the lock box that is written and read by the Originator, and shepherded by the Caretaker.


Check list

  1. Identify the roles of “caretaker” and “originator”.
  2. Create a Memento class and declare the originator a friend.
  3. Caretaker knows when to “check point” the originator.
  4. Originator creates a Memento and copies its state to that Memento.
  5. Caretaker holds on to (but cannot peek into) the Memento.
  6. Caretaker knows when to “roll back” the originator.
  7. Originator reinstates itself using the saved state in the Memento.
Rules of thumb
  • Command and Memento act as magic tokens to be passed around and invoked at a later time. In Command, the token represents a request; in Memento, it represents the internal state of an object at a particular time. Polymorphism is important to Command, but not to Memento because its interface is so narrow that a memento can only be passed as a value.
  • Command can use Memento to maintain the state required for an undo operation.
  • Memento is often used in conjunction with Iterator. An Iterator can use a Memento to capture the state of an iteration. The Iterator stores the Memento internally.

Mediator Design Pattern

Download the working example demo code in java from my GIT repository –

Example Code Description :
1. Air Traffic Controller at air port : Flights classes have the behaviour of landing. Before landing they need to communicate to figure out if run ways is not blocker. With the same intent I have introduced a mediator class called at which will mediate the communication between the flights and assist them for landing.
2. Producer Consumer for messages: Producer and Consumer (multiple objects) relies on a mediator for coordination of exact state to proceed ahead. This is a multi treaded program with intermediatory class –
3. Traffic Light Signal : When one light turns On, rest other have to be turned off. If each light will communicate with another lights to changes their state then it would be highly coupled and difficult to maintain. By introducing Light Mediator which is responsible to hold object reference of all other light and communication task, the design becomes flexible and decoupled. We can add any color light and remove it when ever we want that too at run time.  

Zipped code download link :

Discussion :

Mediator pattern defines an object that encapsulates how a set of objects interact. This pattern is considered to be a behavioral pattern due to the way it can alter the program’s running behavior.

Usually a program is made up of a large number of classes. So the logic and computation is distributed among these classes. However, as more classes are developed in a program, especially during maintenance and/or refactoring, the problem of communication between these classes may become more complex. This makes the program harder to read and maintain. Furthermore, it can become difficult to change the program, since any change may affect code in several other classes.

With the mediator pattern, communication between objects is encapsulated with a mediator object. Objects no longer communicate directly with each other, but instead communicate through the mediator. This reduces the dependencies between communicating objects, thereby lowering the coupling.

Before Mediator Design Pattern

So what is the problem we are trying to solve here? This complex interaction between objects creates dependency and tighter coupling. We stand for loose coupling, we want to reduce dependency as much as possible, we want more reuse.


After Mediator Design Pattern

Define an object that acts as a mediator between communicating objects thus removing the direct dependency between those communicating objects. This mediator object encapsulates the interaction information and uses it to enable communication between the objects.


The intermediate mediator object is not only to communicate between two objects, but it helps in interaction for a set of peer objects. This mediator object is like a router in networks, which is routes / controls or coordinates communication between systems.

Real-time Example for Mediator Design Pattern

Air traffic controller (ATC) is a mediator between flights. It helps in communication between flights and co-oridates/controls landing, take-off. Two flights need not interact directly and there is no dependency between them. This dependency is solved by the mediator ATC. If ATC is not there all the flights have to interact with one another and managing the show will be very difficult and things may go wrong.

ATC Mediator

Mediator Pattern Implementation

In a mediator design pattern implementation we will have

  • mediator interface – an interface that defines the communication rules between objects
  • concrete mediator – a mediator object which will enables communication between participating objects
  • colleague – objects communicating with each other through mediator object
Check list
  1. Identify a collection of interacting objects that would benefit from mutual decoupling.
  2. Encapsulate those interactions in the abstraction of a new class.
  3. Create an instance of that new class and rework all “peer” objects to interact with the Mediator only.
  4. Balance the principle of decoupling with the principle of distributing responsibility evenly.
  5. Be careful not to create a “controller” or “god” object.

Chain of Responsibility Design Pattern

Download the working example demo code in java from my GIT repository –

Example Code Description :
1. Number Handler : Client passes a request (signed number ) to first node of change. Positive number handler will see if number is positive it will print it else pass it to next handler which is Zero number handlers, which in return do the same and pass it to negative number handler.
2. ATM Money dispatcher : Client would enter the amount ex $576/- to first node which might have different handlers for each denomination like 500 dollar bill handler, 100, 50, 10, 5, 2 and 1 dollar bill handers and finally dispatch the money. 
3. Log Handler : Client would enter a message and set the logging level based on which all the consoles would get notifications. In this example the chain is set, however the first node / handler is decided dynamically based on the log level (to skip unused nodes in the chain)

Download example code in zipped format :

  • Avoid coupling the sender of a request to its receiver by giving more than one object a chance to handle the request. Chain the receiving objects and pass the request along the chain until an object handles it.
  • Launch-and-leave requests with a single processing pipeline that contains many possible handlers.
  • An object-oriented linked list with recursive traversal.

Highlights of Chain of Responsibility

  • Sender will not know which object in the chain will serve its request.
  • Every node in chain will have the responsibility to decide, if they can serve the request.
  • If node decides to forward the request, it should be capable of choosing the next node and forward it.
  • There is a possibility where none of the node may serve the request.


There is a potentially variable number of “handler” or “processing element” or “node” objects, and a stream of requests that must be handled. Need to efficiently process the requests without hard-wiring handler relationships and precedence, or request-to-handler mappings.

Chain of responsibility example


Encapsulate the processing elements inside a “pipeline” abstraction; and have clients “launch and leave” their requests at the entrance to the pipeline.

Chain of responsibility example

The pattern chains the receiving objects together, and then passes any request messages from object to object until it reaches an object capable of handling the message. The number and type of handler objects isn’t known a priori, they can be configured dynamically. The chaining mechanism uses recursive composition to allow an unlimited number of handlers to be linked.

Chain of Responsibility simplifies object interconnections. Instead of senders and receivers maintaining references to all candidate receivers, each sender keeps a single reference to the head of the chain, and each receiver keeps a single reference to its immediate successor in the chain.

Make sure there exists a “safety net” to “catch” any requests which go unhandled.

Do not use Chain of Responsibility when each request is only handled by one handler, or, when the client object knows which service object should handle the request.


The derived classes know how to satisfy Client requests. If the “current” object is not available or sufficient, then it delegates to the base class, which delegates to the “next” object, and the circle of life continues.

Chain of responsibility scheme

Multiple handlers could contribute to the handling of each request. The request can be passed down the entire length of the chain, with the last link being careful not to delegate to a “null next”.


The Chain of Responsibility pattern avoids coupling the sender of a request to the receiver by giving more than one object a chance to handle the request. ATM use the Chain of Responsibility in money giving mechanism.

Chain of responsibility example

Check list
  1. The base class maintains a “next” pointer.
  2. Each derived class implements its contribution for handling the request.
  3. If the request needs to be “passed on”, then the derived class “calls back” to the base class, which delegates to the “next” pointer.
  4. The client (or some third party) creates and links the chain (which may include a link from the last node to the root node).
  5. The client “launches and leaves” each request with the root of the chain.
  6. Recursive delegation produces the illusion of magic.
Rules of thumb
  • Chain of Responsibility, Command, Mediator, and Observer, address how you can decouple senders and receivers, but with different trade-offs. Chain of Responsibility passes a sender request along a chain of potential receivers.
  • Chain of Responsibility can use Command to represent requests as objects.
  • Chain of Responsibility is often applied in conjunction with Composite. There, a component’s parent can act as its successor.