Tuesday, November 17, 2015

Head First Design Pattern CH6: Command Pattern


in case you see something like this

public void actionPerformed(ActionEvent e)
{
  Object o = e.getSource();
  if (o = fileNewMenuItem)
    doFileNewAction();
  else if (o = fileOpenMenuItem)
    doFileOpenAction();
  else if (o = fileOpenRecentMenuItem)
    doFileOpenRecentAction();
  else if (o = fileSaveMenuItem)
    doFileSaveAction();
  // and more ...
}

then sure there is a problem, as you can see you are checking the instance and then you call an action method, this means that all these instances should implement a single interface which is the Command interface

// the Command Pattern in Java
public interface Command
{
  public void execute();
}

this interface should be implemented by all the types mentioned in actionPerformed

public class FileOpenMenuItem extends JMenuItem implements Command
{
  public void execute()
  {
    // your business logic goes here
  }
}

now simply you can write actionPerformed like this


public void actionPerformed(ActionEvent e)
{
  Command command = (Command)e.getSource();
  command.execute();
}

sure you can extend this pattern to do something more, for example maybe e.getSource() returns a list, you can simple loop over the list and call execute()

also you can add undo() function to the command interface and implement this function.


Monday, November 16, 2015

Head First Design Pattern CH4: Factory and Abstract Factory Patterns

 in this chapter we talk about Factory Pattern and Abstract Factory Pattern. we will not use the examples given in this chapter, we will just write some notes from it
 

 The idea here that creating object should be a responsibility of a single class,  we dont wanna see new() statments everywhere.

 they talked here about Dependency Inversion Principle, in order to achieve it you should always try to follow this:
 1- you should never have a variable that has a reference to a concrete class (if you use new(), it means that you are
 using a reference to a concrete class, get around that by using the Factory pattern)
 2- you should never have a class that extends a concrete class( only extend from abstract class or implement an interface)
 3- No method should override an implemented method of any of its base classes(if you override an implemented method, then your base
 class wasnt really an abstraction to start with)
 
In Factory Pattern, we will have a class with a specific method to create objects, for example lets consider the following:


we have different shapes here, we will add a Factory to create shapes

as you can see the creation of Shapes is totally seperated from their behaviour, they dont even know how they are created.

ShapeFactory class looks like this:

and if you wanna create a shape you write this.


as you can see the Factory Pattern creates an object of a single class (you will have a Factory class for each Interface), however sometimes you need to create multiple related object together. For example, lets say we have the following:


as you can see we have IProcessor and IRam interfaces,

we have 2 factories one to create a fast computer and another one to create slow computer, as you can see creating a computer means creating ram and processor.

FastComputerFactory knows that it should create CoreI7 processor and DDR3 ram
SlowComputerFactory will create CoreI3 and DDR1.

The AbstractComputerFactory has 2 methods one to getProcessor() and another one to getRam()

The code looks like this:


public interface IProcessor {void PerformOperation();}
public class CoreI7 : IProcessor
{
    public void PerformOperation()
    {
        Console.WriteLine("Operation will perform quickly");
    }
}
public class CoreI3 : IProcessor
{
    public void PerformOperation()
    {
        Console.WriteLine("Operation will perform Slowly");
    }
}


public interface IRam { void StoreData(); }
public class DDR3 : IRam 
{
    public void StoreData()
    {
        Console.WriteLine("Data will take less time to store");
    }
}
public class DDR1: IRam 
{
    public void StoreData()
    {
        Console.WriteLine("Data will take more time to store");
    }
}

public interface AbstractComputerFacotry
{
    IProcessor getProcessor();
    IRam getRam();
}
public class FastComputerFactory : AbstractComputerFacotry
{
    public  IProcessor getProcessor() { return new CoreI7(); }
    public IRam getRam() { return new DDR3(); }
}
public class SlowComputerFactory : AbstractComputerFacotry
{
    public  IProcessor getProcessor() { return new CoreI3(); }
    public IRam getRam() { return new DDR1(); }
}

As you can see in the picture we have a FactoryProducer, basically this is a producer of slow or fast computer

public class FactoryProducer {
   public static AbstractComputerFacotrygetFactory(String choice){
   
      if(choice.equalsIgnoreCase("Fast")){
         return new FastComputerFactory ();
         
      }else if(choice.equalsIgnoreCase("Slow")){
         return new SlowComputerFactory ();
      }
      
      return null;
   }
public class AbstractFactoryPatternDemo {
   public static void main(String[] args) {
      AbstractComputerFacotry computerFactory = FactoryProducer.getFactory("Fast");
      IProcessor processor = computerFactory.getProcessor();
      IRam ram = computerFactory.getRam();      
   }
}