preface

In the factory pattern, it is the factory class that is important, not the product class. Product classes can come in many forms, from multiple layers of inheritance to a single class. To be clear, however, factory mode interfaces will only return instances of one type. This is important when designing product classes, preferably interfaces that have parent classes or common implementations. With the factory pattern, the returned instance must have been created by the factory and not retrieved from another object. The factory pattern can return instances that are not newly created, and it is also possible to return instances that were created by the factory.

The factory pattern primarily provides an interface for creating objects. Factory patterns fall into three categories as described in Java and Patterns:

  1. Simple Factory Pattern
  2. Factory Method Pattern
  3. Abstract Factory Pattern

1. Factory Mode – Simple Factory Mode

Simple factory advantage: Clients are relieved of the responsibility of directly creating product objects and simply “consuming” the product. The simple factory pattern achieves this separation of responsibilities.

1.1. Simple Factory Pattern UML diagram
1.2. Code implementation
Defines the interface
/** * Map specification *@author Dream
 *
 */
public interface IMapView {
    enum MapType {
        // Blank background mode constant
        MAP_TYPE_NONE,
        // Normal map mode constants
        MAP_TYPE_NORMAL,
        // Satellite image mode constant
        MAP_TYPE_SATELLITE
    }

    public View getView(a);

    public void setMapType(MapType mapType);
}
Copy the code
Implementing an interface
public class BaiduMapView implements IMapView {

    @Override
    public View getView(a) {
        System.out.println("Called baidu Map getView");
        return null;
    }

    @Override
    public void setMapType(MapType mapType) {
        System.out.println("Called baidu Map setMapType"); }}Copy the code
public class GaodeMapView implements IMapView {

    @Override
    public View getView(a) {
        System.out.println("Called getView of Amap.");
        return null;
    }

    @Override
    public void setMapType(MapType mapType) {
        System.out.println("Called setMapType of amap."); }}Copy the code
Creating a Factory Class
public class MapViewFactory {
    
    enum MapType{
        Baidu,
        Gaode
    }
    
    // Use the singleton pattern from the previous lesson
    / / LanHanShi
    private static MapViewFactory mapViewFactory;
    
    private MapViewFactory(a){}public static MapViewFactory getInstance(a){
        if(mapViewFactory == null){
            mapViewFactory = new MapViewFactory();
            ArrayList<String> list = new ArrayList<String>();
            HashSet<String> hashSet = new HashSet<String>();
        }
        return mapViewFactory;
    }
    
    public IMapView getMapView(MapType mapType){
        IMapView mapView = null;
        switch (mapType) {
        case Baidu:
            mapView = new BaiduMapView();
            break;
        case Gaode:
            mapView = new GaodeMapView();
            break;
        }
        returnmapView; }}Copy the code
Call main function
public class SimpleTest {

