Monday, 9 February 2015

Adapter and Facade Design Patterns in Java

Background

Some time back we saw Decorator design pattern which was the 1st Structural design pattern that we tried to understand. Adapter and Facade are two more design pattern that come under same category - Structural Design pattern.

Adapter Design Pattern

Adapter pattern converts one interface to another interface that is expected by the target or client system. It simply make interfaces compatible so that integration is possible. To visualize see following diagram


Target or client expects an interface where as interface that is going to use it provides different interface and none of them can be modified. In such cases Adapter proves to be beneficial.

Lets take an example -

Lets say you have designed a program that computes cost of a list of items supplied to it. In your computeCost() method you expect that customer would provide Iterator instance. You write code something like below -

import java.util.Iterator;


public class CostComputer {
    
    public static int computeCost(Iterator<Product> iterator)
    {
        int cost = 0;
        while(iterator.hasNext())
        {
            cost = cost + iterator.next().getCost();
        }
        return cost;
    }
    
}


Also you have exposed a Product interface. Those who want to compute cost should have models extending this Product interface implement it's getCost() method and then can pass the iterator of it to above utility method.

public interface Product {
    int getCost();
}



Now here's something you did not expect.  You get a Toy manufacturing company as your client and their code is something like -

public class Toy implements Product {

    int cost;
    
    public Toy(int cost)
    {
        this.cost = cost;
    }
    
    @Override
    public int getCost() {
        return cost;
    }

}


and

import java.util.Enumeration;
import java.util.Random;
import java.util.Vector;


public class ToysCreator {
    
    int count;
    
    public ToysCreator(int count)
    {
        this.count = count;
    }
    
    public Enumeration createToys()
    {
        Vector toys = new Vector<>();
        for(int i=0; i<count ;i++)
        {
            toys.add(new Toy(new Random().nextInt(10)));
        }
        return toys.elements();
    }

}


and then they tried to use your code as follows -

public class ToysCostComputer {
    
    public static void main(String args[])
    {
        System.out.println(CostComputer.computeCost(new ToysCreator(6).createToys())); // this will fail
    }

}


and viola -

Exception in thread "main" java.lang.Error: Unresolved compilation problem:
    The method computeCost(Iterator<Product>) in the type CostComputer is not applicable for the arguments (Enumeration)

    at ToysCostComputer.main(ToysCostComputer.java:6)

Program crashed. Your code expected a Iterator but customer code returns Enumeration. Now you or your customer have to build Adapter to support Enumeration.

It goes as follows -

import java.util.Enumeration;
import java.util.Iterator;


public class EnumToIteratorAdapter implements Iterator<Product> {

    Enumeration<Product> enumeration;
    
    public EnumToIteratorAdapter(Enumeration<Product> enumeration)
    {
        this.enumeration = enumeration;
    }
    
    @Override
    public boolean hasNext() {
        return enumeration.hasMoreElements();
    }

    @Override
    public Product next() {
        return enumeration.nextElement();
    }

    @Override
    public void remove() {
        throw new UnsupportedOperationException();
        
    }

}


and now client can use our code with the help of Adapter

import java.util.Iterator;


public class ToysCostComputer {
    
    public static void main(String args[])
    {
        Iterator toysIterator = new EnumToIteratorAdapter(new ToysCreator(6).createToys());
        System.out.println(CostComputer.computeCost(toysIterator));
    }

}


and the output is - 27. Some random number but you get the point.

Class Diagram for our above demo is as follows -



Generic Class diagram for Adapter Pattern is as follows -



That was Adapter Pattern. Now lets come to facade pattern.

so in facade pattern Adapter implements target and has an instance of Adaptee. So whenever methods of target are called we call suitable methods of adaptee.

Facade Pattern.

Facade Pattern is kind of an overlay. It provides a unified interface to set of interfaces in the sub system. Note that we cannot say it encapsulates methods of sub system classes as methods of sub system classes are still available for direct use. Facade pattern just simplifies it by abstraction.

There is no fixed generic class diagram as such but it will look like -


Lets say you have multiple modules for handling program bugs. May be
  1. class BugCreator that creates various types of bugs - UI, functional, localization etc. 
    • Methods : createBug(String bugType) etc
  2. class BugsReplicator that tries replicates the bug as per the description of filed bug.
    • Methods :  replicateBug(Bug newBug) etc
  3. class BugsSolver that finds the fix and checks in the code.
    • Methods : fixBug(Bug newBug) etc
  4. class BugsDeployer that deploys the fix to dev or qa environments.
    • Methods : deployFix(CodeFix fix) etc
  5. class BugsTester that tests out the fix
    • Methods : testFix(Bug bug) etc
