问题描述
什么是"静态工厂"方法?
推荐答案
我们避免提供对数据库连接的直接访问,因为它们是资源密集的.因此,我们使用静态出厂方法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); //... } }
其他推荐答案
静态出厂方法模式是一种封装对象的方式创建.没有工厂方法,您只需称呼该类的 constructor "> constructor 直接:Foo x = new Foo().使用此模式,您将调用工厂方法:Foo x = Foo.create().构造函数是私人标记的,因此除了从类内部外,不能被调用,并且工厂方法被标记为 static ,以便可以不首先具有对象.
这种模式有一些优势.一个是工厂可以从许多子类(或接口的实现者)中进行选择,然后返回.这样,呼叫者可以通过参数指定所需的行为,而无需了解或理解潜在的复杂类层次结构.
正如Matthew和James指出的那样,另一个优势是控制对有限资源(例如Connections)的访问.这是实现可重复使用对象的池 - 而不是使用和拆除对象, ,如果施工和破坏是昂贵的过程,那么建造一次并回收它们可能更有意义.如果对象计数低于某个阈值,则工厂方法可以返回现有未使用的实例化对象,或者如果对象计数低于某个阈值,则可以返回一个,或者如果该对象在上阈值之上,则可以返回异常或返回null.
.根据Wikipedia的文章,多种工厂方法还允许对类似参数类型的不同解释.通常,构造函数的名称与该类具有相同的名称,这意味着您只能拥有一个带有给定的 signature ">签名.工厂不是那么限制,这意味着您可以拥有两种不同的方法来接受相同的参数类型:
Coordinate c = Coordinate.createFromCartesian(double x, double y)
和
Coordinate c = Coordinate.createFromPolar(double distance, double angle)
这也可以用来提高可读性,如拉斯姆斯注意.
其他推荐答案
注意! " 静态工厂方法是不是与工厂方法模式相同"(c)有效的Java,Joshua Bloch.
工厂方法:"定义用于创建对象的接口,但让实现接口的类决定要实例化的类.工厂方法让类延迟实例化为子类"(c)GOF.
."静态出厂方法只是返回类实例的静态方法." (c)有效的Java,Joshua Bloch.通常此方法在特定类中.
差异:
静态出厂方法的关键思想是获得对对象创建的控制,并将其从构造函数到静态方法委派.要创建的对象的决定就像在方法之外做出的抽象工厂一样(通常情况下,但并非总是如此).虽然工厂方法的关键(!)想法是委派出在工厂方法内创建哪个类实例的决策.例如.经典的Singleton实施是静态工厂方法的特殊情况.常用静态工厂方法的示例:
- valueof
- getinstance
- newinstance
问题描述
What's a "static factory" method?
推荐答案
We avoid providing direct access to database connections because they're resource intensive. So we use a static factory method getDbConnection that creates a connection if we're below the limit. Otherwise, it tries to provide a "spare" connection, failing with an exception if there are none.
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); //... } }
其他推荐答案
The static factory method pattern is a way to encapsulate object creation. Without a factory method, you would simply call the class's constructor directly: Foo x = new Foo(). With this pattern, you would instead call the factory method: Foo x = Foo.create(). The constructors are marked private, so they cannot be called except from inside the class, and the factory method is marked as static so that it can be called without first having an object.
There are a few advantages to this pattern. One is that the factory can choose from many subclasses (or implementers of an interface) and return that. This way the caller can specify the behavior desired via parameters, without having to know or understand a potentially complex class hierarchy.
Another advantage is, as Matthew and James have pointed out, controlling access to a limited resource such as connections. This a way to implement pools of reusable objects - instead of building, using, and tearing down an object, if the construction and destruction are expensive processes it might make more sense to build them once and recycle them. The factory method can return an existing, unused instantiated object if it has one, or construct one if the object count is below some lower threshold, or throw an exception or return null if it's above the upper threshold.
As per the article on Wikipedia, multiple factory methods also allow different interpretations of similar argument types. Normally the constructor has the same name as the class, which means that you can only have one constructor with a given signature. Factories are not so constrained, which means you can have two different methods that accept the same argument types:
Coordinate c = Coordinate.createFromCartesian(double x, double y)
and
Coordinate c = Coordinate.createFromPolar(double distance, double angle)
This can also be used to improve readability, as Rasmus notes.
其他推荐答案
NOTE! "The static factory method is NOT the same as the Factory Method pattern" (c) Effective Java, Joshua Bloch.
Factory Method: "Define an interface for creating an object, but let the classes which implement the interface decide which class to instantiate. The Factory method lets a class defer instantiation to subclasses" (c) GoF.
"Static factory method is simply a static method that returns an instance of a class." (c) Effective Java, Joshua Bloch. Usually this method is inside a particular class.
The difference:
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:
- valueOf
- getInstance
- newInstance