什么是静态工厂方法?
我们避免直接访问数据库连接,因为它们占用大量资源。因此getDbConnection,如果我们低于限制,我们将使用静态工厂方法来创建连接。否则,它将尝试提供“备用”连接,如果不存在则失败,并显示异常。
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); //... } }
该静态工厂方法模式是一种封装对象的创建。如果没有工厂方法,则只需直接调用类的构造函数:Foo x = new Foo()。使用这种模式,你可以改为调用factory方法: Foo x = Foo.create()。构造函数被标记为私有,因此只能从类内部调用它们,并且将工厂方法标记为,static以便无需首先具有对象就可以对其进行调用。
Foo x = new Foo()
Foo x = Foo.create()
这种模式有一些优点。一种是工厂可以从许多子类(或接口的实现者)中进行选择并返回。这样,调用者可以通过参数指定所需的行为,而不必了解或理解潜在的复杂类层次结构。
正如Matthew和James指出的那样,另一个优势是控制对有限资源(例如连接)的访问。这是一种实现可重用对象池的方法-而不是构建,使用和拆除对象,如果构建和销毁是昂贵的过程,则一次构建并回收它们可能更有意义。工厂方法可以返回一个现有的,未使用的实例化对象(如果有),或者如果对象计数低于某个下限阈值则构造一个实例,或者如果该对象null高于上限阈值则抛出异常或返回。
根据Wikipedia上的文章,多种工厂方法还允许对类似参数类型进行不同的解释。通常,构造函数与类具有相同的名称,这意味着你只能有一个具有给定签名的构造函数。工厂并不是那么受约束,这意味着你可以有两种接受相同参数类型的不同方法:
Coordinate c = Coordinate.createFromCartesian(double x, double y)
和
Coordinate c = Coordinate.createFromPolar(double distance, double angle)
正如Rasmus指出的那样,这也可以用来提高可读性。