Now lets say your customer uses these classes or subsystems to handle their code bugs. They will have to call each method and do handling on their own. Instead you can provide them with a simplified facade.

public boolean resolveBug(String desc, String bugType)
{
      Bug newBug =  new BugCreator().createBug(bugType);
      boolean replicated = new BugsReplicator .replicateBug(newBug);
      if(replicated)
      {
          CodeFix fix = new BugsSolver().fixBug(newBug);
          new BugsDeployer().deployFix(fix);
          if(new BugsTester.testFix(Bug bug))
          {
              return true;
          }
          else
          {
              return false;
          }
      }
      else
      {
          return false;
      }
}


Now this is just an example that I am giving to help you understand how Facade pattern simplifies subsystem complexity. 


Notes

  • Facade does not encapsulate subsystem classes. It simply provides simplified interface to complex subsystem classes. Subsystem classes are still accessible for direct use.

Summary

  • Decorator pattern does not alter any interface. It simply adds responsibility.
  • Adapter pattern Converts one interface (Adaptee) to another (Target) for compatibility.
  • Facade pattern simplifies interface for complex subsystem subclasses.

Related Links

Saturday, 7 February 2015

String processing using Matcher, Pattern and Regex in Java

Background

Using regex or simply regular expressions have been very important part of String processing. We will explore it is this post.


Before you get to Java code lets take a looks at Regex symbols - 

Regex Symbols

Common Regex Symbols : 

Common Regex Meta Symbols : 


Common Regex Quantifier Symbols : 

Now lets head on to Java Code....

Using java.util.regex.Pattern and java.util.regex.Matcher classes

Lets use these classes to demonstrate regex.

    public static void main(String args[])
    {
        String str = "Hi there! My name is John. How can I help you?";
        Pattern p = Pattern.compile("[.!?]");
        Matcher matcher = p.matcher(str);
        int count = 0;
        while(matcher.find()) {
            count++;
        }
        System.out.println("Count : " + count);

    }

and the output is - 3. Lets see what we did here. We have a String - "Hi there! My name is John. How can I help you?"  and we are interested in finding number of times symbol '.', '!' or '?' appears in the String. So we provided the regex "[.!?]". 

Did not quite get the regex part? Go back to previous section - Regex symbols. Notice in Common Regex symbols image [xyz] represent x or y or z. We are simply incrementing the counter if we find such a regex meaning '.', '!' or '?' '.

Lets head on to something more interesting. How many time have you used String classes split() method? Did you realize that it is infact a regex that split method takes. We split words from line as follows -

    public static void main(String args[])
    {
        String str = "Hello all. Welcome to Open Source For Geeks!";
        String[] tokens = str.split(" ");
        for(String token : tokens)
        {
            System.out.println(token);
        }

    }


and you get output as -

Hello
all.
Welcome
to
Open
Source
For
Geeks!


as expected.  If you see the split method code it internally used java.util.regex.Pattern to compile you regex and use it to split the String -

    public String[] split(String regex, int limit) {
    return Pattern.compile(regex).split(this, limit);
    }


Now lets do the same thing as split using Patter and Matcher.

    public static void main(String args[])
    {
        String str = "Hello all. Welcome to Open Source For Geeks!";
        Pattern pattern= Pattern.compile("\\w+");
        Matcher matcher = pattern.matcher(str);
        while(matcher.find()) {
            System.out.println(matcher.group());
        }

    }


and the output is -

Hello
all
Welcome
to
Open
Source
For
Geeks


Noticed any difference? '.'(dot) and '!'(exclamation) are not present. Well that is expected. See Regex symbols again. We used "\\w+"  which means match one or more word character and dot and exclamation aren't one of them.

Note : Space is also not a word character. Else we would have got whole String as matched pattern (leaving dot and exclamation mark aside). Digits are also part of word characters i.e \\w+ .

 So lets slightly modify our code to get the same output.

    public static void main(String args[])
    {
        String str = "Hello all. Welcome to Open Source For Geeks!";
        Pattern pattern= Pattern.compile("\\w+\\.*!*");
        Matcher matcher = pattern.matcher(str);
        while(matcher.find()) {
            System.out.println(matcher.group());
        }

    }


and the output is -

