代码之家  ›  专栏  ›  技术社区  ›  Hemanshu Bhojak

施工人员与工厂方法[关闭]

  •  153
  • Hemanshu Bhojak  · 技术社区  · 15 年前

    建模类时,初始化的首选方法是:

    1. 施工人员,或
    2. 工厂方法

    那么使用它们的注意事项是什么呢?

    在某些情况下,我更喜欢使用工厂方法,如果无法构造对象,则返回空值。这使得代码整洁。我可以在采取其他操作之前简单地检查返回值是否不为空,而不是从构造函数中抛出异常。(我个人不喜欢例外)

    比如,我在一个类上有一个构造函数,它需要一个ID值。构造函数使用此值从数据库填充类。如果不存在具有指定ID的记录,则构造函数将引发RecordNotFoundException。在这种情况下,我必须将所有此类类的构造包含在一个try..catch块中。

    与此相反,我可以在那些类上使用静态工厂方法,如果找不到记录,这些类将返回空值。

    在这种情况下,哪种方法更好,构造函数或工厂方法?

    10 回复  |  直到 6 年前
        1
  •  59
  •   reevesy onejigtwojig    12 年前

    摘自第108页 Design Patterns: Elements of Reusable Object-Oriented Software by Gamma, Helm, Johnson, and Vlissides.

    使用工厂方法模式

    • 类不能预测它必须创建的对象的类
    • 类希望其子类指定它创建的对象
    • 类将责任委托给几个助手子类中的一个,并且您希望本地化哪些助手子类是委托的知识。
        2
  •  174
  •   David Pokluda    15 年前

    问问你自己它们是什么,为什么我们有它们。它们都是用来创建对象实例的。

    ElementarySchool school = new ElementarySchool();
    ElementarySchool school = SchoolFactory.Construct(); // new ElementarySchool() inside
    

    到目前为止没有区别。现在假设我们有不同的学校类型,我们希望从使用elementschool切换到使用highschool(它来自elementschool或实现与elementschool相同的接口)。代码更改将是:

    HighSchool school = new HighSchool();
    HighSchool school = SchoolFactory.Construct(); // new HighSchool() inside
    

    在接口的情况下,我们将有:

    ISchool school = new HighSchool();
    ISchool school = SchoolFactory.Construct(); // new HighSchool() inside
    

    现在,如果您在多个地方使用了这个代码,您可以看到使用工厂方法可能非常便宜,因为一旦更改了工厂方法,您就完成了(如果我们将第二个示例与接口一起使用)。

    这是主要的区别和优势。当您开始处理复杂的类层次结构,并且希望从这样的层次结构动态创建类的实例时,您会得到以下代码。然后,工厂方法可以采用一个参数来告诉该方法要实例化什么具体实例。假设您有一个mystudent类,您需要实例化相应的ischool对象,以便您的学生是该学校的成员。

    ISchool school = SchoolFactory.ConstructForStudent(myStudent);
    

    现在,您的应用程序中有一个地方包含业务逻辑,用于确定要为不同的istudent对象实例化的ischool对象。

    所以-对于简单的类(值对象等),构造函数是很好的(您不想过度设计应用程序),但对于复杂的类层次结构,工厂方法是首选的方法。

    这样,您就可以遵循 gang of four book “程序到接口,而不是实现”。

        3
  •  63
  •   cherouvim    15 年前

    您需要阅读(如果您有权访问) Effective Java 2 第1项:考虑静态工厂方法而不是构造函数 .

    静态工厂方法的优点:

    1. 他们有名字。
    2. 每次调用它们时,不需要它们创建新对象。
    3. 它们可以返回其返回类型的任何子类型的对象。
    4. 它们减少了创建参数化类型实例的冗长性。

    静态工厂方法缺点:

    1. 当只提供静态工厂方法时,没有公共或受保护构造函数的类不能被子类化。
    2. 它们不容易与其他静态方法区分开来。
        4
  •  23
  •   G S    15 年前

    默认情况下,应该首选构造函数,因为它们更容易理解和编写。但是,如果您特别需要将对象的构造细节与客户机代码所理解的语义含义分离开来,那么最好使用工厂。

    构造器和工厂之间的区别类似于变量和指向变量的指针。还有另一个间接的层面,这是一个劣势;但也有另一个层面的灵活性,这是一个优势。因此,在做出选择的同时,我们建议您进行成本效益分析。

        5
  •  11
  •   Eugen Labun rbrayb    14 年前

    引用“有效Java”,第二版,项目1:考虑静态工厂方法而不是构造函数,第5页:

    “注意 静态工厂方法与工厂方法模式不同 从设计模式 [甘玛95,第107页]。中描述的静态工厂方法 此项在设计模式中没有直接等效项。“

        6
  •  11
  •   Hannele    9 年前

    仅当需要额外的对象创建控件时才使用工厂,这种方式无法用构造函数完成。

    例如,工厂有缓存的可能性。

    另一种使用工厂的方法是在您不知道要构造的类型的场景中。在插件工厂场景中经常会看到这种用法,其中每个插件必须派生自基类或实现某种接口。工厂创建从基类派生或实现接口的类的实例。

        7
  •  7
  •   RS Conley    15 年前

    来自CAD/CAM应用程序的具体示例。

    通过使用构造器可以生成切割路径。它是一系列线条和弧线,定义了切割的路径。虽然一系列的线和弧可以是不同的,并且具有不同的坐标,但通过将列表传递给构造函数,可以很容易地处理这些线和弧。

    一个形状将由一家工厂制造。因为虽然有一个形状类,但根据形状的类型,每个形状的设置都会有所不同。在用户做出选择之前,我们不知道要初始化什么形状。

        8
  •  5
  •   blue_note    6 年前

    除了 “有效Java” (如另一个答案所述) another classic book 还建议:

    与重载的构造函数相比,更喜欢静态工厂方法(具有描述参数的名称)。

    不要写

    Complex complex = new Complex(23.0);
    

    而是写

    Complex complex = Complex.fromRealNumber(23.0);
    

    这本书甚至建议 Complex(float) 构造函数私有,以强制用户调用静态工厂方法。

        9
  •  3
  •   Lightman    9 年前

    这个过程绝对应该在构造函数之外。

    1. 构造函数不应访问数据库。

    2. 任务和构造函数的原因是 初始化数据成员 并且 建立类不变量 使用传递给构造函数的值。

    3. 对于其他所有事情,更好的方法是使用 静态工厂法 或者在更复杂的情况下, 工厂 建设者 班级。

    Some constructor guide lines from Microsoft :

    在构造函数中做最少的工作。除了捕获构造函数参数外,构造函数不应该做太多的工作。任何其他处理的成本都应延迟到需要时为止。

        10
  •  0
  •   trashgenerator    6 年前

    var value = new Instance(1, 2).init()
    public function init() {
        try {
            doSome()
        }
        catch (e) {
            soAnotherSome()
        }
    }
    

    推荐文章