Showing posts with label pattern. Show all posts
Showing posts with label pattern. Show all posts

Saturday, October 13, 2012

Understanding Dependency Inversion in real life


Hi there! Today i wanna share a real life example of dependency Inversion with you. In my RCP-Client developer career we had often the challange that due some customer change requests, we were forced to instantiate some domain specific dialogs from base. The problem here is that base (package: com.yourcompany.base) is not allowed to create dependencies to domain specific packages. So how could we solve this problem? We must inverse the dependency. What do we need? We will create a dependency registry in which we register domain specific dialog factories to be able to instantiate them from the base without having to create dependencies from base to specific domain packages.

The common factory interface

We define a factory interface in base. Let's say package is called: com.yourCompany.base.



interface DialogFactory{
    Dialog createFilterDialog();
}

In the same package we define an interface for the depencency inversion of our registry later:

// then we define also in base the interface for DependencyInversion in general. 
// to be used by all Registries we need in future. package: com.yourCompany.base
public interface DependencyInversion<T> {

    void registerFactory(String factoryMapKey, T factory);

    void unregisterFactory(String factoryMapKey);

    T getRegisteredFactoryOrNull(String factoryMapKey);
}

Now we need a Dependency Inversion Helper, which will handle the factory map later:


import java.util.HashMap;
import java.util.Map;

// for the same general reason, we define a dependency inversion helper which
// handle with the factoryMaps for any kind of factory in future. This class is
// also placed in base package: com.yourCompany.base
public class DependencyInversionHelper<T> {

    private Map<String, T> factoryMap = new HashMap<String, T>();

    public void unregisterIfExistsInMap(String factoryMapKey) {
        if (doesFactoryExistInMap(factoryMapKey)) {
            removeFactoryFromMap(factoryMapKey);
        }
    }

    public void registerIfNotExistsInMap(String factoryMapKey, T factory) {
        if (!doesFactoryExistInMap(factoryMapKey)) {
            insertFactoryIntoMap(factoryMapKey, factory);
        }
    }

    public boolean doesFactoryExistInMap(String factoryMapKey) {
        return this.factoryMap.containsKey(factoryMapKey);
    }

    public void insertFactoryIntoMap(String factoryMapKey, T factory) {
        this.factoryMap.put(factoryMapKey, factory);
    }

    public void removeFactoryFromMap(String factoryMapKey) {
        this.factoryMap.remove(factoryMapKey);
    }

    public T getRegisteredFactoryOrNull(String factoryMapKey) {
        return (T) (doesFactoryExistInMap(factoryMapKey) ? this.factoryMap.get(factoryMapKey) : null);
    }

}

The Registry

And finally we define in the same package our registry, which uses the helper and implements DependencyInversion:


// Now every thing we need to implement is the registry itself. This will be a singleton because
// we just need it once in the whole application. We place it also in base: com.yourCompany.base 
public class FilterDialogDependencyInversionRegistry implements DependencyInversion<DialogFactory> {

    private static FilterDialogDependencyInversionRegistry instance = new FilterDialogDependencyInversionRegistry();
    private DependencyInversionHelper<DialogFactory> helper = new DependencyInversionHelper<DialogFactory>();

    private FilterDialogDependencyInversionRegistry() {
        // singleton: we just need one global registry for it.
    }

    public static FilterDialogDependencyInversionRegistry instance() {
        return instance;
    }

    @Override
    public void registerFactory(String factoryMapKey, DialogFactory factory) {
        helper.registerIfNotExistsInMap(factoryMapKey, factory);
    }

    @Override
    public void unregisterFactory(String factoryMapKey) {
        helper.unregisterIfExistsInMap(factoryMapKey);
    }

    @Override
    public DialogFactory getRegisteredFactoryOrNull(String factoryMapKey) {
        return helper.getRegisteredFactoryOrNull(factoryMapKey);
    }

}

Ready for implementation:

Now we are able to register all factories we need with this registry. Because this registry is visible in base and in any other domain specific package, we can access our new Registry from anywhere and get the factory we need for any factoryMapKey we define. In Eclipse RCP this is usually done in the method  start() from the application. when the method getRegisteredFactoryOrNull(key) is called, we get a  DialogFactory and are able now to call the method createFilterDialog() from it. What it happens now is very cool. Any interface knows its implementation and creates the right dialog without having dependencies to the base modul. Any domain specific factory must only implement DialogFactory. That's all.