Hello
all.
Welcome
to
Open
Source
For
Geeks!


Ok that's the same. What did we do here? Notice the regex again. This time it is - "\\w+\\.*!*". We are saying get me sequence that matches [(one or more word characters) then (zero or more dot symbols) then (zero or more exclamation symbols)].

Note :  Dot is a regex symbol and hence you need to escape (like we did \\. ) it if you want to use it for searching dot pattern. Exclamation on the other hand was not so we could directly use it.


Another Example


Lets  do something practical now. Lets say you have following data (maybe in a file or just an array) -

data1=${key1}
data2=${key2}
data3=${key3}

and you have to replace the placeholder with the actual value whose mapping you have (again maybe in a different file).

key1 -> ActualKey1
key2 -> ActualKey2
key3 -> ActualKey3

and finally you want output like -

data1=ActualKey1
data2=ActualKey2
data3=ActualKey3

Lets write code to achieve this using regex.

    public static void main(String args[])

    {

        String[] replacableData = new String[]{"data1=${key1}","data2=${key2}","data3=${key3}"};

        Map<String, String> keyMappings = new HashMap<String, String>();

        keyMappings.put("key1", "ActualKey1");

        keyMappings.put("key2", "ActualKey2");

        keyMappings.put("key3", "ActualKey3");

        Pattern pattern= Pattern.compile("(\\w+=)(\\$\\{)(\\w+)(\\})");

        for(String str : replacableData) {

            Matcher matcher = pattern.matcher(str);

            String key = matcher.replaceAll("$3");

            System.out.println("Key : " + key);

            String newStr = matcher.replaceAll("$1"+ keyMappings.get(key));

            System.out.println("After Replacement : " + newStr);

        }

    }


and the output is -

Key : key1
After Replacement : data1=ActualKey1
Key : key2
After Replacement : data2=ActualKey2
Key : key3
After Replacement : data3=ActualKey3


Another important concept to note here is the groups in the rgex that you can refer later with $groupIndex.

In our regex - "(\\w+=)(\\$\\{)(\\w+)(\\})"

group1 -> (\\w+=)
group2 -> (\\$\\{)
group3 -> (\\w+)
group4 -> (\\})
  Also replaceAll() replaces the entire original String with whatever group combinations you provide. For example matcher.replaceAll("$1$2$3$4") will give you back the same String.

Note : replaceAll() method return a new String. original String is not changed.

Note :  Even used replace() and replaceAll() method of String class?  Both of them replace all occurences with the String you desire. Only difference is replaceAll() uses a regex where as replace() uses simple CharSequence.

Friday, 6 February 2015

Difference between Dalvik and ART runtimes in Android

Background

If you own an Andorid device with Kitkat you would already know this. You have an option of choosing between the runtimes - 
  • Dalvik
  • ART

What is runtime you ask? -  Think of it as a library that takes care of converting the code that you write in a high level language like Java to machine code that the processor/cpu will understand. Android uses virtual machine as it's runtime (like JVM) which makes it "write once run everywhere".


From Android L (5.0) ART has been made as the default runtime (ART has completely replaced Dalvik).

For my device running Kitakat it looks like the following -




The goal of this post is to understand these runtimes so that you can choose the appropriate one (in Android kitkat). Before proceeding to the details I would recommend read more about JIT (Just in time) compilation. You can see the JIT section in my following post -


 History

Lets step back a little and see how did we reached to ART. We all know Dalvik was used as the virtual machine. In it's simple form consider Dalvik as JVM optimized for mobile platforms. Later from Android 2.2 (Froyo) JIT compiler was launched (which Dalvik used) to further optimize and improve applications performance. JIT allows code to be directly compiled to native code (unlike interpreting it every time) and use the same thereafter. JIT did these only for so called "identified hotspots" (typically code snippets getting executed very frequently). So still major code was interpreted and need was felt to further optimize and improve performance of Android application and hence from Android 4.4 (kitkat) ART was introduced as a runtime and from Android 5.0 (Lollipop) it has completely replaced Dalvik. 

Android Architecture with ART looks like -


So Dalvik used JIT(Just in time) compilation where as ART uses AOT (Ahead of time) compilation. Lets see what that is.

 AOT (Ahead of time) Compilation and ART

We all know android apps come in .apk format. You essentially write you code in Java (.java classes) which are bundled in apk files. While application gets bundles your java classes are converted to bytecodes (.dex) files. This is common for both Dalvik as well as ART. Difference is what comes next.

