编程经验之考虑使用静态工厂方法

英文原文:Consider static factory method。 

安卓中的基本问题之一就是对键/值对的持有。因为bundle 需要键/值对,所以你总是需要一个key。然而问题是哪里保存这些key?

有几种方法。

1.每个fragment,activity创建相同的key。比如你想从LoginActivity 传递数据到LoginFragment。你在两个类中中都持有相同的key。

Cons: 重复了,而且容易产生书写错误。

2.把key放在一个类但可以在任何地方访问到,比如:LoginActivity.KEY_FOO。

**Cons:**这会制造一个耦合而且类总是必须知道要调用哪个key。这也可能影响到系统。假定你误用了另外一个key。

3.把所有key都放在一个类中,比如Constants.java。

Cons: 我认为这是三者中最糟糕的。所有的类都将和这个类耦合并且一个小错误就会影响到整个系统。不久因为太多的key会轻易失去控制。

那么,该如何办呢?

静态工厂方法对这种情况有很大帮助。

与其创建另一个类的对象,不如让对应的类自己创建对象。

HomeActivity 自己负责创建自己的intent。

调用者类无需知道intent以及key的任何事情。LoginActivity 只需告诉HomeActivity,”嘿,我需要一个带有这个数据的intent”。就是这样,HomeActivity 会做完其它的事情。

相同的原理也应用到fragments 上。我们都知道不应该使用非默认的构造器来传递数据。主要的原因是当fragment 被重建的时候( config changes 或者旋转的时候),会用到默认的构造器而你会丢失数据。你需要找到修复它的规避措施。

而有了静态工厂方法,你就有了一个简洁的方法来避免这个问题。创建一个方法来传递你的变量,把它们放到一个bundle 中然后设置给fragment。

静态工厂方法在null条件下也非常有用。

比如;我们需要把一个对象拷贝到另一个而有些field可能是null的。

在下面的代码中,如果 response.getUserResponse() 是null。因为User 的构造方法使用了它,它会抛出一个空指针异常。

User 类总是希望一个非空的对象。

一种办法是在创建对象的时候在Account 类中检查一下。

这让代码显得有点丑陋而且可读性差。想象一下你有许多这样的情况,你总是需要检查一下。

另一个办法是在User 中做判空检查。

但是如果你仔细点就会注意到,这里的问题是我们会得到一个field全为空的新对象。这肯定会在别的地方引起crash 。

简洁的解决办法来自于静态工厂方法。我们基本就是使用newUser 方法首先检查response ,如果response 无效我们仅返回null而不创建一个新的对象。而如果response 有效则返回一个新的user 对象。

你也可以做其它方面的验证,比如其中一个变量为空你就不想创建一个新的对象等。

我们大量的使用静态工厂方法并且从中获得了很多好处。

  1. 简洁

  2. 低耦合

  3. 对应的类在创建之前可以先做验证。

  4. 对应的类可以使用单例模式返回现有的对象而不创建一个新的对象。

  5. 对应的类可以创建一个子类并返回。

总之,对应的类总是能够做正确的事情。