Jas*_*wen 455
该静态工厂方法模式是封装对象创建的一种方式.如果没有工厂方法,您只需直接调用类的构造函数:Foo x = new Foo()
.使用此模式,您将调用工厂方法: Foo x = Foo.create()
.构造函数被标记为私有,因此除了从类内部调用它们之外不能调用它们,并且工厂方法被标记为static
可以在没有第一个对象的情况下调用它.
这种模式有一些优点.一个是工厂可以从许多子类(或接口的实现者)中进行选择并返回它.这样,调用者可以通过参数指定所需的行为,而无需了解或理解可能复杂的类层次结构.
另一个优点是,正如Matthew和James所指出的那样,控制对诸如连接之类的有限资源的访问.这是一种实现可重用对象池的方法- 而不是构建,使用和拆除对象,如果构造和销毁是昂贵的过程,那么构建它们并回收它们可能更有意义.工厂方法可以返回现有的,未使用的实例化对象(如果有),或者如果对象计数低于某个下限阈值则构造一个,或者null
如果它高于上限阈值则抛出异常或返回.
根据维基百科上的文章,多个工厂方法也允许对类似参数类型的不同解释.通常,构造函数与类具有相同的名称,这意味着您只能拥有一个具有给定签名的构造函数.工厂不受限制,这意味着您可以使用两种不同的方法来接受相同的参数类型:
Coordinate c = Coordinate.createFromCartesian(double x, double y)
Run Code Online (Sandbox Code Playgroud)
和
Coordinate c = Coordinate.createFromPolar(double distance, double angle)
Run Code Online (Sandbox Code Playgroud)
Rasmus指出,这也可用于提高可读性.
Gry*_*har 163
注意!"该静态工厂方法是不一样的工厂方法模式"(三)有效的Java,约书亚·布洛克.
工厂方法:"定义用于创建对象的接口,但让实现接口的类决定实例化哪个类.Plant方法允许类将实例化延迟到子类"(c)GoF.
"静态工厂方法只是一个返回类实例的静态方法." (c)有效的Java,Joshua Bloch.通常此方法位于特定类中.
区别:
静态工厂方法的关键思想是控制对象创建并将其从构造函数委托给静态方法.要创建的对象的决定就像在方法之外的抽象工厂中做出的(通常情况下,但并非总是如此).而Factory方法的关键(!)思想是委托在Factory Method中创建类的实例的决定.例如,经典的Singleton实现是静态工厂方法的一个特例.常用的静态工厂方法示例:
Mat*_*hen 119
我们避免提供对数据库连接的直接访问,因为它们是资源密集型的.因此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);
//...
}
}
Run Code Online (Sandbox Code Playgroud)
Ras*_*ber 67
可通过静态工厂方法改进可读性:
相比
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.
Run Code Online (Sandbox Code Playgroud)
至
public class Foo{
public static Foo createWithBar(){
//...
}
public static Foo createWithoutBar(){
//...
}
}
// ...
// This is much easier to read!
Foo foo = Foo.createWithBar();
Run Code Online (Sandbox Code Playgroud)
sol*_*oth 20
- 有一些名称,不像构造函数,可以澄清代码.
- 不需要在每次调用时创建新对象 - 如有必要,可以缓存和重用对象.
- 可以返回其返回类型的子类型 - 特别是,可以返回调用者未知其实现类的对象.在许多框架中,这是一个非常有价值且广泛使用的特性,它使用接口作为静态工厂方法的返回类型.
来自http://www.javapractices.com/topic/TopicAction.do?Id=21
cwa*_*ash 18
这一切都归结为可维护性.放置它的最佳方法是,只要您使用new
关键字创建对象,就可以将要写入的代码与实现相结合.
工厂模式允许您将对象的创建方式与对象的创建方式分开.使用构造函数创建所有对象时,基本上是将使用该对象的代码硬连接到该实现.使用您的对象的代码"依赖于"该对象.这似乎在表面上看起来不是什么大问题,但是当对象发生变化时(考虑改变构造函数的签名,或者对对象进行子类化),你必须返回并重新布线.
今天,工厂基本上已被抛弃,转而使用依赖注入,因为它们需要大量的锅炉板代码,这些代码结果有点难以维护.依赖注入基本上等同于工厂,但允许您指定对象如何以声明方式(通过配置或注释)连接在一起.
San*_*osh 11
如果类的构造函数是私有的,那么您就无法从其外部为类创建对象.
class Test{
int x, y;
private Test(){
.......
.......
}
}
Run Code Online (Sandbox Code Playgroud)
我们不能从它外面为上面的类创建一个对象.所以你不能从课堂外访问x,y.那么这堂课的用途是什么?
这是答案:FACTORY方法.
在上面的类中添加以下方法
public static Test getObject(){
return new Test();
}
Run Code Online (Sandbox Code Playgroud)
所以现在你可以从它外面为这个类创建一个对象.喜欢的方式......
Test t = Test.getObject();
Run Code Online (Sandbox Code Playgroud)
因此,通过执行其私有构造函数返回类对象的静态方法称为FACTORY方法
.
我想我会在这篇文章中为我所知道的内容添加一些亮点.我们在我们的广泛使用这项技术recent android project
.而不是creating objects using new operator
你也可以static method
用来实例化一个类.代码清单:
//instantiating a class using constructor
Vinoth vin = new Vinoth();
//instantiating the class using static method
Class Vinoth{
private Vinoth(){
}
// factory method to instantiate the class
public static Vinoth getInstance(){
if(someCondition)
return new Vinoth();
}
}
Run Code Online (Sandbox Code Playgroud)
静态方法支持条件对象创建:每次调用构造函数时,都会创建一个对象,但您可能不希望这样.假设您只想检查某些条件,然后才想创建一个新对象.除非满足条件,否则每次都不会创建Vinoth的新实例.
另一个来自Effective Java的例子.
public static Boolean valueOf(boolean b) {
return (b ? TRUE : FALSE);
}
Run Code Online (Sandbox Code Playgroud)
此方法将布尔基元值转换为布尔对象引用.该Boolean.valueOf(boolean)
方法说明了我们,它永远不会创建一个对象.static factory methods
从重复返回同一对象的能力invocations
允许类在任何时候保持对存在的实例的严格控制.
Static factory methods
就是这样,constructors
他们可以返回object
任何subtype
一种返回类型.这种灵活性的一个应用是API可以在不公开其类的情况下返回对象.以这种方式隐藏实现类会导致非常紧凑的API.
Calendar.getInstance()是上面的一个很好的例子,它根据语言环境a创建BuddhistCalendar
,JapaneseImperialCalendar
或者默认创建一个Georgian
.
我能想到的另一个例子是Singleton pattern
,你将构造函数私有化的地方创建了一个自己的getInstance
方法,你可以确保只有一个实例可用.
public class Singleton{
//initailzed during class loading
private static final Singleton INSTANCE = new Singleton();
//to prevent creating another instance of Singleton
private Singleton(){}
public static Singleton getSingleton(){
return INSTANCE;
}
}
Run Code Online (Sandbox Code Playgroud)