In JIT/Dalvik every time an application is launched byte code is interpreted line by line. If a routine or function is identified as hotspot it is directly compiled to native code by JIT with optimization. This leads to time and memory footprint overhead as this is done on the fly when application is running. The JIT compiled code is then run directly everytime thereafter (no interpretation needed) which increases the performance.

In AOT/ART when application (.apk) file is installed entire byte code is converted to machine code and stored in the persistent storage. As this is on installation this happens only once. Every time the application is launched this machine code is directly executed. No need of interpreter. yes it takes more storage space as compiled native code is stored in the storage but takes less CPU and less RAM (memory footprint).

As per Wiki,

To maintain backward compatibility, ART uses the same input bytecode as Dalvik, supplied through standard .dex files as part of APK files, while the .odex files are replaced with Executable and Linkable Format (ELF) executables. Once an application is compiled by using ART's on-device dex2oat utility, it is run solely from the compiled ELF executable; this approach eliminates various overheads involved with JIT compilation, but it requires additional time for compilation when an application is installed, and applications take up slightly larger amounts of space to store the compiled code


Following diagram should clear everything I just explained above - 


Benefits of ART

  • Reduces startup time of applications as native code is directly executed.
  • Improves battery performance as power utilized to interprete byte codes line by line is saved.
  • As JIT is not in the picture no on the fly compilation and native code storage. This significantly reduces memory footprint (less RAM is required for application to run).

Drawbacks of ART

  • As dex bytecodes are converted to native machine code on installation itself, installation takes more time.
  • As the native machine code generated on installation is stored in internal storage, more internal storage is required.

Related Links

Wednesday, 4 February 2015

The Decorator pattern design pattern

Background

This pattern employes a very important OO design principle -
  • Classes should be open for extension but closed for modification.
This design pattern allows new functionality to be added to an existing Object without modifying it's structure.  Also this is the 1st structural design pattern that we are taking a look at. If you remember there are 3 types of design patterns -

  1. Creational
  2. Structural
  3. Behavioral

Lets take an example to understand this better. Lets say you have opened a Pizza shop and you offer various types of Pizzas.



You then created classes for each type of Pizza. Now that you are very well versed with following design principle -
  • Code for interface and not implementation
you would probably create an interface Pizza and then make concrete class like PaneerPizza, ChickenPizza by implementing Pizza interface. But now lets say your business grows and you offer various types of toppings like extra cheese or mushrooms or spicy chicken or corn. For this you will have to now either create new concrete Pizzas or alter existing code. But this is not practical as every time you decide to offer or remove a new topping you code will change (Think of each Pizza having a getCost() method which will differ with toppings). This is where Decorator pattern comes to the rescue.


Generic Class Diagram



Source : Wiki


To the Code....

Lets first create an interface - Pizza

public interface Pizza {
    int getCost();
}

Now lets create concrete classes for Pizza - 

public class PaneerPizza implements Pizza {

    @Override
    public int getCost() {
        return 3;
    }

}

and

public class ChickenPizza implements Pizza {

    @Override
    public int getCost() {
        return 5;
    }

}

And now lets create decorator class. Remember decorator class will implement Component and will also have an instance of Component in it. Also the operation method which is this case is getCost() will be abstract.

public abstract class PizzaDecorator implements Pizza {

    

    Pizza pizza;



    public abstract int getCost();



}

and now lets create concrete classes for Toppings which will extend PizzaDecorato.

public class MushroomToppings extends PizzaDecorator {

    public MushroomToppings(Pizza pizza) {
        this.pizza = pizza;
    }
    
    @Override
    public int getCost() {
        return 2 + pizza.getCost();
    }

}

and

public class CornTopping extends PizzaDecorator {

    public CornTopping(Pizza pizza) {
        this.pizza = pizza;
    }
    
    @Override
    public int getCost() {
        return 1 + pizza.getCost();
    }

}

and  that's all with the model classes. Now lets simulate it and see,

/**
 * @author athakur
 */
public class PizzaSimulation {
    
    public static void main(String args[])
    {
        Pizza pizza = new ChickenPizza();
        System.out.println("Pizza cost : " + pizza.getCost());
        
        Pizza pizzaWithCornToppings = new CornTopping(pizza);
        System.out.println("Pizza cost : " + pizzaWithCornToppings.getCost());
        
        Pizza pizzaWithCornAndMushroomToppings = new MushroomToppings(pizzaWithCornToppings);
        System.out.println("Pizza cost : " + pizzaWithCornAndMushroomToppings.getCost());
        
    }
}



