什么是“静态工厂”方法?
当前回答
工厂方法:将对象的实例化抽象出来的方法。一般来说,当你知道你需要一个实现接口的类的新实例,但你不知道实现类时,工厂是有用的。
这在处理相关类的层次结构时非常有用,GUI工具包就是一个很好的例子。您可以简单地对每个小部件的具体实现的构造函数进行硬编码调用,但是如果您想要将一个工具包交换为另一个工具包,那么您将有很多地方需要更改。通过使用工厂,您可以减少需要更改的代码数量。
其他回答
注意!“静态工厂方法与工厂方法模式不同”(c) Effective Java, Joshua Bloch。
工厂方法:定义一个用于创建对象的接口,但是让实现该接口的类来决定实例化哪个类。Factory方法允许类延迟实例化到子类“(c) GoF”。
静态工厂方法只是一个返回类实例的静态方法。(c)有效的Java,约书亚·布洛赫。通常这个方法在一个特定的类中。
的区别:
The key idea of static factory method is to gain control over object creation and delegate it from constructor to static method. The decision of object to be created is like in Abstract Factory made outside the method (in common case, but not always). While the key (!) idea of Factory Method is to delegate decision of what instance of class to create inside Factory Method. E.g. classic Singleton implementation is a special case of static factory method. Example of commonly used static factory methods:
返回对象的值 getInstance newInstance
我们避免提供对数据库连接的直接访问,因为它们是资源密集型的。因此,我们使用一个静态工厂方法getDbConnection,它在低于限制时创建一个连接。否则,它将尝试提供一个“备用”连接,如果没有则会出现异常而失败。
public class DbConnection{
private static final int MAX_CONNS = 100;
private static int totalConnections = 0;
private static Set<DbConnection> availableConnections = new HashSet<DbConnection>();
private DbConnection(){
// ...
totalConnections++;
}
public static DbConnection getDbConnection(){
if(totalConnections < MAX_CONNS){
return new DbConnection();
}else if(availableConnections.size() > 0){
DbConnection dbc = availableConnections.iterator().next();
availableConnections.remove(dbc);
return dbc;
}else {
throw new NoDbConnections();
}
}
public static void returnDbConnection(DbConnection dbc){
availableConnections.add(dbc);
//...
}
}
One of the advantages of the static factory methods with private constructor(object creation must have been restricted for external classes to ensure instances are not created externally) is that you can create instance-controlled classes. And instance-controlled classes guarantee that no two equal distinct instances exist(a.equals(b) if and only if a==b) during your program is running that means you can check equality of objects with == operator instead of equals method, according to Effective java.
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. There are several reasons to write instance-controlled classes. Instance control allows a class to guarantee that it is a singleton (Item 3) or noninstantiable (Item 4). Also, it allows an immutable class (Item 15) to make the guarantee that no two equal instances exist: a.equals(b) if and only if a==b. If a class makes this guarantee, then its clients can use the == operator instead of the equals(Object) method, which may result in improved performance. Enum types (Item 30) provide this guarantee.
摘自Effective Java, Joshua Bloch(第1项,第6页)
可读性可以通过静态工厂方法来提高:
比较
public class Foo{
public Foo(boolean withBar){
//...
}
}
//...
// What exactly does this mean?
Foo foo = new Foo(true);
// You have to lookup the documentation to be sure.
// Even if you remember that the boolean has something to do with a Bar
// you might not remember whether it specified withBar or withoutBar.
to
public class Foo{
public static Foo createWithBar(){
//...
}
public static Foo createWithoutBar(){
//...
}
}
// ...
// This is much easier to read!
Foo foo = Foo.createWithBar();
静态工厂的优点之一是API可以返回对象,而不需要将它们的类设为public。这导致了非常紧凑的API。在java中,这是通过Collections类实现的,它隐藏了大约32个类,这使得它的集合API非常紧凑。
推荐文章
- 在流中使用Java 8 foreach循环移动到下一项
- 访问限制:'Application'类型不是API(必需库rt.jar的限制)
- 用Java计算两个日期之间的天数
- 如何配置slf4j-simple
- 在Jar文件中运行类
- 带参数的可运行?
- 我如何得到一个字符串的前n个字符而不检查大小或出界?
- 我可以在Java中设置enum起始值吗?
- Java中的回调函数
- c#和Java中的泛型有什么不同?和模板在c++ ?
- 在Java中,流相对于循环的优势是什么?
- Jersey在未找到InjectionManagerFactory时停止工作
- 在Java流是peek真的只是调试?
- Recyclerview不调用onCreateViewHolder
- 将JSON字符串转换为HashMap