Java Tutorial : Hands on project for library management application

I am coding Library Management Project in Java and teaching it in simple steps.
If you are interested in doing or learning Java with hands on project then check out this play list from my youtube video 🙂

Git Repo :
https://github.com/ProjectsbyPrem/LibraryManagement

Project requirements:
https://docs.google.com/document/d/1ZzAuMQ5jqCwh1qvF5DIvuVP6J1QwUugTuQ1uQjIXRkg/edit
For details visit : http://www.premaseem.com

Java : How to setup and run activeMQ for JMS on macos

Setup using command of home brew : 

➜ software brew install apache-activemq
==> Downloading https://www.apache.org/dyn/closer.cgi?path=/activemq/5.13.0/apache-activemq-5.13.0-bin.tar.gz
==> Best Mirror http://apache.spinellicreations.com/activemq/5.13.0/apache-activemq-5.13.0-bin.tar.gz

curl: (28) Resolving timed out after 5539 milliseconds
Trying a mirror…
==> Downloading https://archive.apache.org/dist/activemq/5.13.0/apache-activemq-5.13.0-bin.tar.gz
######################################################################## 100.0%
🍺 /usr/local/Cellar/activemq/5.13.0: 559 files, 58.9M, built in 2 minutes 41 seconds

 

Go to default directory of active mq 

When you use brew the default installation directory on mac os is below
➜  software cd /usr/local/Cellar/activemq/

Starting the activemq service 

➜ bin git:(master) activemq start
INFO: Loading ‘/usr/local/Cellar/activemq/5.13.0/libexec//bin/env’
INFO: Using java ‘/Library/Java/JavaVirtualMachines/jdk1.8.0_60.jdk/Contents/Home/bin/java’
INFO: Starting – inspect logfiles specified in logging.properties and log4j.properties to get details
INFO: pidfile created : ‘/usr/local/Cellar/activemq/5.13.0/libexec//data/activemq.pid’ (pid ‘58039’)

Please verifiy the service is running using below command
➜  bin git:(master) ps -eaf | grep activemq

Testing the activemq service on bowser

Open below url and use id as “admin” and password as “admin” to login
http://127.0.0.1:8161/admin/

Stopping the serving 

➜ bin git:(master) activemq stop
INFO: Loading ‘/usr/local/Cellar/activemq/5.13.0/libexec//bin/env’
INFO: Using java ‘/Library/Java/JavaVirtualMachines/jdk1.8.0_60.jdk/Contents/Home/bin/java’
INFO: Waiting at least 30 seconds for regular process termination of pid ‘58039’ :
Java Runtime: Oracle Corporation 1.8.0_60 /Library/Java/JavaVirtualMachines/jdk1.8.0_60.jdk/Contents/Home/jre
Heap sizes: current=62976k free=61664k max=932352k
JVM args: -Xms64M -Xmx1G -Djava.util.logging.config.file=logging.properties -Djava.security.auth.login.config=/usr/local/Cellar/activemq/5.13.0/libexec//conf/login.config -Dactivemq.classpath=/usr/local/Cellar/activemq/5.13.0/libexec//conf:/usr/local/Cellar/activemq/5.13.0/libexec//../lib/ -Dactivemq.home=/usr/local/Cellar/activemq/5.13.0/libexec/ -Dactivemq.base=/usr/local/Cellar/activemq/5.13.0/libexec/ -Dactivemq.conf=/usr/local/Cellar/activemq/5.13.0/libexec//conf -Dactivemq.data=/usr/local/Cellar/activemq/5.13.0/libexec//data
Extensions classpath:
[/usr/local/Cellar/activemq/5.13.0/libexec/lib,/usr/local/Cellar/activemq/5.13.0/libexec/lib/camel,/usr/local/Cellar/activemq/5.13.0/libexec/lib/optional,/usr/local/Cellar/activemq/5.13.0/libexec/lib/web,/usr/local/Cellar/activemq/5.13.0/libexec/lib/extra]
ACTIVEMQ_HOME: /usr/local/Cellar/activemq/5.13.0/libexec
ACTIVEMQ_BASE: /usr/local/Cellar/activemq/5.13.0/libexec
ACTIVEMQ_CONF: /usr/local/Cellar/activemq/5.13.0/libexec/conf
ACTIVEMQ_DATA: /usr/local/Cellar/activemq/5.13.0/libexec/data
Connecting to pid: 58039
………………………….
INFO: Regular shutdown not successful, sending SIGKILL to process
INFO: sending SIGKILL to pid ‘58039’

