美文网首页程序员Java学习笔记
使用静态工厂方法代替构造器

使用静态工厂方法代替构造器

作者: 落英坠露 | 来源:发表于2017-08-03 10:51 被阅读60次

最近看到一段代码,感觉写得非常好,它的功能是带参数启动 Activity:

public class SecondActivity extends Activity {

    public static void actionStart(Context context, String data1, String data2) {
        Intent intent = new Intent(context, SecondActivity.class);
        intent.putExtra("param1", data1);
        intent.putExtra("param2", data2);
        context.startActivity(intent);
    }
    ...
}

使用静态方法的好处是什么呢?首先是一目了然,SecondActivity 需要的数据在方法参数中全部体现出来了,这样即使不阅读 SecondActivity 的代码,不用询问负责编写 SecondActivity 的同事,也可以清楚地知道启动 SecondActivity 需要传递哪些数据。另外,这样写还简化了启动 Activity 的代码,调用者只需要使用一行代码就可以启动 Activity,真的是非常简便!

SecondActivity.actionStart(FirstActivity.this, "data1", "data2");

这让我想到了《Effective Java 第2版》书中讲的一条经验:考虑使用静态工厂方法代替构造器。这里的静态工厂方法与设计模式中的工厂方法模式不同,它是用于创建当前类对象的静态方法。

提供静态工厂方法而不是公有的构造器的好处是什么呢?

  • 静态工厂方法有名称,可以清晰地阅读。如果构造器的参数本身没有确切地描述返回的对象,那么具有适当名称的静态工厂方法会更容易使用。

    举个栗子:Executors 类里面有一系列构建线程池的静态工厂方法,根据方法名就能知道返回的线程池的类型,清晰简洁,对使用者来说非常友好。

    public static ExecutorService newCachedThreadPool() {
            return new ThreadPoolExecutor(0, Integer.MAX_VALUE,
                                      60L, TimeUnit.SECONDS,
                                      new SynchronousQueue<Runnable>());
    }
    
    public static ExecutorService newFixedThreadPool(int nThreads) {
          return new ThreadPoolExecutor(nThreads, nThreads,
                                      0L, TimeUnit.MILLISECONDS,
                                      new LinkedBlockingQueue<Runnable>());
    }
    
  • 不必在每次调用静态工厂方法的时候都创建一个新对象。这使得不可变类可以使用预先构建好的实例,或者将实例缓存起来进行复用,从而避免创建不必要的重复对象。

    举个栗子:Boolean 类的 valueOf 方法,返回预先构建的缓存的实例,实例的复用提升了软件的性能。

    public static final Boolean TRUE = new Boolean(true);
    public static final Boolean FALSE = new Boolean(false);
    
    public static Boolean valueOf(boolean b) {
        return b ? Boolean.TRUE : Boolean.FALSE;
    }
    
  • 静态工厂方法可以返回原返回类型的任何子类型的对象,这样我们在选择返回对象的类时就有了更好的灵活性。

    举个栗子:EnumSet 类的 noneOf 方法返回一个空的枚举集合,类型是 EnumSet 的子类,这样根据不同的条件就能得到不同的实现类的实例,提高了方法的灵活性。

    public static <E extends Enum<E>> EnumSet<E> noneOf(Class<E> elementType) {
        if (!elementType.isEnum()) {
            throw new ClassCastException(elementType.getClass().getName() + " is not an Enum");
        }
        E[] enums = Enum.getSharedConstants(elementType);
        if (enums.length <= 64) {
            return new MiniEnumSet<E>(elementType, enums);
        }
        return new HugeEnumSet<E>(elementType, enums);
    }
    
  • 使用静态工厂方法创建参数化类型的实例,代码会变得非常简洁

    举个栗子:使用静态工厂方法 newInstance 创建带参数的 Fragment,参数清晰、代码简洁,使用起来非常容易。

    public class BlankFragment extends Fragment {
    
            public static BlankFragment newInstance(String param1, String param2) {
                  BlankFragment fragment = new BlankFragment();
                  Bundle args = new Bundle();
                  args.putString("param1", param1);
                  args.putString("param2", param2);
                  fragment.setArguments(args);
                  return fragment;
            }
            ...
    }
    

静态工厂方法的命名也有标准,下面是一些惯用名称:

  • valueOf: 这是类型转换的方法,返回的实例与它的参数具有相同的值。
  • of:valueOf 的一种更为简洁的替代,在 EnumSet 中使用并流行起来。
  • getInstance:返回的实例是通过方法的参数来描述的,对于单例来说,返回唯一的实例。
  • newInstance:像 getInstance 一样,但是可以确保返回的每个实例都与其他的实例不同。
  • getType:像 getInstance 一样,但是在工厂方法处于不用的类中的时候使用。
  • newType:像 newInstance 一样,但是在工厂方法处于不用的类中的时候使用。

总而言之,静态工厂方法的优势还是很明显的,简洁易读,方便使用。所以在编码的过程中,还是要考虑使用静态工厂方法,不要一味地使用构造器。

相关文章

  • 第一条 考虑用静态工厂方法代替构造器

    创建和销毁对象 考虑用静态工厂方法代替构造器 一般使用构造器 使用静态方法 这样写的优势 静态方法有名字构造器与类...

  • Java创建和销毁对象

    考虑用静态工厂方法代替构造器 静态工厂方法可以通过静态获取类的一个实例,而不需要通过构造器; 使用静态工厂方法的优...

  • EffectiveJava第2章-创建和销毁对象

    第1条:考虑使用静态工厂方法代替构造器 获取类实例的两种方法:公有的构造器、公有的静态工厂方法返回类的实例。 静态...

  • EffectiveJava-1-创建和销毁对象

    一. 使用静态工厂方法代替构造器 一个类对外提供获取自身实例对象的方法: 提供公有构造器 公有的静态工厂方法(一个...

  • effective java学习笔记 原则1:考虑用静态工厂方法

    原则1:考虑用静态工厂方法代替公有构造器 提供实例的方式:静态工厂方法(非设计模式中的静态工厂模式)公有构造器ne...

  • 创建和销毁对象

    1,考虑用静态工厂方法代替构造器 切忌第一反应就是提供共有构造器,而不先考虑静态工厂。 类可以通过静态工厂方法返回...

  • effective java读书笔记

    一、考虑用静态工厂方法代替构造器1.静态工厂方法有名称,而构造器只能是类名 private Map > map =...

  • Effective Java--(1)创建和销毁对象

    1 考虑用静态工厂方法代替构造器 例如如下方法: 静态工厂方法和构造器都各有长处,我们需要理解各自长处,做出合适的...

  • Java静态工厂方法

    相比构造器,静态工厂方法提供实例的优势: 静态工厂方法有名字 使用静态工厂方法比直接使用等效的构造方法更易阅读理解...

  • java编程建议系列一

    1.考虑用静态工厂方法代替构造器 静态工厂方法惯用名称 valueOf —— 类型转换方法 of —— value...

网友评论

    本文标题:使用静态工厂方法代替构造器

    本文链接:https://www.haomeiwen.com/subject/wloulxtx.html