英文原文: 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 对象。
你也可以做其它方面的验证,比如其中一个变量为空你就不想创建一个新的对象等。
我们大量的使用静态工厂方法并且从中获得了很多好处。
简洁
低耦合
对应的类在创建之前可以先做验证。
对应的类可以使用单例模式返回现有的对象而不创建一个新的对象。
对应的类可以创建一个子类并返回。
总之,对应的类总是能够做正确的事情。