什么是“静态工厂”方法?


当前回答

静态工厂的优点之一是API可以返回对象,而不需要将它们的类设为public。这导致了非常紧凑的API。在java中,这是通过Collections类实现的,它隐藏了大约32个类,这使得它的集合API非常紧凑。

其他回答

当您希望确保只有一个实例将返回要使用的具体类时,静态工厂方法很好。

例如,在一个数据库连接类中,您可能希望只有一个类创建数据库连接,因此如果您决定从Mysql切换到Oracle,您只需更改一个类中的逻辑,而应用程序的其余部分将使用新的连接。

如果您希望实现数据库池,那么也可以在不影响应用程序其余部分的情况下完成。

它保护应用程序的其余部分不受您可能对工厂所做的更改的影响,这就是目的。

它是静态的原因是,如果你想跟踪一些有限的资源(套接字连接或文件句柄的数量),那么这个类可以跟踪已经传递和返回了多少,这样你就不会耗尽有限的资源。

静态工厂的优点之一是API可以返回对象,而不需要将它们的类设为public。这导致了非常紧凑的API。在java中,这是通过Collections类实现的,它隐藏了大约32个类,这使得它的集合API非常紧凑。

这一切都归结为可维护性。最好的方式是,无论何时使用new关键字创建对象,都是将所编写的代码耦合到实现中。

The factory pattern lets you separate how you create an object from what you do with the object. When you create all of your objects using constructors, you are essentially hard-wiring the code that uses the object to that implementation. The code that uses your object is "dependent on" that object. This may not seem like a big deal on the surface, but when the object changes (think of changing the signature of the constructor, or subclassing the object) you have to go back and rewire things everywhere.

如今,由于依赖注入需要大量的样板代码,而这些代码本身维护起来有点困难,工厂在很大程度上被忽略了。依赖注入基本上等同于工厂,但允许你以声明的方式(通过配置或注释)指定你的对象如何连接在一起。

静态

用关键字'static'声明的成员。

工厂方法

方法,用于创建和返回新对象。

在Java中

编程语言与“静态”的含义相关,但与“工厂”的定义无关。

我们避免提供对数据库连接的直接访问,因为它们是资源密集型的。因此,我们使用一个静态工厂方法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);
     //...
   }
}