And the output is -

Pizza cost : 5
Pizza cost : 6
Pizza cost : 8


Now go back to each Pizza and Topping class and verify the output. It's pretty straight forward. See how we could dynamically add toppings and compute total cost without actually modifying the original class? That the power of Adapter patter.


NOTE : In decorator pattern decorator implements the component and also composes the component.
NOTE : In adapter pattern adapter implements the target and composes the adaptee.

Class Diagram for Above Pizza Store Code

Related Links


Summary

  • Decorator pattern does not alter any interface. It simply adds responsibility.
  • Adapter pattern Converts one interface (Adaptee) to another (Target) for compatibility.
  • Facade pattern simplifies interface for complex subsystem subclasses.

Sunday, 1 February 2015

The Observer Design Pattern

Background

Ever subscribed to a blog, news or a RSS feed? If not you should definitely try it out. It saves time of scanning through the whole content to find posts of your interest especially in this information technology times when there is so much data flowing on the internet. Anyway lets see how this works as it would be crucial in understanding the design pattern that we are going to discuss today -  The Observer Design Pattern.


How Observer Pattern Works?

Lets say we have a new website - www.worldNews.com that provides information of events going on in the entire glob. You on the other hand are Cricket fan and really would like to get all updates of cricket matches all over the globe.



One crude way would be go to the sites sports section and check out cricket events like twice a day or more? But if the site provides an RSS feed for cricket news you can simply subscribe to it and whenever news site publishes something about cricket you will directly get the news feed.   




In The Observer Design Pattern world 'Cricket' is the subject and you are the observer. As an observer you register yourself to the Subject and whenever Subject's state gets updated all the registered observers (including you) get notified. You can also de-register yourself from the update.


Lets write a code in Java for above to get a better understanding of Observer pattern. For the record Java provides an in built support for Observer pattern but we will look at it in some time. For now lets do it from very basics.

Definition

Definition for Observer Design pattern as per Wiki is -

The observer pattern is a software design pattern in which an object, called the subject, maintains a list of its dependents, called observers, and notifies them automatically of any state changes, usually by calling one of their methods. It is mainly used to implement distributed event handling systems.

Generic Class Diagram



"Observer" by WikiSolved - Own work. Licensed under Public Domain via Wikimedia Commons.

To the code.....

Lets first create our interfaces and model classes - 

Lets first create Subject interface. Later we will create Cricket subject that implements Subject interface. We write interface so that tomorrow we can add  more subjects like finance, political new etc. For this demo we will just see cricket event.

public interface Subject {
    public void registerObserver(Observer observer);
    public void deregisterObserver(Observer observer);
    public void notifyObservers(Event event);
    public void onNewEvent(Event event);
}

Notice how Subject interface has following three methods - 

  1. registerObserver - Each observer will call this method on the Subject he is interested in and will get registered.
  2. deregisterObserver - Observer may choose to de register from getting updates on a subject. I such cases Observer will call this method.
  3. notifyObservers - Whenever subjects state will change this method will be invoked which will push the updated data to the observers who have registered to that subject.
  4. onNewEvent - This method is called whenever new Event is generated. When this happens all we have to do is call notifyObservers.
 Now lets create our Observer interface -

public interface Observer {
    
    public void update(Event event);

}


Notice observer interface has just one method -
  1. update - This method will be invoked on every registered observer by the corresponding subject

Finally lets create an Event interface  . This is just a interface with no methods in it. Each actual event like CricketEvent in our example will implement this interface. Other Events could be FinanceEvent, PoliticsEvent etc

public interface Event {

}

Very important point to note here - Why are we creating interfaces and not direct concrete implementation?

Remember the OO design principles mentioned in Introduction to Design Patterns 

  • Code for interface not implementation
And the reason is quite simple. If you code for concrete implementation then you have to change base code every time new entity is added.


Lets move on to our concrete classes implementations now.

First Lets write our CricketEvent -

public class CricketEvent implements Event {
    

    String team1;
    String team2;
    String matchLocation;
    String matchDate;

    

    public CricketEvent(String team1, String team2, String matchLocation, String matchDate) {
        this.team1 = team1;
        this.team2 = team2;
        this.matchLocation = matchLocation;
        this.matchDate = matchDate;
    }


    @Override
    public String toString() {
        return "CricketEvent [team1=" + team1 + ", team2=" + team2
                + ", matchLocation=" + matchLocation + ", matchDate="
                + matchDate + "]";
    }
    

}


