Java 使用工厂方法进行对象实例化
我目前参加了CS2课程(数据结构),其中Java是使用的语言,我对使用传统构造函数方法与工厂方法比较和对比对象实例化感兴趣。一个代表了比另一个更高的计算优雅度吗?工厂方法是否会以类似于参数化构造函数的方式处理参数?例如:Java 使用工厂方法进行对象实例化,java,oop,Java,Oop,我目前参加了CS2课程(数据结构),其中Java是使用的语言,我对使用传统构造函数方法与工厂方法比较和对比对象实例化感兴趣。一个代表了比另一个更高的计算优雅度吗?工厂方法是否会以类似于参数化构造函数的方式处理参数?例如: public class Tester { private String name; private int age; // Parameterized constructor public Tester(String myName, in
public class Tester
{
private String name;
private int age;
// Parameterized constructor
public Tester(String myName, int myAge)
{
this.name = myName;
this.age = myAge;
}
}
本质上,我很好奇如何编写一个等效的工厂方法,以及这样做的潜在好处是什么
谢谢
~Caitlin工厂方法很好,因为它们可以返回对对象的引用,而对象不一定是该类的实例。它可以返回那个类、一个子类型,甚至
null
,并且通常按照方法所能实现的任何方式执行。因此,您可以将选择类型的逻辑移动到您自己的代码中。您可以在适当的地方返回现有实例,以节省堆空间等
另一个基本的伪示例是Integer.forValue()
,它可以插入一个整数,因此不会无缘无故地重新创建相同的不可变对象。另请参见Executors.newXxxThreadPool()
一个基本的例子:
public class Tester
{
private String name;
private int age;
// Parameterized constructor
private Tester(String myName, int myAge)
{
this.name = myName;
this.age = myAge;
}
public static Tester getTester(String mn, int ag){
if(age>0){return new Tester(mn, ag);}
else if(age>80){return new OldPersonThatExtendsTester(mn, ag);}
//we'd need a public or otherwise accessible constructor above. It's a subtype!
else {return null;} //yes, this is possible
}
}
工厂在特定情况下非常有用:
但是,如果您(出于某种原因)拥有一个只创建车辆对象(而不是汽车或卡车)的VehicleFactory,并且如果强制使用该工厂(您无法访问车辆的构造器),则基本上不可能对车辆进行子类化。当您使用工厂时,您会使其他人很难(至少)添加新的子类。根据有效Java中的合理观察,静态工厂方法的主要优点如下:
- 您可以命名它们,而构造函数必须始终以类命名。这使得代码更具可读性,并且可以避免由于参数类型相同等原因导致重载构造函数不可能实现的糟糕情况。在这种情况下,您可以轻松提供两个具有不同名称的工厂方法来指示差异
- 与必须创建新实例的构造函数不同,静态工厂方法不需要实际实例化任何东西。因此,静态工厂方法对于实例控制的类(例如单例类)是必不可少的
- 与构造函数不同,静态工厂方法可以返回任何对象,只要返回的对象匹配或是返回类型的子类。这将启用基于接口的类型系统。Java1.5的Enum框架利用了这一点:EnumSet类没有公共构造函数,只有静态工厂。静态工厂返回的实际对象因枚举的大小而异
静态工厂的主要缺点是它们不能作为为继承而设计的类的基础。只能提供私有构造函数的类不能被子类化。静态工厂方法的一个小缺点是它们无法与其他静态方法区分开来,因此为了让读者能够识别它们,它们通常遵循命名模式(如果这种模式被设计为静态工厂方法的标记注释,则可以对其进行注释).看看这个:Joshua Bloch的Essential Java,第2版中的第1项是关于赞美静态工厂方法的优点和许多优点,作为构造函数获取对新实例化对象的引用的真正替代方法。EssentialJava对于任何希望获得Java专业知识的人来说都是一本极好的读物(出于许多原因)。我建议您获取并阅读它。工厂方法模式的一个真实示例是
ExecutorService es=Executors。newXxxThreadPool()
对于设计用于继承的类,静态工厂方法通常不是好的选择。@scottb您能解释一下为什么吗?我打算读“基本Java”,但同时…非常好。非常感谢。