使用工厂方法进行对象实例化

时间:2013-09-13 22:44:01

标签: java oop

我目前正在参加CS2课程(数据结构),其中Java是使用的语言,我有兴趣使用传统的构造函数方法比较和对比对象实例。工厂方法。一个人比另一个代表更高程度的计算优雅吗?工厂方法是否会以类似于参数化构造函数的方式处理参数? E.g:

public class Tester
{
    private String name;
    private int age;

    // Parameterized constructor  
    public Tester(String myName, int myAge)
    {
        this.name = myName;
        this.age = myAge; 
    }
} 

基本上,我非常好奇如何编写一个等效的工厂方法以及这样做的潜在好处。

谢谢,

〜凯特琳

3 个答案:

答案 0 :(得分:3)

工厂方法很好,因为它们可以返回对不一定是该类实例的对象的引用。它可以返回该类,子类型,甚至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
    }
} 

答案 1 :(得分:2)

工厂在特定情况下很有用:

  1. 根据参数,可以返回对象的几个不同子类中的一个。
  2. 有些人需要“保护”对象的创建,可能是为了安全,也许是为了某种同步。
  3. 创建对象需要在创建后以某种方式“注册”,并且在构造函数中这样做是不可行的。
  4. 除非必须创建实例,否则甚至不想加载(实际)类(及其引用类的树)。
  5. 如果上述某些原因不存在,那么工厂方法没有任何好处,它们只是模糊了逻辑。

    对于工厂可以做什么没有实际的限制,因为它可以(如果设置正确)访问不能被hoi polloi访问的包级别构造函数和接口。

    已添加:解决“继承”问题 -

    假设我们有汽车和卡车子类的经典车辆示例。如果您只是拥有CarFactory和TruckFactory,那么就会无缘无故地增加代码的复杂性(除非有其他令人信服的理由使用工厂)。

    但是你可以拥有一个VehicleFactory并让它根据输入或外部因素“决定”创建汽车或卡车。这是一种相当普遍的模式。

    但是,如果您(由于某种原因)拥有仅创建了Vehicle对象(而不是汽车或卡车)的VehicleFactory,并且如果必须使用工厂(您无法访问Vehicle的构造函数),那么基本上不可能将Vehicle子类化。当你使用工厂时,你很难(至少)让其他人添加新的子类。

答案 2 :(得分:2)

根据Effective Java中有充分理由的观察结果,静态工厂方法的主要优点如下:

  • 您可以为它们命名,不像构造函数必须始终以类命名。这使得代码更具可读性,并且可以避免由于参数类型相同而导致重载构造函数不可能的丑陋情况等。在这种情况下,您可以轻松地提供两个具有不同名称的工厂方法来指示差异。

  • 与必须创建新实例的构造函数不同,实际上不需要静态工厂方法。因此,静态工厂方法对于实例控制的类(例如,单例类)至关重要。

  • 与构造函数不同,只要返回的对象匹配或者是返回类型的子类,静态工厂方法就可以返回任何对象。这使基于接口的类型系统成为可能。 Java 1.5的Enum框架使用了这个:EnumSet类没有公共构造函数,只有静态工厂。静态工厂返回的实际对象取决于枚举的大小。

静态工厂的主要缺点是它们不能成为为继承而设计的类的基础。只提供私有构造函数的类不能被子类化。静态工厂方法的一个小缺点是它们无法与其他静态方法区分开来,因此为了使它们能够被读者识别,它们通常遵循命名模式(如果将这样的设计作为标记注释,则可以对它们进行注释)对于静态工厂方法)。