Skip to content
September 26, 2008 / Shrikant Patil

Abstract Factory Pattern

This Pattern Defines and interface for creating an object, but let subclasses decide which class to instantiate. Factory Method lets a class defer instantiation to subclasses.
This pattern allows us to encapsulate instantiations of concrete types. The Abstract ‘creator’ defines an interface with a method for creating objects. This method is known as ‘Factory Method.

We can implement other methods in Abstract ‘creator’ which are also implemented in products created by the factory method. The subclasses of this Abstract ‘creator’ will implement the factory method and create products. The subclasses of this Abstract ‘creator’ decide which product is needed to be created at run time. So this Abstract class is totally unaware of which product will get created at run time, which is decided totally by the decision of subclasses of this Abstract ‘creator’.
Let us start with code. We are going to create a Player (client) which asks to Factory (Creator) to create a particular Song (product) object, depending passes language parameter.

Here is the class diagram,
Creating Song (Products) Class:
At the beginning we create an interface ISong, which is get implemented by all Songs (Product) classes. The interface defines a signature of a method playSong() which is get implemented in all implementing Songs (Product) classes.


package flexScript
{
    public interface ISong
    {
        function playSong():void;
    }
}

Let us create two of classes EnglishSong and SpanishSong which implements ISong interface. Both classes implement the method playSong() which is defined by the ISong interface.


package flexScript
{
    internal class EnglishSong implements ISong
    {
        //ISong method implementation
        public function playSong():void
        {
            trace("Playing English Song...");
        }

    }
}


package flexScript
{
    internal class SpanishSong implements ISong
    {
        //ISong method implementation
        public function playSong():void
        {
            trace("Playing Spanish Song...");
        }

    }
}

Creating Abstract Factory (Abstract Creator) class:
The Factory class should be an Abstract class. Means that it should be subclasses and not instantiated. It has an public method createSong() which defines a object of ISong and assign the return value from songFactory() method & once the instance from songFactory() method assigned to the defined object, the method calls its method song.playSong(). Class also defines an Abstract method songFactory() which is overridden in subclasses, the songFactory() method returns an object of ISong.


package flexScript
{
    import flash.errors.IllegalOperationError;
    //This is creator class and it must be abstract class
    //Abstract class means this class can be extended but not instantiated
    public class Factory
    {
        public function Factory()
        {
        }
        public function createSong():void{
            var song:ISong = this.songFactory();
            song.playSong();
        }

        //Abstract method which can be overidden in subclass
        protected function songFactory():ISong{
            throw new Error("This is Abstract Method: overriden in subclass");
            return null;
        }
    }
}

Lets us create concrete creator classes EnglishSongFactory and SpanishSongFactory. Both classes extends base Abstract Factory (abstract creator) class and override the songFactory() method to define their own creation of product objects (EnglishSing or SpanishSong)


package flexScript
{
    public class EnglishSongFactory extends Factory
    {
        public function EnglishSongFactory()
        {
            super();
        }
        //override songFactory() method of super class
        override protected function songFactory():ISong{
            trace("Creating English Song....");
            return new EnglishSong();
        }
    }
}

package flexScript
{
    public class SpanishSongFactory extends Factory
    {
        public function SpanishSongFactory()
        {
            super();
        }

        //override songFactory of super class
        override protected function songFactory():ISong{
            trace("Creating Spanish Song....");
            return new SpanishSong();
        }

    }
}

Crating Client class:
The client class may be the main class of the application. This client doesn’t know anything about product classes and what they exactly do. Client only instantiates EnglishSongFactory and SpanishSongFactory and tell them to call createSong(). The createSong() method calls songFactory() method of Factory abstract class to return a product object. After creating product class it calls playSong() in the product object.

<?xml version="1.0" encoding="utf-8"?>
<mx:Application xmlns:mx="http://www.adobe.com/2006/mxml"
layout="absolute" creationComplete="init()">
    <mx:Script>
        <!&#91;CDATA&#91;
            import flexScript.*;

            private function init():void{
                // instantiate concrete creators
                var song1:Factory = new EnglishSongFactory();
                var song2:Factory = new SpanishSongFactory();
                song1.createSong();
                song2.createSong();
            }
        &#93;&#93;>
    </mx:Script>
</mx:Application>

The role of EnglishSongFactory and SpanishSongFactory is to create and return product objects (EnglishSong or SpanishSong). The both classes know which product need to be created and returned. They override songFactory() to instantiate the particular products and return them to createSong() method.
In this manner Factory method pattern encapsulate concrete product classes form client.

Advertisements

Leave a Reply

Fill in your details below or click an icon to log in:

WordPress.com Logo

You are commenting using your WordPress.com account. Log Out / Change )

Twitter picture

You are commenting using your Twitter account. Log Out / Change )

Facebook photo

You are commenting using your Facebook account. Log Out / Change )

Google+ photo

You are commenting using your Google+ account. Log Out / Change )

Connecting to %s

%d bloggers like this: