Bootstrap

JAVA设计模式之工厂方法模式

一 概述

1.1 定义

定义一个用于创建对象的接口,让子类决定实例化哪个类。

  • 工厂方法模式属于创建型模式
  • 工厂方法模式主要用来创建复杂的对象,简单对象能够使用 new 来创建就不用工厂方法模式来创建了

1.2 使用场景

首先当然是在你需要 new 一个类的对象的时候,此时各种状况出现啦:

  • 你不想直接 new 这个类的对象,怕以后这个类改变的时候你需要回来改代码,而此时依赖这个类的地方已经到处都是了
  • 这个类的对象构建过程非常复杂,你不愿意将这么复杂的构建过程一遍又一遍的写在需要用到此对象的地方
  • 这个类的对象在构建过程中依赖了很多其他的类,而你无法在调用的地方提供

工厂方法模式是简单工厂模式的升级版本,为了克服简单工厂模式的缺点而生,作用和简单工厂模式完全一样。

1.3 UML 类图

在这里插入图片描述
角色说明:

  • Product(抽象产品类):要创建的复杂对象,定义对象的公共接口
  • ConcreteProduct(具体产品类):实现 Product 接口
  • Factory(抽象工厂类):该方法返回一个 Product 类型的对象
  • ConcreteFactory(具体工厂类):返回 ConcreteProduct 实例

工厂方法模式为每一种产品生成一个对应的工厂,从而替换掉简单工厂方法模式中那个静态工厂方法。

工厂方法模式的核心思想:讨论的仍然是如何构建同一类型产品(都实现同一个接口)的问题,只不过是通过为每一种要生产的产品配备一个工厂,就是说每个工厂只生产一种特定的产品。这样做的好处就是当以后需要增加新的产品时,直接新增加一个对应的工厂就可以了,而不是去修改原有的工厂。

下面我们看下具体代码。

二 实现

2.1 创建抽象产品类,定义公共接口

    // 抽象产品类
    public abstract class Product {
        public abstract void show();
    }

2.2 创建具体产品类,继承 Product 类

    // 具体产品类 A 
    public class ProductA extends Product {
        @Override
        public void show() {
            System.out.println("product A");
        }
    }
    // 具体产品类 B
    public class ProductB extends Product {
        @Override
        public void show() {
            System.out.println("product B");
        }
    }

2.3 创建抽象工厂类,定义公共接口

    // 抽象工厂类
    public abstract class Factory {
        public abstract Product create();
    }

2.4 创建具体工厂类,继承抽象工厂类,实现创建具体的产品

    // 具体工厂类 A
    public class FactoryA extends Factory {
        @Override
        public Product create() {
            return new ProductA(); // 创建 ProductA
        }
    }
    // 具体工厂类 B
    public class FactoryB extends Factory {
        @Override
        public Product create() {
            return new ProductB(); // 创建 ProductB
        }
    }

2.5 测试方法

 public void test() {
        // 产品A
        Factory factoryA = new FactoryA();
        Product productA = factoryA.create();
        productA.show();
        // 产品B
        Factory factoryB = new FactoryB();
        Product productB = factoryB.create();
        productB.show();
    }

三 总结

3.1 特点

生成复杂对象时,无需知道具体类名,只需知道相应的工厂方法即可。

3.2 优点

  • 符合开放封闭原则。新增产品时,只需增加相应的具体产品类和相应的工厂子类即可
  • 符合单一职责原则。每个具体工厂类只负责创建对应的产品

3.3 缺点

  • 一个具体工厂只能创建一种具体产品
  • 增加新产品时,还需增加相应的工厂类,系统类的个数将成对增加,增加了系统的复杂度和性能开销
  • 引入的抽象类也会导致类结构的复杂化

四 Android 中的源码实例分析

Android 中的 ThreadFactory 就是使用了工厂方法模式来生成线程的,线程就是 ThreadFactory 的产品。

4.1 ThreadFactory 相关源码分析

    // 抽象产品:Runnable
    public interface Runnable {
        public abstract void run();
    }
    
    // 具体产品:Thread
    public class Thread implements Runnable {
        //构造方法
        public Thread(Runnable target, String name) {
            init(null, target, name, 0);
        }
        
        @Override
        // 实现抽象产品的抽象方法
        public void run() {
            if (target != null) {
                target.run();
            }
        }        
        // 其他代码略
    }
    
    
    // 抽象工厂:ThreadFactory
    public interface ThreadFactory {
        Thread newThread(Runnable r);
    }
    
    // 具体工厂:AsyncTask 中的实现
    private static final ThreadFactory sThreadFactory = new ThreadFactory() {
        private final AtomicInteger mCount = new AtomicInteger(1);
        
        // 实现抽象工厂的抽象方法
        public Thread newThread(Runnable r) {
        // 返回 Thread 这个产品
            return new Thread(r, "AsyncTask #" + mCount.getAndIncrement());
        }
    };

4.2 总结:

  • 这里只要是介绍 Android 系统中工厂方法模式的应用,线程和 AsyncTask 的原理就不说了
  • 通过 ThreadFactory,我们可以创建出不同的 Thread 来
  • 同样,我们可以创建另外类似的工厂,生产某种专门的线程,非常容易扩展

悦读

道可道,非常道;名可名,非常名。 无名,天地之始,有名,万物之母。 故常无欲,以观其妙,常有欲,以观其徼。 此两者,同出而异名,同谓之玄,玄之又玄,众妙之门。

;