Other tasks which can run as
$ activemq <taskname>

Tasks:
browse – Display selected messages in a specified destination.
bstat – Performs a predefined query that displays useful statistics regarding the specified broker
consumer – Receives messages from the broker
create – Creates a runnable broker instance in the specified path.
decrypt – Decrypts given text
dstat – Performs a predefined query that displays useful tabular statistics regarding the specified destination type
encrypt – Encrypts given text
export – Exports a stopped brokers data files to an archive file
list – Lists all available brokers in the specified JMX context
producer – Sends messages to the broker
purge – Delete selected destination’s messages that matches the message selector
query – Display selected broker component’s attributes and statistics.
start – Creates and starts a broker using a configuration file, or a broker URI.
stop – Stops a running broker specified by the broker name.

What is ISO date format

As world is becoming a big family with globalization, we need the standard to followed to avoid confusion especially related to date and time. If every country or person would write dates in different format, it would be confusing to figure out exact date while doing communication across countries, hence ISO has come up with ISO date format to be followed by every one. 

International Standard ISO 8601 specifies numeric representations of date and time. This standard notation helps to avoid confusion in international communication caused by the many different national notations and increases the portability of computer user interfaces.

YYYY-MM-DDThh:mm:ss.sTZD

where:

     YYYY = four-digit year

     MM   = two-digit month (01=January, etc.)

     DD   = two-digit day of month (01 through 31)

     hh   = two digits of hour (00 through 23) (am/pm NOT allowed)

     mm   = two digits of minute (00 through 59)

     ss   = two digits of second (00 through 59)

     s    = one or more digits representing a decimal fraction of a second

     TZD  = time zone designator (Z or +hh:mm or -hh:mm)

example: 

 1997-07-16T19:20:30.45Z (Z at end indicates time is taken with Zero correction i.e. UTC time)

 1997-07-16T19:20:30.45+01:00 (+1:00 at end indicates time is taken at time zone which is 1:00 ahead of UTC time)

Advantages of the ISO 8601 standard date notation compared to other commonly used variants:

  • easily readable and writeable by software (no ‘JAN’, ‘FEB’, … table necessary)
  • easily comparable and sortable with a trivial string comparison
  • language independent
  • can not be confused with other popular date notations
  • consistency with the common 24h time notation system, where the larger units (hours) are also written in front of the smaller ones (minutes and seconds)
  • strings containing a date followed by a time are also easily comparable and sortable (e.g. write “1995-02-04 22:45:00”)
  • the notation is short and has constant length, which makes both keyboard data entry and table layout easier
  • identical to the Chinese date notation, so the largest cultural group (>25%) on this planet is already familiar with it 🙂
  • date notations with the order “year, month, day” are in addition already widely used e.g. in Japan, Korea, Hungary, Sweden, Finland, Denmark, and a few other countries and people in the U.S. are already used to at least the “month, day” order
  • a 4-digit year representation avoids overflow problems after 2099-12-31

Java Program to find out duplicate number in an Array

Problem statement : In an array 1-100, many numbers are duplicates, how do you find it?

we can loop over array and put the values in a map to find out duplicate numbers with the number of time they repeat them selves.

            int[] numbers = new int [100];
        Map<Integer, Integer> map = new HashMap<Integer, Integer>();
       
        for(int i=0;i<100;i++){
            int temp = numbers[i];
            Integer count = map.get(temp);
            map.put(temp, (count == null) ? 1 : count + 1);
        }
       
        for (Map.Entry<Integer, Integer> entry : map.entrySet()) {
            System.out.println(“Key : ” + entry.getKey() + ” Value repetition time: “
                + entry.getValue());
        }

The solution I proposed gives you the freedom of printing you data in several way or store the data in a manner which is most easy to retrieve. ie create a map for each number and save them against the key.

What is Code Refactoring ?

Refactoring : A change made to the internal structure of software to make it easier to understand and cheaper to modify without changing its observable behavior.

Code refactoring is the process of restructuring existing computer code – changing the factoring – without changing its external behavior. Refactoring improves nonfunctional attributes of the software. Advantages include improved code readability and reduced complexity to improve source code maintainability, and create a more expressive internal architecture or object model to improve extensibility. Typically, refactoring applies a series of standardised basic micro-refactorings, each of which is (usually) a tiny change in a computer program’s source code that either preserves the behaviour of the software, or at least does not modify its conformance to functional requirements.

