You must read these articles before going through this article.
In this tutorial, I will explain the Abstract Factory method design pattern. Let say we have Many Interfaces and we have multiple implementations of the same interfaces. For example,
We have two Interfaces “Mobile” and “Laptop”. We have implementations as “Iphone”, “Samsung” and “NokiaLumia” for Mobile and“AppleMac”, “Asus” and “Compaq” for Laptop. If you want to create an object of Mobile or Laptop, You have to create Factory for those Interfaces.
Here we can have many factories. So, We create a Factory Producer, which produce an object of the required factory.
Once we have an object of the factory then, using factory we can create an object of Samsung/Iphone/NokiaLumia or AppleMac/Asus/Compaq.
[tmh_article_ads]
Let see by coding:
File structure:
Mobile.java
package co.tellmehow.afm; public interface Mobile { void getMobileData(); }
This is the Mobile interface. It will be implemented by “Samsung”,”Iphone” and “NokiaLumia” classes.
Samsung.java
package co.tellmehow.afm; public class Samsung implements Mobile { @Override public void getMobileData() { System.out.println("I am samsung"); } }
Iphone.java
package co.tellmehow.afm; public class Iphone implements Mobile { @Override public void getMobileData() { System.out.println("I am iPhone"); } }
NokiaLumia.java
package co.tellmehow.afm; public class NokiaLumina implements Mobile { @Override public void getMobileData() { System.out.println("I am Nokia"); } }
Similarly, Check Laptop Interface and Its implementations:
Laptop.java
package co.tellmehow.afm; public interface Laptop { void getLaptopData(); }
This is the Laptop interface. It will be implemented by “AppleMac”, “Asus” and “Compaq” classes.
AppleMac.java
package co.tellmehow.afm; public class AppleMac implements Laptop { @Override public void getLaptopData() { System.out.println("I am Apple Mac"); } }
Asus.java
package co.tellmehow.afm; public class Asus implements Laptop { @Override public void getLaptopData() { System.out.println("I am Asus"); } }
Compaq.java
package co.tellmehow.afm; public class Compaq implements Laptop { @Override public void getLaptopData() { System.out.println("I am HP Compaq"); } }
Now I have created Interfaces and its implemented classes. Suppose I want to create an object of Iphone. I first have to create Factory for Mobile, where objects of Iphone, Samsung or NokiaLumia (All implemented classes) will be created.
Let’s create factory classes for Mobile and Laptop.
MobileFactory.java
package co.tellmehow.afm.factory; import co.tellmehow.afm.Iphone; import co.tellmehow.afm.Laptop; import co.tellmehow.afm.FactoryProducer; import co.tellmehow.afm.Mobile; import co.tellmehow.afm.NokiaLumina; import co.tellmehow.afm.Samsung; public class MobileFactory extends FactoryProducer { public Mobile getMobile(String s) { if(s.equals("android")) { return new Samsung(); } else if(s.equals("ios")) { return new Iphone(); } else { return new NokiaLumina(); } } public Laptop getLaptop(String s) { return null; } }
LaptopFactory.java
package co.tellmehow.afm.factory; import co.tellmehow.afm.AppleMac; import co.tellmehow.afm.Asus; import co.tellmehow.afm.Compaq; import co.tellmehow.afm.Laptop; import co.tellmehow.afm.FactoryProducer; import co.tellmehow.afm.Mobile; public class LaptopFactory extends FactoryProducer { @Override public Laptop getLaptop(String s) { if(s.equals("amd")) { return new Asus(); } else if(s.equals("apple")) { return new AppleMac(); } else { return new Compaq(); } } public Mobile getMobile(String s) { return null; } }
If you have a single factory, Then our process is completed. See the Factory Method Design Pattern.
But I have many factories. In this case, I will have to create an object of a factory. For example:
If I want an object of Samsung class. I will have to create an object of MobileFactory first.
I have created an Abstract class FactoryProducer, Which will help to create an object of Factory.
FactoryProducer.java
package co.tellmehow.afm; public abstract class FactoryProducer { public abstract Laptop getLaptop(String s); public abstract Mobile getMobile(String s); }
FactoryOfFactory.java
package co.tellmehow.afm; import co.tellmehow.afm.factory.LaptopFactory; import co.tellmehow.afm.factory.MobileFactory; public class FactoryOfFactory { public static FactoryProducer getFactory(String s) { if(s.equalsIgnoreCase("mobile")) { return new MobileFactory(); } else { return new LaptopFactory(); } } }
Explanation: Here “getFactory(String s)” is FactoryProducer type method and is also a static method. This method returns MobileFactory/LaptopFactory.But, it depends on string parameter.
If s equals “moble” then MobileFactory otherwise LaptopFactory will be returned by this method.
This class helps to hide the process of creation of an object of Factory.
All is done. A user has to use the following code in the main class to create an object.
AbstractFactoryMethodApp.java
package co.tellmehow.afm; public class AbstractFactoryMethodApp { public static void main(String[] args) { FactoryProducer fd = FactoryOfFactory.getFactory("laptop"); Laptop l = fd.getLaptop("apple"); l.getLaptopData(); } }
Output: I am Apple Mac
Explanation:
FactoryProducer fd = FactoryOfFactory.getFactory(“laptop”);
Here getFactory is static method. So FactoryOfFactory Class is used to call this method. It returns LaptopFactory object. “fd” has reference of LaptopFactory object.
Laptop l = fd.getLaptop(“apple”);
This line gives the object of AppleMac class. If I pass “amd”, it returns the object of Asus class.
Here the user is only responsible to pass the only strings as parameters. It means, Which class object is initialized, is hidden from the user.
Share your thoughts