Difference between revisions of "Abstract Factory"

From CDOT Wiki
Jump to: navigation, search
(Java Example)
(Code Example)
 
(17 intermediate revisions by the same user not shown)
Line 11: Line 11:
  
 
===Code Example===
 
===Code Example===
 +
'''JAVA'''
 +
<pre>
 +
/*
 +
* GUIFactory example
 +
*/
  
public abstract class CPU {
+
public abstract class GUIFactory {
    ...
+
  public static GUIFactory getFactory() {
} // class CPU
+
        int sys = readFromConfigFile("OS_TYPE");
 +
        if (sys == 0) {
 +
            return(new WinFactory());
 +
        } else {
 +
            return(new OSXFactory());
 +
        }
 +
  }
 +
  public abstract Button createButton();
 +
}
  
The concrete widget classes are simply classes that implement the widget interfaces:
+
class WinFactory extends GUIFactory {
 +
    public Button createButton() {
 +
        return(new WinButton());
 +
    }
 +
}
  
class EmberCPU extends CPU {
+
class OSXFactory extends GUIFactory {
     ...
+
     public Button createButton() {
} // class EmberCPU
+
        return(new OSXButton());
 +
    }
 +
}
  
Below is code for a concrete factory class that creates instances of classes to test ember architecture computers:
+
public abstract class Button  {
 +
    private String caption;
 +
    public abstract void paint();
 +
   
 +
    public String getCaption(){
 +
        return caption;
 +
    }
 +
    public void setCaption(String caption){
 +
        this.caption = caption;
 +
    }
 +
}
  
class EmberToolkit extends ArchitectureToolkit {
+
class WinButton extends Button {
     public CPU createCPU() {
+
     public void paint() {
        return new EmberCPU();
+
      System.out.println("I'm a WinButton: " + getCaption());
     } // createCPU()
+
     }
 +
}
  
     public MMU createMMU() {
+
class OSXButton extends Button {
        return new EmberMMU();
+
     public void paint() {
     } // createMMU()
+
      System.out.println("I'm a OSXButton  : " + getCaption());
    ...
+
     }
} // class EmberFactory
+
}
  
Below is the code for the abstract factory class:
+
public class Application {
 +
    public static void main(String[] args) {
 +
        GUIFactory aFactory = GUIFactory.getFactory();
 +
        Button aButton = aFactory.createButton();
 +
        aButton.setCaption("Play");
 +
        aButton.paint();
 +
    }
 +
    //output is
 +
    //I'm a WinButton: Play
 +
    //or
 +
    //I'm a OSXButton: Play
 +
}
 +
</pre>
  
public abstract class ArchitectureToolkit {
+
'''C++'''
    private static final EmberToolkit emberToolkit = new
+
<pre>
EmberToolkit();
+
#include <memory>
    private static final EnginolaToolkit
+
using std::auto_ptr;
enginolaToolkit
 
      = new EnginolaToolkit();
 
...
 
  
    /**
+
class Control { };
    * Returns a concrete factory object that is an
 
instance of the
 
    * concrete factory class appropriate for the given
 
architecture.
 
    */
 
    static final ArchitectureToolkit getFactory(int
 
architecture) {
 
        switch (architecture) {
 
          case ENGINOLA:
 
            &nbs
 
p; return enginolaToolkit;
 
  
          case EMBER:
+
class PushControl : public Control { };
            &nbs
 
p; return emberToolkit;
 
            ...
 
        } // switch
 
        String errMsg =
 
Integer.toString(architecture);
 
        throw new
 
IllegalArgumentException(errMsg);
 
    } // getFactory()
 
  
    public abstract CPU createCPU() ;
+
class Factory {
    public abstract MMU createMMU() ;
+
public:
    ...
+
  // Returns Factory subclass based on classKey.  Each
} // AbstractFactory
+
  // subclass has its own getControl() implementation.
 +
  // This will be implemented after the subclasses have
 +
  // been declared.
 +
  static auto_ptr<Factory> getFactory(int classKey);
 +
  virtual auto_ptr<Control> getControl() const = 0;
 +
};
  
Client classes typically create concrete widget objects using code that looks something like this:  
+
class ControlFactory : public Factory {
public class Client {
+
public:
    public void doIt () {
+
  virtual auto_ptr<Control> getControl() const {
        AbstractFactory af;
+
      return auto_ptr<Control>(new PushControl());
        af =
+
  }
AbstractFactory.getFactory(AbstractFactory.EMBER);
+
};
        CPU cpu = af.createCPU();
+
 
        ...
+
auto_ptr<Factory> Factory::getFactory(int classKey) {
    } // doIt
+
  // Insert conditional logic here. Sample:
} // class Client
+
  switch(classKey) {
 +
    default:
 +
      return auto_ptr<Factory>(new ControlFactory());
 +
  }
 +
}
 +
</pre>
  
 
===Reference===
 
===Reference===

Latest revision as of 19:41, 18 February 2007

Definition

A software design pattern, the Abstract Factory Pattern provides a way to encapsulate a group of individual factories that have a common theme. In normal usage, the client software would create a concrete implementation of the abstract factory and then use the generic interfaces to create the concrete objects that are part of the theme. The client does not know (nor care) about which concrete objects it gets from each of these internal factories since it uses only the generic interfaces of their products. This pattern separates the details of implementation of a set of objects from its general usage.

UML Diagram

Abstract factory uml.gif


Picture sourced:[1]

Code Example

JAVA

/*
* GUIFactory example
*/

public abstract class GUIFactory {
   public static GUIFactory getFactory() {
        int sys = readFromConfigFile("OS_TYPE");
        if (sys == 0) {
            return(new WinFactory());
        } else {
            return(new OSXFactory());
        }
   }
   public abstract Button createButton();
}

class WinFactory extends GUIFactory {
    public Button createButton() {
        return(new WinButton());
    }
}

class OSXFactory extends GUIFactory {
    public Button createButton() {
        return(new OSXButton());
    }
}

public abstract class Button  {
    private String caption;
    public abstract void paint();
    
    public String getCaption(){
        return caption;
    }
    public void setCaption(String caption){
        this.caption = caption;
    }
}

class WinButton extends Button {
    public void paint() {
       System.out.println("I'm a WinButton: " + getCaption());
    }
}

class OSXButton extends Button {
    public void paint() {
       System.out.println("I'm a OSXButton  : " + getCaption());
    }
}

public class Application {
    public static void main(String[] args) {
        GUIFactory aFactory = GUIFactory.getFactory();
        Button aButton = aFactory.createButton();
        aButton.setCaption("Play");
        aButton.paint();
    }
    //output is
    //I'm a WinButton: Play
    //or
    //I'm a OSXButton: Play
}

C++

#include <memory>
using std::auto_ptr;

class Control { };

class PushControl : public Control { };

class Factory {
 public:
   // Returns Factory subclass based on classKey.  Each
   // subclass has its own getControl() implementation.
   // This will be implemented after the subclasses have
   // been declared.
   static auto_ptr<Factory> getFactory(int classKey);
   virtual auto_ptr<Control> getControl() const = 0;
};

class ControlFactory : public Factory {
public:
   virtual auto_ptr<Control> getControl() const {
      return auto_ptr<Control>(new PushControl());
   }
};

auto_ptr<Factory> Factory::getFactory(int classKey) {
  // Insert conditional logic here.  Sample:
  switch(classKey) {
    default:
      return auto_ptr<Factory>(new ControlFactory());
  }
}

Reference

http://en.wikipedia.org/wiki/Abstract_factory_pattern
http://www.dofactory.com/Patterns/PatternAbstract.aspx