    public static void main(String[] args) {
        // The client and our map module are much less coupledIMapView mapView = MapViewFactory.getInstance().getMapView( MapViewFactory.MapType.Baidu); mapView.getView(); mapView.setMapType(IMapView.MapType.MAP_TYPE_NONE); }}Copy the code
The results
Get baidu Map MapView set the Autonavi map type get Autonavi Map MapView set the Autonavi map typeCopy the code
1.3. Used in Android source code
Simple factory in the Android - BitmapFactory XmlPullParserFactory, CertificateFactoryCopy the code

2. Factory Mode – Factory method mode

The factory method pattern: Postpones the implementation of objects until subclasses complete the factory method advantage: allows the system to introduce new products without modifying specific factory roles.

2.1 factory method pattern UML diagram
2.2 code implementation
Product Interface and Implementation (Mapview)
/ / interface
public abstract class IMapView {
    public abstract void onStart(a);

    public abstract void onResume(a);

    public abstract void onDestory(a);
}
Copy the code
public class BaiduMapView extends IMapView {

    @Override
    public void onStart(a) {
        System.out.println("Baidu Map onStart");
    }

    @Override
    public void onResume(a) {
        System.out.println("Baidu Map onResume");
    }

    @Override
    public void onDestory(a) {
        System.out.println(Baidu Map onDestory); }}Copy the code
public class GaodeMapView extends IMapView {

    @Override
    public void onStart(a) {
        System.out.println("Amap onStart");
    }

    @Override
    public void onResume(a) {
        System.out.println("Amap onResume");

    }

    @Override
    public void onDestory(a) {
        System.out.println("Amap onResume"); }}Copy the code
The abstract factory
/ / abstract
public abstract class AbsMapFactory {
    // I only define standards
    public abstract <T extends IMapView> T createMapView(Class<T> clzz);
}
Copy the code
Implementing factory
public class DefaultMapFactory extends AbsMapFactory {

    private static DefaultMapFactory defaultMapFactory;

    private DefaultMapFactory(a) {}public static DefaultMapFactory getInstance(a){
        if(defaultMapFactory == null){
            defaultMapFactory = new DefaultMapFactory();
        }
        return defaultMapFactory;
    }


    @Override
    public <T extends IMapView> T createMapView(Class<T> clzz) {
        try {
            / / reflection
            return clzz.newInstance();
        } catch (Exception e) {
            e.printStackTrace();
        }
        return null; }}Copy the code
Call main function
public class TestClient {
    
    public static void main(String[] args) {
        // Factory method patternAbsMapFactory factory = DefaultMapFactory.getInstance(); BaiduMapView mapView = factory.createMapView(BaiduMapView.class); mapView.onStart(); }}Copy the code
The results
Baidu map onStartCopy the code
2.2 use of source code in Java or Android

Analysis of List collection, Set collection, Map collection source lterator: traversal collection factory method abstract Itr: concrete factory implementation class

Lterator –> Abstraction (Factory method abstraction) –>AdsMapFactory Itr –> Implementation class –> DefaultMapFactory AbstractList –> Abstraction –>ImapView

ArrayList-> Implementation class --> BaiduMapViewCopy the code

3. Factory Pattern – Abstract Factory Pattern

The abstract factory pattern is introduced in order to add navigation modules, panorama modules, positioning modules rather than just map modules (a set of classes requires the same constraints). The abstract factory advantage: It provides an interface to the client to create product objects in multiple product families without specifying the specific type of the product

3.1 Abstract factory model UML diagram
3.2 code implementation
The abstract factory
public abstract class AbsMapFactory {

    public abstract AbsMapView createMapView(a);

    public abstract AbsMapNavigation createMapNavigation(a);

    public abstract AbsMapLocation createMapLocation(a);
}
Copy the code
Specific factories
public class GaodeMapFactory extends AbsMapFactory {

    @Override
    public AbsMapView createMapView(a) {
        return new GaodeMapView();
    }

    @Override
    public AbsMapNavigation createMapNavigation(a) {
        return new GaodeMapNavigation();
    }

    @Override
    public AbsMapLocation createMapLocation(a) {
        return newGaodeMapLocation(); }}Copy the code
public class BaiduMapFactory extends AbsMapFactory {

    @Override
    public AbsMapView createMapView(a) {

        return  new BaiduMapView();
    }

    @Override
    public AbsMapNavigation createMapNavigation(a) {

        return new BaiduMapNavigation();
    }

    @Override
    public AbsMapLocation createMapLocation(a) {
        return newBaiduMapLocation(); }}Copy the code
Initial chemical plant
public class DefaultFactory {


    // Use reflection
    public static  <T extends AbsMapFactory> T creatProduct(Class<T> clz){
        AbsMapFactory api =null;
        try {
            api =(AbsMapFactory) Class.forName(clz.getName()).newInstance();
        } catch (InstantiationException e) {
            e.printStackTrace();
        } catch (IllegalAccessException e) {
            e.printStackTrace();
        } catch (ClassNotFoundException e) {
            e.printStackTrace();
        }

        return(T)api; }}Copy the code
All products in the factory

Product positioning

public abstract class AbsMapLocation {
    
    /** ** locate */
    public abstract void location(a);
}
Copy the code
public class BaiduMapLocation extends AbsMapLocation {

    @Override
    public void location(a) {
        System.out.println("Baidu Map positioning..."); }}Copy the code
public class GaodeMapLocation extends AbsMapLocation {

    @Override
    public void location(a) {
        System.out.println("Amap location..."); }}Copy the code

Map products

public abstract class AbsMapView {
    
    /**
     * Result for IActivityManager.startActivity: an error where the
     * start had to be canceled.
     * @hide* /
    public abstract void onStart(a);

    public abstract void onResume(a);

    public abstract void onDestory(a);
}
Copy the code
public class BaiduMapView extends AbsMapView {

    
    @Override
    public void onStart(a) {
        System.out.println("Baidu Map called onStart");
    }

    @Override
    public void onResume(a) {
        System.out.println("Baidu map called onResume.");
    }

    @Override
    public void onDestory(a) {
        System.out.println("Baidu Maps called onDestory."); }}Copy the code
public class GaodeMapView extends AbsMapView {

    @Override
    public void onStart(a) {
        System.out.println("Amap called onStart");
    }

    @Override
    public void onResume(a) {
        System.out.println("Amap called onResume.");
    }

    @Override
    public void onDestory(a) {
        System.out.println("Amap called onDestory."); }}Copy the code

Navigation products

public abstract class AbsMapNavigation {
    
    /** ** route planning */
    public abstract void turnByTurn(a);
    
    / /... Many functional methods
}
Copy the code
public class BaiduMapNavigation extends AbsMapNavigation {

    @Override
    public void turnByTurn(a) {
        System.out.println("Baidu Map Navigation Route Planning"); }}Copy the code
public class GaodeMapNavigation extends AbsMapNavigation {

    @Override
    public void turnByTurn(a) {
        System.out.println("Route Planning of Amap Navigation Function"); }}Copy the code
Call main function

public class Test {
    
    public static void main(String[] args) {
        // Initialize a map directly
        AbsMapFactory factory = new BaiduMapFactory();
        factory.createMapView().onStart();
        factory.createMapLocation().location();

        // Reflection initializes a mapAbsMapFactory factory2 = DefaultFactory.creatProduct(GaodeMapFactory.class); factory2.createMapView().onStart(); factory2.createMapLocation().location(); }}Copy the code
The results
Baidu map called onStart Baidu map positioning... Amap call onStart amAP location...Copy the code
3.3. Used in Android source code

Activity, Service — AbsMapView or absmapnavnavigation is our custom Activity (such as BaseActivity), Service –BaiduMapView or Navigation is involved in the ActivityManager, ServiceManager – similar to what we commonly call the AbsMapFactory

Conclusion:

Simple factory: Used to produce any product in the same grade structure. Factory method: used to produce fixed products in the same grade structure. Abstract factory: Used to produce all products of different product families. (Nothing can be done to add new products; Support for adding product family) the above three factory methods support different degrees in the two directions of hierarchy and product family. So consider which method to use depending on the situation.