😱👇 PROMOTIONAL DISCOUNT: BOOKS AND IPODS PRO ðŸ˜±ðŸ‘‡

Be sure to read, it will change your life!
Show your work by Austin Kleonhttps://amzn.to/34NVmwx

This book is a must read - it will put you in another level! (Expert)
Agile Software Development, Principles, Patterns, and Practiceshttps://amzn.to/30WQSm2

Write cleaner code and stand out!
Clean Code - A Handbook of Agile Software Craftsmanship: https://amzn.to/33RvaSv

This book is very practical, straightforward and to the point! Worth every penny!
Kotlin for Android App Development (Developer's Library): https://amzn.to/33VZ6gp

Needless to say, these are top right?

😱👆 PROMOTIONAL DISCOUNT: BOOKS AND IPODS PRO ðŸ˜±ðŸ‘†

Understanding Callbacks with Java - Inversion of control

Callback Pattern in Java Environment


Hi there! today i wanna share something with you, that it is very common and widely used in javascript for example. I'm speaking of callbacks. Do you know how and when this "pattern" is used? Do you really understand it in a java context (environment)? Well i was asking me also some of those questions and that's the reason i started to learn more about it. The ideia behind it is the inversion of control (abbreviated IoC). This paradigma describes the way frameworks work. It is also known as the "Hollywood principle - Don't call me, we will call you"

Simplified Callback pattern in Java just to understand it. Concrete example follows bellow.




interface CallBack {
    void methodToCallBack();
}

class CallBackImpl implements CallBack {
    public void methodToCallBack() {
        System.out.println("I've been called back");
    }
}

class Caller {

    public void register(CallBack callback) {
        callback.methodToCallBack();
    }

    public static void main(String[] args) {
        Caller caller = new Caller();
        CallBack callBack = new CallBackImpl();
        caller.register(callBack);
    }
} 

Ok you may be asking you, when this usefull or may be asking you what's the difference between calling directly callback.methodToCallBack() right?

ANSWER: well, this example just shows to you how to construct such a callBack function when working in a java environment. Certainlly it doesn't make it any sense to use it that way. Let's get a little deeper into a concrete useful example now.

The idea behind it is the "INVERSION OF CONTROL". Let's take a timer as a realistic example. Let's supose that you know, that a specific timer supports callback functions every hour. Exactly it means, that every hour, the timer will call your registed call method function.

Conctrete Example:

Let's say we wanna update the time of a website every hour. Here is the UML of the following example:


Callback Interface

Let's define first the callback interface:


import java.util.ArrayList;
import java.util.List;

// For example: Let's assume that this interface is offered from your OS to be implemented
interface TimeUpdaterCallBack {
    void updateTime(long time);
}

// this is your implementation.
// for example: You want to update your website time every hour
class WebSiteTimeUpdaterCallBack implements TimeUpdaterCallBack {

    @Override
    public void updateTime(long time) {
        // print the updated time anywhere in your website's example
        System.out.println(time);
    }
}

The SystemTimer that supports Callback functions in our example:



// This is the SystemTimer implemented by your Operating System (OS)
// You don't know how this timer was implemented. This example just
// show to you how it could looks like. How you could implement a
// callback by yourself if you want to.
class SystemTimer {

    List<TimeUpdaterCallBack> callbacks = new ArrayList<TimeUpdaterCallBack>();

    public void registerCallBackForUpdatesEveryHour(TimeUpdaterCallBack timerCallBack) {
        callbacks.add(timerCallBack);
    }

    // ... This SystemTimer may have more logic here we don't know ...

    // At some point of the implementaion of this SystemTimer (you don't know)
    // this method will be called and every registered timerCallBack
    // will be called. Every registered timerCallBack may have a totally
    // different implementation of the method updateTime() and my be
    // used in different ways by different clients.
    public void oneHourHasBeenExprired() {

        for (TimeUpdaterCallBack timerCallBack : callbacks) {
            timerCallBack.updateTime(System.currentTimeMillis());
        }
    }
}

And finally our WebSiteTimeUpdater which is our client in this fictive and simple example:



// This is our client. It will be used in our WebSite example. It shall update
// the website's time every hour.
class WebSiteTimeUpdater {

    public static void main(String[] args) {
        SystemTimer SystemTimer = new SystemTimer();
        TimeUpdaterCallBack webSiteCallBackUpdater = new WebSiteTimeUpdaterCallBack();
        SystemTimer.registerCallBackForUpdatesEveryHour(webSiteCallBackUpdater);
    }
}

😱👇 PROMOTIONAL DISCOUNT: BOOKS AND IPODS PRO 😱👇

Be sure to read, it will change your life!
Show your work by Austin Kleon: https://amzn.to/34NVmwx

This book is a must read - it will put you in another level! (Expert)
Agile Software Development, Principles, Patterns, and Practices: https://amzn.to/30WQSm2

Write cleaner code and stand out!
Clean Code - A Handbook of Agile Software Craftsmanship: https://amzn.to/33RvaSv

This book is very practical, straightforward and to the point! Worth every penny!
Kotlin for Android App Development (Developer's Library): https://amzn.to/33VZ6gp

Needless to say, these are top right?

😱👆 PROMOTIONAL DISCOUNT: BOOKS AND IPODS PRO 😱👆

Monday, March 5, 2012

How to write a singleton? (pros and contras)

A singleton for each situation and the pros and contras of it?


Lazy synchronized initialization

public final class Session 
  {
      private static Session instance;
 
      /** singleton */
      private Session() {}
 
      /** if you do not need synchronisation do not mark it as synchronized */
      public synchronized static Session getInstance() 
      {
          return (instance == null) ? instance = new Session() : instance;
      }
      /** your methods goes here... */
   }


PRO: can be initialized lazy the first time it is used
CONTRA: Singletons shall be avoid because they are hard to test and debug. Futher they contribute to less cohesive designs.


No Lazy initialization needed

public class Session 
  {
    private final static Session INSTANCE = new Session();

    private Session() {}

    public static Session getInstance() 
    { 
      return Session.INSTANCE; 
    }

    protected Object clone() 
    {
      throw new CloneNotSupportedException();
    }

    /** your methods goes here... */
  }

PRO: Immediate allocation of the needed resource
CONTRA: Needs "more" resource as nescessary + CONTRA from first case


No Lazy initialization needed (the elegant, modern way)

public enum Session 
   {
       INSTANCE;
       private int session;

       public int getSession() {
           return ++session;
       }

       /** your methods goes here... */
   }


PRO: Very simple, modern way. Immediate allocation of the needed resource
CONTRA: Needs "more" resource as nescessary + CONTRA from first case



😱👇 PROMOTIONAL DISCOUNT: BOOKS AND IPODS PRO ðŸ˜±ðŸ‘‡

Be sure to read, it will change your life!
Show your work by Austin Kleonhttps://amzn.to/34NVmwx

This book is a must read - it will put you in another level! (Expert)
Agile Software Development, Principles, Patterns, and Practiceshttps://amzn.to/30WQSm2

Write cleaner code and stand out!
Clean Code - A Handbook of Agile Software Craftsmanship: https://amzn.to/33RvaSv

This book is very practical, straightforward and to the point! Worth every penny!
Kotlin for Android App Development (Developer's Library): https://amzn.to/33VZ6gp

Needless to say, these are top right?

😱👆 PROMOTIONAL DISCOUNT: BOOKS AND IPODS PRO ðŸ˜±ðŸ‘†

Wednesday, February 29, 2012

How to eliminate If-Statements and InstanceOf with the Visitor-Pattern

Using the visitor pattern to eliminate If-Statements and InstanceOf


We all know the visitor pattern from the book GoF (gang of four) or from other famous books. The examples in there are usually associated with trees or composite structures. I was always searching for real life examples, where this pattern could be used, making software reusable and more readable. During a refactoring task, a collegue of mine had a really good idea, that i want to share with you.


Here is the code fragment from the method we want to refactore. The method has a lot of if-statements and instanceOf in there. It maps contacts to data transfer objects (DTO)


public static void mapKontakte(ContactType contactType, List<ErweiterteKontakt<? extends StringDomainEnum>> kontakte) {
        ch.abraxas.tax.register.registerimport.parser.ech0046.v10.ObjectFactory ech0046Factory =
                new ch.abraxas.tax.register.registerimport.parser.ech0046.v10.ObjectFactory();
        for (ErweiterteKontakt<? extends StringDomainEnum> kontakt : kontakte) {
            if (kontakt instanceof Telefon) {
                PhoneType phoneType = ech0046Factory.createPhoneType();
                phoneType.setPhoneCategory(new BigInteger( ((Telefon) kontakt).getKategorie().key()));
                phoneType.setPhoneNumber(kontakt.getDetail());
                contactType.getPhone().add(phoneType);
            } else if (kontakt instanceof Email) {
                EmailType emailType = ech0046Factory.createEmailType();
                emailType.setEmailCategory(new BigInteger( ((Email) kontakt).getKategorie().key()));
                emailType.setEmailAddress(kontakt.getDetail());
                contactType.getEmail().add(emailType);
            } else if (kontakt instanceof Internet) {
                InternetType internetType = ech0046Factory.createInternetType();
                internetType.setInternetCategory(new BigInteger( ((Internet) kontakt).getKategorie().key()));
                internetType.setInternetAddress(kontakt.getDetail());
                contactType.getInternet().add(internetType);
            }
            // Should we use an else branch to verify that we are mapping all Kontakte?
        }
    }


here is the same method after refactoring:


public static void mapKontakte(ContactType contactType,
   List<ErweiterteKontakt<? extends StringDomainEnum>> kontakte) {

  ErweiterterKontaktVisitor visitor = new BindingObjectFromKontaktVisitor(contactType);
  for (ErweiterteKontakt<? extends StringDomainEnum> kontakt : kontakte) {
   // calls the Kontakt to use the visitor
   kontakt.accept(visitor);
  }
 }


Well here is how to do it. In the abstract class ErweiterteKontakt we define following method:


public abstract void accept(ErweiterterKontaktVisitor visitor);


Then we implement this abstract method in the classes Email, Telefon and Internet. They all extends ErweiterkeKontakt.


 @Override
 public void accept(ErweiterterKontaktVisitor visitor) {
  visitor.visit(this);
 }

Defining the visitor interface


public interface ErweiterterKontaktVisitor {

 /**
  * Visit the telefon
  * 
  * @param telefon
  */
 public void visit(Telefon telefon);

 /**
  * visit the email
  * 
  * @param email
  */
 public void visit(Email email);

 /**
  * visit the internet
  * 
  * @param internet
  */
 public void visit(Internet internet);
}


Then Implementing the Visitor itself:


public class BindingObjectFromKontaktVisitor implements ErweiterterKontaktVisitor {

 private ch.abraxas.tax.register.registerimport.parser.ech0046.v10.ObjectFactory ech0046Factory = new ch.abraxas.tax.register.registerimport.parser.ech0046.v10.ObjectFactory();

 private ContactType contactType;

 /**
  * Konstruktor
  */
 public BindingObjectFromKontaktVisitor(ContactType contactType) {
  this.contactType = contactType;
 }

 /**
  * {@inheritDoc}
  */
 @Override
 public void visit(Telefon telefon) {
  PhoneType phoneType = ech0046Factory.createPhoneType();
  phoneType.setPhoneCategory(new BigInteger(telefon.getKategorie().key()));
  phoneType.setPhoneNumber(telefon.getDetail());
  contactType.getPhone().add(phoneType);
 }

 /**
  * {@inheritDoc}
  */
 @Override
 public void visit(Email email) {
  EmailType emailType = ech0046Factory.createEmailType();
  emailType.setEmailCategory(new BigInteger(email.getKategorie().key()));
  emailType.setEmailAddress(email.getDetail());
  contactType.getEmail().add(emailType);

 }

 /**
  * {@inheritDoc}
  */
 @Override
 public void visit(Internet internet) {
  InternetType internetType = ech0046Factory.createInternetType();
  internetType.setInternetCategory(new BigInteger((internet).getKategorie().key()));
  internetType.setInternetAddress(internet.getDetail());
  contactType.getInternet().add(internetType);

 }
}


Done!
No more If-Statements, no more InstanceOf and the code is now extandable and more flexible.

😱👇 PROMOTIONAL DISCOUNT: BOOKS AND IPODS PRO ðŸ˜±ðŸ‘‡

Be sure to read, it will change your life!
Show your work by Austin Kleonhttps://amzn.to/34NVmwx

This book is a must read - it will put you in another level! (Expert)
Agile Software Development, Principles, Patterns, and Practiceshttps://amzn.to/30WQSm2

Write cleaner code and stand out!
Clean Code - A Handbook of Agile Software Craftsmanship: https://amzn.to/33RvaSv

This book is very practical, straightforward and to the point! Worth every penny!
Kotlin for Android App Development (Developer's Library): https://amzn.to/33VZ6gp

Needless to say, these are top right?

😱👆 PROMOTIONAL DISCOUNT: BOOKS AND IPODS PRO ðŸ˜±ðŸ‘†