English | 简体中文 | 繁體中文 | Русский язык | Français | Español | Português | Deutsch | 日本語 | 한국어 | Italiano | بالعربية

Instance Explanation of Factory Method Pattern in Android Programming Design Patterns

This article describes an example of Factory Method pattern in Android programming design. Shared for everyone's reference, as follows:

One, Introduction

Factory Method pattern (Factory Pattern) is one of the creation design patterns. The Factory Method pattern is a simple structure pattern, which is widely used in our daily development. Perhaps you don't know it, but you have used this pattern countless times, such as the various lifecycle methods in the Activity of Android. Taking onCreate as an example, it can be regarded as a factory method, where we can construct our View and return it to the framework through setContentView, and so on. We will discuss related content later. Let's first look at the definition of the Factory Method pattern.

Two, Definition

Define an interface for creating objects, allowing subclasses to decide which class to instantiate.

Three, Application Scenarios

The Factory Method pattern can be used anywhere complex objects need to be generated. Complex objects are suitable for using the Factory pattern, and objects created with new do not need to use the Factory pattern.

Four, simple implementation of the pattern

Abstract product class:

public abstract class Product {
  /**
   * Abstract method of product class
   * By specific product classes to implement
   * */
  public abstract void method();
}

Concrete product class A:

public class ConcreteProductA extends Product {
  @Override
  public void method() {
    System.out.println("I am a specific product A");
  }
}

Concrete product class B:

public class ConcreteProductB extends Product {
  @Override
  public void method() {
    System.out.println("I am a specific product B");
  }
}

Abstract factory class:

public abstract class Factory {
  /**
   * Abstract factory method
   * To be implemented by subclasses
   * 
   * @return The specific product object
   * */
  public abstract Product createProduct();
}

Concrete factory class:

public class ConcreteFactory extends Factory {
  /**
   * Concrete factory class
   * */
  @Override
  public Product createProduct() {
    return new ConcreteProductA();
  }
}

Client class:

public class Client {
  public static void main(String[] args) {
    Factory factory = new ConcreteFactory();
    Product product = factory.createProduct();
    product.method();
  }
}

Result:

I am a specific product A

The roles here are quite simple, mainly divided into four modules: the abstract factory, which is the core of the factory method pattern; the concrete factory, which implements specific business logic; the abstract product, which is the superclass of the products created by the factory method pattern; and the concrete product, which is an object representing a specific product that implements the abstract product.

In the above code, we constructed a factory object in the Client class and produced a product object through it. The product object we get is an instance of ConcreteProductA. If you want to get an instance of ConcreteProductB, you can change the logic in ConcreteFactory:

public class ConcreteFactory extends Factory {
  /**
   * Concrete factory class
   * */
  @Override
  public Product createProduct() {
    //return new ConcreteProductA();
    return new ConcreteProductB();
  }
}

This method is quite common, producing the required product on demand. Sometimes, it can also be more concise to produce specific product objects using reflection. In this case, a Class object needs to be passed in the parameter list of the factory method to determine which product class to use:

public abstract class Factory {
  /**
   * Abstract factory method
   * To be implemented by subclasses
   * 
   * @param clz The type of the product object class
   * 
   * @return The specific product object
   * */
  public abstract <T extends Product> T createProduct(Class<T> clz);
}

For specific factory classes, you can obtain an instance of the class through reflection:

public class ConcreteFactory extends Factory {
  /**
   * Concrete factory class
   * */
  @SuppressWarnings("unchecked")
  @Override
  public <T extends Product> T createProduct(Class<T> clz) {
    Product product = null;
    try {
      product = (Product) Class.forName(clz.getName()).newInstance();
    } catch (Exception e) {
      e.printStackTrace();
    }
    return (T)product;
  }
}

Let's take a look at the implementation in Client:

public class Client {
  public static void main(String[] args) {
    Factory factory = new ConcreteFactory();
    Product product = factory.createProduct(ConcreteProductB.class);
    product.method();
  }
}

Pass the type of the class you need as an argument, and this method is more concise and dynamic. If you don't like this way, you can also try to define a specific factory for each product, each performing its own role.

public class ConcreteFactoryA extends Factory {
  /**
   * Concrete factory class
   **/
  @Override
  public Product createProduct() {
    return new ConcreteProductA();
  }
}
public class ConcreteFactoryB extends Factory {
  /**
   * Concrete factory class
   **/
  @Override
  public Product createProduct() {
    return new ConcreteProductB();
  }
}
public class Client {
  public static void main(String[] args) {
    Factory factoryA = new ConcreteFactoryA();
    Product productA = factoryA.createProduct();
    productA.method();
    Factory factoryB = new ConcreteFactoryB();
    Product productB = factoryB.createProduct();
    productB.method();
  }
}

The way of having multiple factories like this is called the Multi-Factory Method Pattern. Similarly, going back to our original Factory Method Pattern, when we have only one factory, we still provide an abstract class for the factory. Then, can we simplify it? If you are sure that your factory class has only one, it is definitely fine to simplify the abstract class. We just need to change the corresponding factory method to a static method:

public class Factory {
  /**
   * Concrete factory class
   **/
  @Override
  public static Product createProduct() {
    return new ConcreteProductA();
  }
}

This kind of method is also called simple factory pattern or static factory pattern, which is a weakened version of the factory method pattern.

In fact, by now, everyone should have found that the factory method pattern fully conforms to the design principles, which reduces the coupling between objects and has very good expandability. The factory method pattern relies on the abstract architecture, and it delegates the instantiation task to the subclass to complete, which has very good expandability.

Fifth, Factory Method Pattern in Android Source Code

Various Life Cycle of Activity

ArrayList and HashSet

Sixth, Summary

Advantages:

The factory method pattern fully conforms to the design principles and reduces the coupling between objects. The high-level modules only need to know the abstract class of the product, and do not need to care about other implementations.

Good encapsulation, clear code structure. Good expandability.

Disadvantages:

Every time we add a new product to the factory method pattern, we need to write a new product class. At the same time, we also need to introduce the abstract layer, which will inevitably lead to the complexity of the class structure. Therefore, when the situation is relatively simple, whether to use the factory pattern needs to be weighed by the designer.

Readers who are interested in more content related to Android can check the special topics on this site: 'Android Development入门与进阶教程', 'Android Debugging Skills and Common Problem Solutions Summary', 'Summary of Android Basic Component Usage', 'Summary of Android View View Skills', 'Summary of Android Layout Layout Skills', and 'Summary of Android Widget Usage'.

I hope the content described in this article will be helpful to everyone in Android program design.

Declaration: The content of this article is from the Internet, and the copyright belongs to the original author. The content is contributed and uploaded by Internet users spontaneously. This website does not own the copyright, has not been edited by humans, and does not assume relevant legal liabilities. If you find any content suspected of copyright infringement, please send an email to notice#w (replace # with @ when sending email).3If you find any infringing content, please send an email to notice#w (replace # with @ when sending email) to report it, and provide relevant evidence. Once verified, this site will immediately delete the suspected infringing content.

You May Also Like