第一条:考虑使用静态方法替代构造器

The traditional way for a class to allow a client to obtain an instance is to provide a public consructor.There is another technique that should be a part of every programmer's toolkit.A class can provide a public static factory method,which is simply a static method that returns an instance of the class.Here's a simple example from Boolean(the boxed primitive class for boolean).This method translates a boolean primitive value into a Boolean object reference:

    public static Boolean valueOf(boolean b) {

        return b ? Boolean.TRUE : Boolean.False;

    }

Note that a static factory method is not the same as the Factory Method pattern from Design Patterns[Gramma95].The static factory method described in this item has no direct equivalent in Design Patterns.

对于一个类来说,允许获取一个对象实例的传统的方式就是提供一个公有的构造器。还有一个另外的方法应该出现在每一个程序员的工具包中。一个类可以提供一个简单的公有静态工厂方法,返回一个类的实例。Boolean类(基本类型boolean的包装类)中有个简单的例子,下面这个方法将一个boolean值转换成了Boolean对象的引用:

    public static Boolean valueOf(boolean b) {

        return b ? Boolean.TRUE : Boolean.False;

    }

注意这里的静态工厂方法并不是设计模式中的工厂模式。本条中描述的静态工厂方法在设计模式中并没有直接的等价物。

A class can provide its clients with static factory methods instead of,or in addition to,public constructors.Providing a static factory method instead of a public constructor has both advantages and disadvantages.

类除了给客户端提供公有构造方法外还可以提供静态工厂方法代替。提供静态工厂方法替代公有构造器有优点也有缺点。

One advantage of static factory method is that,unlike constructors,they have names.If the parameters to a constructor do not,in and of themselves,describe the object being returned,a static factory with a well-chosen name is easier to use the resulting client code easier to read.For example,the constructor BigInteger(int,int,Random),which returns a BigInteger that is probably prime,would have been better expressed as a static factory method named BigInteger.probablePrime.(This method was added in Java 4.)

静态工厂方法的第一个优点是,不像构造器那样,他们有名字。如果构造器的参数没有描述返回值对象,那么一个具有好的名字的静态工厂方法将会使代码更加易读。例如,构造方法BigInteger(int,int,Random),返回一个可能为质数的BigInteger,相比较而言,静态工厂方法BigInteger.probablePrime(Java 4中增加的方法)可能表达的更好一点。

A class can have only a single constructor with a given signature.Programmers have been known to get around this restriction by providing two constructors whose parameter lists differ only in the order of their parameter types.this is really bad idea.The user of such an API will never be able to remember which constuctor is which and will end up calling the wrong one by mistake.People reading code that uses these constructors will not know what the code does without referring to the class documentation.

一个类对于给定的签名只能提供一个构造器。程序员知道可以提供两个构造器来绕开这个限制,通过改变参数类型的顺序,这真的是个坏主意。API文档的使用者将不可能记住哪个构造器做什么的,有可能会发生错误的调用。读代码的人如果不看文档将不会知道构造器的作用。

Because they have names,static factory methods don't share the restriction discussed int the previous paragraph.In cases where a class seems to require multiple constructors with the same signature,replace the constructors with static factory methods and carefully chosen names to highlight their differences.

因为有名字,所以静态工厂方法不存在上段所讨论的限制。如果一个类中需要多个相同签名的构造函数,那么使用静态工厂方法替代他们,并认真的选择方法名来强调他们的不同。

A second advantage of static factory methods is that,unlike constructors,they are not required to create a new object each time they're invoked.This allows immutable classes to use preconstructed instances,or to cache instances as they're constructed,and dispense them repeatedly to avoid creating unnecessary duplicate objects.The Boolean.valueOf(boolean) method illustrates this technique: it never creates an object. This technique is similar to the Flyweight pattern. It can greatly improve performance if equivalent objects are requested often,especially if they are expensive to create.

静态工厂方法的第二个优点是,不像构造器那样,他们不需要在每次被调用的时候都创建一个新的对象。这允许了不可变类去使用之前构造的实例,或者缓存创建过的实例,然后反复的发放它们来避免创建多余的对象。Boolean.valueOf(boolean)方法表明了这个技巧,他从不会创建一个对象。这个技巧和设计模式中的享元模式相似。如果一个对象经常被请求的话,这种方式可以提高性能,特别是创建对象的代价很高时。

The ability of static factory methods to return the same object from repeated invocations allows classes to maintain strict control over what instances exist at any time.Classes that do this are said to be instance-controlled classes.There are several reasons to wirte instance-controlled classes.Instance contro allowsa a class to guarantee that it is a singleton or noninstantiable.Also,it allows an immutable value class to make the guarantee that no two equal instances exist: a.equals(b) if and only if a == b.This is the basis of the Flyweight pattern.Enum types provide this guarantee.

静态工厂方法从重复调用返回同一对象的能力允许类在任何时候保持对存在的实例的严格控制。可以做到这点的类被称为实例控制类。这里有几个要写实例控制类的原因。实例控制允许一个类去保证它的单例或者不可实例化。同样,它还允许不可变值类去保证没有两个相同实例的存在:当且仅当a==b时,a.equals(b)。这是享元模式的基础。枚举类型保证了这一点。

A third advantage of static factory methods is that,unlike constructors,they can return an object of any subtype of their return type.This gives you great flexibility in choosing the class of the returned object.

静态工厂方法的第三个好处是,他们可以返回一个返回值类型的任意一个子类型。这让你在选择返回对象时具有非常大的灵活性。

One application of this flexibility is that an API can return objects without making their classes public.Hiding implementation classes in this fashion leads to a very compact API.This technique lends itself to interface-based frameworks,where interfaces provide natural return types for static factory methods.

这种灵活性的一个应用就是API可以在不公开实现类信息的情况下返回对象。隐藏实现类的方式会使API非常的紧凑。这种技术衍生了很多基于接口的框架,接口为静态工厂方法提供原始返回类型。

Prior to Java 8,interfaces couldn't have static methods.By convention,static factory methods for an interface named Type were put in a noninstantiable companion class names Types.For example,The Java collections Framework has forty-five utility implementations of its interfaces,providing unmodifiable collections,synchronized collections,and the like.Nearly all of these implmentations are exported via static factory in one noninstantiable class(java.util.Collections).The classes of the returned objects are all nonpublic.

Java 8之前,接口不可以有静态方法。因此按照惯例,接口Type的静态工厂方法被放在一个名为Types的不可实例化的伴生类中。例如,Java Collections Framework 的集合接口有45个工具实现,分别提供了不了修改的集合、同步集合,等等。几乎所有这些实现都通过静态工厂方法在一个不可实例化的类(java.util.Collections)中导出。所有返回对象的类都是非公有的。

The collections Framework API is much smaller than it would have been had it exported forty-five separate public classes,one for each convenience implementation.It is not just the bulk of the API that is reduced but the conceptual weight: the number and  difficulty of the concepts that programmers must master in order to use the API.The programmer knows that the returned objects has precisely the API specified by its interface,so there is no need to read additional class documentation for the implementation class.Furthermore,using such a static factory method requires the client to refer to the returned object by interface rather than implementation class, which is generally good practice.

As of Java 8, the restriction that interfaces cannot contain static methods was eliminated, so there is typically little reason to provide a noninstantiable companion class for an interface. Many public static members that would have been at home in such a class should instead be put in the interface itself. Note,however, that it may still be necessary to put the bulk of the implementation code behind these static methods in a separate package-private class. This is because Java 8 requires all static members of an interface to be public.Java 9 allows private static methods,but static fields and static member classes are still required to be public.

你可能感兴趣的:(技术文章翻译系列)