I’ve been asked, “Is refactoring just cleaning up code?” In a way the answer is yes, but I think refactoring goes further because it provides a technique for cleaning up code in a more efficient and controlled manner. Since I’ve been using refactoring, I’ve noticed that I clean code far more effectively than I did before. This is because I know which refactorings to use, I know how to use them in a manner that minimizes bugs, and I test at every possible opportunity.

Like refactoring, performance optimization does not usually change the behavior of a component (other than its speed); it only alters the internal structure. However, the purpose is different. Performance optimization often makes code harder to understand, but you need to do it to get the performance you need. Most of the the time refactoring improves performance in terms of speed as well, however at times its inverse could happen ie by extracting too many classes and introducing too many variable could have an impact of performance as well.

I want to reiterate that refactoring does not change the observable behavior of the software. The software still carries out the same function that it did before.

One thing at a time with TWO HATS ( Refactoring Vs Adding feature )

When you add function, you shouldn’t be changing existing code; you are just adding new capabilities. You can measure your progress by adding tests and getting the tests to work. When you refactor, you make a point of not adding function; you only restructure the code. You don’t add any tests (unless you find a case you missed earlier); you only restructure the code. You don’t add any tests (unless you find a case you missed earlier); you only change tests when you absolutely need to in order to cope with a change in an interface.

As you develop software, you probably find yourself swapping hats frequently. You start by trying to add a new function, and you realize this would be much easier if the code were structured differently. So you swap hats and refactor for a while. Once the code is better structured, you swap hats and add the new function. Once you get the new function working, you realize you coded it in a way that’s awkward to understand, so you swap hats again and refactor. All this might take only ten minutes, but during this time you should always be aware of which hat you’re wearing.

NOTE :

Please note that testing the while refactoring is very import. Always make small changes, test them commit them and make other changes. Do not thing to make all changes in a singe go and later on test entire application at the end. Multiple small cycles of refactor– test – refactor –test and smile Smile  is better then big refactoring – final testing – crying Sad smile

Interpreter Design Pattern

Download the working example demo code in java from my GIT repository –
https://github.com/premaseem/designPatterns/tree/master/ZipDownloadableProjects

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 :
https://drive.google.com/file/d/0B-9WtmpPhI4ZREEwNWpRYWVzSGM/view?usp=sharing

Intent
  • 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.

interpreter

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.

Discussion

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.

Example

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 –
https://github.com/premaseem/designPatterns/tree/master/ZipDownloadableProjects

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 :
https://drive.google.com/file/d/0B-9WtmpPhI4ZLV9rcFlmOXN2N0U/view?usp=sharing

memento1
Intent
  • 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.
Problem

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

Discussion

memento2

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.

momentoStructure

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 –https://github.com/premaseem/designPatterns/tree/master/ZipDownloadableProjects

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  ATCMediator.java 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 – Mediator.java
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 : https://drive.google.com/file/d/0B-9WtmpPhI4ZaU9rMnRIMjBTWFE/view?usp=sharing

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.

MediatorProblem

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.

Mediator

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 –https://github.com/premaseem/designPatterns/tree/4bb9beca7bab5b5e71d02b76e4f1ad48fce4aca6/ZipDownloadableProjects

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 : https://drive.google.com/file/d/0B-9WtmpPhI4ZYVNIc2hOcE5PSkU/edit?usp=sharing

Intent
  • 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.

Problem

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

Discussion

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.

Structure

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”.

Example

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.

Visitor Design Pattern

Download the working example demo code in java from my GIT repository -https://github.com/premaseem/designPatterns/tree/4bb9beca7bab5b5e71d02b76e4f1ad48fce4aca6/ZipDownloadableProjects

Example code description : This is an interesting example which includes a Party. So the Party class has music, drinks and food. For the preparation Party Host class accepts visitor cooks  (Veg cook and Non-Veg cook). So the combination could be of a week end party / a week day party in which you can have veg / non veg cooked food. Please download and run the program once. Without using  pattern if we put logic in “if else conditions” them it could had been messy and maintaining it could had been a night mare.Visitor patter is blessing in disguise of use cases like these.

visitor3
Intent
  • Represent an operation to be performed on the elements of an object structure. Visitor lets you define a new operation without changing the classes of the elements on which it operates.
  • The classic technique for recovering lost type information.
  • Do the right thing based on the type of two objects.
  • Double dispatch
Problem

Many distinct and unrelated operations need to be performed on node objects in a heterogeneous aggregate structure. You want to avoid “polluting” the node classes with these operations. And, you don’t want to have to query the type of each node and cast the pointer to the correct type before performing the desired operation.

