Saturday, December 9, 2017

Abstract Factory Pattern

Definition -

This is a creation pattern. It is also referred to as Factory of Factories. This helps designers to decouple objects from the implementing systems. Here the abstract factory will have a set of core functionalities which has to be implemented by all the factories which implement them.

Scenario -
Lets take a scenario where you are required to work with different protocols and you have to execute certain functions based irrespective of the protocol but the method of implementation is different.
In this case lets assume we have to deal with TCP and UDP protocols and each one of them have to read the data on a port. The reading of the data is different for TCP and UDP.

The UML diagram is as shown below



Based on the above -

protocolImplementor is an abstract class.
the concrete factories will be tcpprotocol and udpprotocol which will implement the read and processing functionality.

So here we have an abstract factory which defines two functionalities.

The two concrete factories tcpprotocol and udpprotocol will implement the abstract factory.

In the main method, we are invoking the classes depending on the requirement. There are other methods to invoke this which include creating an instance of the abstract factory and then invoking the class which is required. I have just maintained this for simplicity.

Code

We will have an abstract Interface called:  protocolImplementor

package FactoryPattern;

public abstract interface protocolImplementor {
    
    public void readport(int port);
    public void processdata();

}

The below two classes tcpprotocol and udpprotocol will implement the interface as shown below - 

package FactoryPattern;

public class tcpprotocol implements protocolImplementor {
    
    public tcpprotocol() {
        System.out.println("Initializing tcp protocol");
    }

    @Override
    public void readport(int port) {
        
        System.out.println("tcp method: Reading port:"+port);
        
    }

    @Override
    public void processdata() {
        
        System.out.println("tcp method: processing data");
        
    }

}


package FactoryPattern;

public class udpprotocol implements protocolImplementor{
    
    
    public udpprotocol() {
        System.out.println("Initializing udp protocol");
    }

    @Override
    public void readport(int port) {
        
        System.out.println("udp method: Reading port:"+port);
        
    }

    @Override
    public void processdata() {
        
        System.out.println("udp method: processing data");
        
    }

}



Then we will have a client abstractfactoryclient which will show us demo of the pattern

package FactoryPattern;

public class abstractfactoryclient {

    public static void main(String[] args) {
        
        String protocol="TCP";;
        int port=8080;
        
        if(protocol=="TCP") {
            tcpprotocol tcp=new tcpprotocol();
            tcp.readport(port);
            tcp.processdata();
        }
        
        if(protocol=="UDP") {
            udpprotocol udp=new udpprotocol();
            udp.readport(port);
            udp.processdata();
        }

    }

}


Place to use -
1. If you have multiple platforms and you require to use one of them depending on the scenario.
2. You want to provide a library without exposing the implementation details.
3. You want to ensure your implementation is platforms independent.
4. If you have products which needs to adhere to a minimum set of functionalities and the client program can choose this at runtime.


Place not to use -
1. Do not use this if you have too many objects being passed.
2. If the future extension requires new functionalities, which would mean we would implement the interface but we would not use it. This would result in a very bad design.
3. If there are too many attributes being introduced in the future.

No comments:

Post a Comment