Simple Cricket Event class with some attribute.

Next lets implement our Subject - CricketSubject.

public class CricketSubject implements Subject {

    

    List<Observer> registeredObservers;

    

    public CricketSubject() {
        registeredObservers = new ArrayList<>();
    }

    @Override
    public void registerObserver(Observer observer) {
        registeredObservers.add(observer);
        
    }

    @Override
    public void deregisterObserver(Observer observer) {
        registeredObservers.remove(observer);
        
    }

    @Override
    public void notifyObservers(Event event) {
        for(Observer observer : registeredObservers) {
            observer.update(event);
        }
    }

   

    @Override
    public void onNewEvent(Event CricketEvent) {
        notifyObservers(CricketEvent);
    }

}


We are using a simple ArrayList to keep track of registered Observers. Whenever new Cricket is generated onNewCricketEvent method is called (you don't have to worry about this. All you have to know is whenever cricket event is generated this will be called.) then we call notifyObservers to notify all observers.

Lets now create class for CricketEventObserver -

public class CricketEventObserver implements Observer {
    
    public CricketEventObserver(Subject subject) {
        subject.registerObserver(this);
    }

    @Override
    public void update(Event event) {
        CricketEvent crickEvent = (CricketEvent) event;
        System.out.println("Received Cricket Event : " + crickEvent);
    }

}


Notice in constructor it takes an Observer reference and registers itself to it. Now lets simulate and see the working -

public class ObserverSimulation {

    public static void main(String args[]) {
       
        Subject cricketSubject = new CricketSubject();
        Observer cricketEventObserver1 = new CricketEventObserver(cricketSubject);
        Observer cricketEventObserver2 = new CricketEventObserver(cricketSubject);
       
        System.out.println("Generating Cricket Event");
        cricketSubject.onNewEvent(new CricketEvent("India", "Aus", "Melbourne Cricket Ground", "01/02/2015"));
        System.out.println("--------------------------");
        System.out.println("De registerting cricket observer 2");
        cricketSubject.deregisterObserver(cricketEventObserver2);
        System.out.println("--------------------------");
        System.out.println("Generating Cricket Event");
        cricketSubject.onNewEvent(new CricketEvent("India", "England", "Eden Gardens", "03/02/2015"));
        System.out.println("--------------------------");
    }
    
}



and the output is -

Generating Cricket Event
Received Cricket Event : CricketEvent [team1=India, team2=Aus, matchLocation=Melbourne Cricket Ground, matchDate=01/02/2015]
Received Cricket Event : CricketEvent [team1=India, team2=Aus, matchLocation=Melbourne Cricket Ground, matchDate=01/02/2015]
--------------------------
De registerting cricket observer 2
--------------------------
Generating Cricket Event
Received Cricket Event : CricketEvent [team1=India, team2=England, matchLocation=Eden Gardens, matchDate=03/02/2015]
--------------------------


as expected.

Class diagram for above Design is -




Java built in support for Observer pattern

Java provided built in support for Observer pattern with following two entities -
  1. class java.util.Observable
  2. interface java.util.Observer

Observable is a class and have methods like addObserver(), deleteObserver() etc where as Observer is an interface with method update() which Observable instance calls while notifying.

Note :
  • Before calling notifyObservers() you need to call setChanged() to mark the state changed. if you miss this notifyObservers() method will just return without notifying the observers.
  •  Also all methods in Observable class are synchronized which makes it's instances thread safe.

Observer pattern used in JDK

This pattern is used extensively in Swing.
javax.swing.AbstractButton class is the Subject and has concrete implementations like javax.swing.JButton. Observer is java.awt.event.ActionListener interface and you can create instances of it and register to JButton to receive Events update.

For example - 

    public static void main(String args[]) {

        JButton button = new JButton();
        button.addActionListener(new ActionListener() {
            @Override
            public void actionPerformed(ActionEvent e) {
                System.out.println("Observer 1 : Action Event recived from JButton Subject");
                
            }
        });
        button.addActionListener(new ActionListener() {
            @Override
            public void actionPerformed(ActionEvent e) {
                System.out.println("Observer 2 : Action Event recived from JButton Subject");
                
            }
        });
        
    }

Above code registers two concrete implementations of ActionListener interface with Subject JButton and whenever any action is triggered on the button these listeners will be notified.

Related Links



t> UA-39527780-1 back to top