public class Feeder {
    public void feed(Dog d) {
        d.eat();
    }
    public void feed(Cat c) {
        c.eat();
    }
}
 
Feeder feeder = new Feeder();
Object o = new Dog();
feeder.feed(o); // Cannot compile!
This issue is called double dispatch as it requires calling a method based on both instance and parameter types, which Java doesn’t handle natively. In order to make it compile, the following code is required:

if (o instanceof Dog) {
    feeder.feed((Dog) o);
} else if (o instanceof Cat) {
    feeder.feed((Cat) o);
} else {
    throw new RuntimeException(“Invalid type”);
}

 

This gets even more complex with more overloaded methods available – and exponentially so with more parameters. In maintenance phase, adding more overloaded methods requires reading the whole if stuff and updating it. Multiple parameters are implemented through embedded ifs, which is even worse regarding maintainability. The Visitor pattern is an elegant way to achieve the same, with no ifs, at the expense of a single method on the Animal class.

public interface Animal {
    void eat();
    void void accept(Visitor v);
}
 
public class Cat {
    public void eat() { … }
    public void accept(Visitor v) {
        v.visit(this);
    }
}
 
public class Dog {
    public void eat() { … }
    public accept(Visitor v) {
        v.visit(this);
    }
}
 
public class FeederVisitor {
    public void visit(Cat c) {
        new Feeder().feed(c);
    }
    public void visit(Dog d) {
        new Feeder().feed(d);
    }
}

Discussion

Visitor’s primary purpose is to abstract functionality that can be applied to an aggregate hierarchy of “element” objects. The approach encourages designing lightweight Element classes – because processing functionality is removed from their list of responsibilities. New functionality can easily be added to the original inheritance hierarchy by creating a new Visitor subclass.

The Visitor pattern makes adding new operations (or utilities) easy – simply add a new Visitor derived class. But, if the subclasses in the aggregate node hierarchy are not stable, keeping the Visitor subclasses in sync requires a prohibitive amount of effort.

An acknowledged objection to the Visitor pattern is that is represents a regression to functional decomposition – separate the algorithms from the data structures. While this is a legitimate interpretation, perhaps a better perspective/rationale is the goal of promoting non-traditional behavior to full object status.

visitor_taxi

Let us take an example of Taxi. You (Person – domain object ) wants to visit a new a place in city. Now you do not want to implement the driving logic in your domain object. So you can add accept visitor method object in which the Taxi object might contain and execute the logic for you .

 

Check list
  1. Confirm that the current hierarchy (known as the Element hierarchy) will be fairly stable and that the public interface of these classes is sufficient for the access the Visitor classes will require. If these conditions are not met, then the Visitor pattern is not a good match.
  2. Create a Visitor base class with a visit(ElementXxx) method for each Element derived type.
  3. Add an accept(Visitor) method to the Element hierarchy. The implementation in each Element derived class is always the same – accept( Visitor v ) { v.visit( this ); }. Because of cyclic dependencies, the declaration of the Element and Visitor classes will need to be interleaved.
  4. The Element hierarchy is coupled only to the Visitor base class, but the Visitor hierarchy is coupled to each Element derived class. If the stability of the Element hierarchy is low, and the stability of the Visitor hierarchy is high; consider swapping the ‘roles’ of the two hierarchies.
  5. Create a Visitor derived class for each “operation” to be performed on Element objects.visit() implementations will rely on the Element’s public interface.
  6. The client creates Visitor objects and passes each to Element objects by calling accept().
Rules of thumb
  • The Visitor pattern is like a more powerful Command pattern because the visitor may initiate whatever is appropriate for the kind of object it encounters.
  • The Visitor pattern is the classic technique for recovering lost type information without resorting to dynamic casts.

Visitor Vs Strategy

The strategy pattern is like a 1:many relationship. When there is one type of object and I want to apply multiple operations to it, I use the strategy pattern. I think of the visitor pattern as a many:many relationship.
A Visitor is like an extended Strategy that is polymorphic at two dimensions: the code executed doesn’t only depend on the actual strategy used, but also on the parameter passed to it.
Strategy, State, Command, Visitor (and more I’m sure) all have some behavior built into an object that we can pass around, so they all have a very similar feeling when you’re building the object. Their “intent” is subtly different and yet sometimes overlapping.
Visitor is often (but not always) a way to add new functionality to an existing object graph. The example I learned on is an HTML parser that builds a DOM of objects on an HTML page and invites me to add functionality via visitors.