Warning: file_get_contents(/data/phpspider/zhask/data//catemap/2/python/340.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181

Warning: file_get_contents(/data/phpspider/zhask/data//catemap/4/oop/2.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
Python 使用工厂与常规构造函数的优缺点_Python_Oop_Inheritance_Design Patterns_Class Factory - Fatal编程技术网

Python 使用工厂与常规构造函数的优缺点

Python 使用工厂与常规构造函数的优缺点,python,oop,inheritance,design-patterns,class-factory,Python,Oop,Inheritance,Design Patterns,Class Factory,(使用Python 3.2,但我怀疑这是否重要。) 我有类数据,类规则,类结果。我使用小写字母表示该类的一个实例 规则对象包含的规则如果应用于数据对象,可以创建结果对象 我正在决定将(相当复杂和不断发展的)代码放在哪里,这些代码实际上将规则应用于数据。我可以看到两种选择: 将该代码放入类Result方法中,比如说parse\u rulesResult构造函数将把rules对象作为参数,并将其传递给self.parse\u rules 将该代码放入一个新类ResultFactoryResultFa

(使用Python 3.2,但我怀疑这是否重要。)

我有
类数据
类规则
,类
结果
。我使用小写字母表示该类的一个实例

规则
对象包含的规则如果应用于
数据
对象,可以创建
结果
对象

我正在决定将(相当复杂和不断发展的)代码放在哪里,这些代码实际上将规则应用于数据。我可以看到两种选择:

  • 将该代码放入类
    Result
    方法中,比如说
    parse\u rules
    Result
    构造函数将把
    rules
    对象作为参数,并将其传递给
    self.parse\u rules

  • 将该代码放入一个新类
    ResultFactory
    ResultFactory
    将是一个单例类,它有一个方法,比如
    build\u result
    ,该方法将
    规则
    作为参数,并返回一个新生成的
    result
    对象

  • 这两种方法的优缺点是什么?

    提供了在面向对象设计中为类和对象分配职责的指南。例如,Creator模式建议:一般来说,如果以下一项或多项适用,则类B应负责创建类a的实例:

    • B的实例包含或复合聚合A的实例
    • B的实例记录A的实例
    • B的实例紧密地使用A的实例
    • B实例具有A实例的初始化信息,并在创建时传递该信息
    在您的示例中,您有复杂且不断发展的代码,用于将规则应用于数据。这意味着使用了

    禁止将代码放入结果中,因为1)结果不会创建结果,2)结果不是信息专家(即,他们不具备所需的大部分知识)


    简而言之,ResultFactory似乎是一个合理的地方,可以集中知识,了解如何将规则应用于数据以生成结果。如果您试图将所有这些逻辑推送到类构造函数中以获得结果或规则,则会导致紧密耦合和内聚性的丧失。

    好吧,第二个是非常愚蠢的,尤其是在所有单元素的情况下。如果
    Result
    需要
    Rules
    来创建实例,而没有它您就无法创建实例,那么它应该将此作为
    \uuuuuuu init\uuuu
    的参数。无需模式购物。

    为什么不将规则放在他们自己的类中?如果您创建一个规则基类,那么每个规则都可以从中派生。这样,当数据需要应用规则时,可以使用多态性。数据不需要知道或关心应用了哪些规则实例(除非数据本身知道应该应用哪些规则)

    当需要调用规则时,数据实例可以调用所有RuleBase.ExecuteRules()并将自身作为参数传入。如果数据知道需要哪个规则,则可以直接从数据中选择规则的正确子类。或者可以使用其他一些设计模式,比如责任链,其中数据调用该模式并返回结果


    这将是一个很好的白板讨论。

    你能让ResultFactory成为一个纯函数吗?如果您只需要一个函数,那么创建单例对象是没有用的。

    第三种情况:

    你可能想考虑第三种情况:

    • 将代码放入方法
      规则中。\uuuu调用\uuuu

      实例化
      Result
      类似:
      Result=规则(数据)
    优点:

    • 结果
      s可能完全不知道生成它们的
      规则(甚至可能不知道原始
      数据
    • 每个
      规则
      子类都可以自定义其
      结果
      创建
    • (对我来说)这感觉很自然:
      规则
      应用于
      数据
      产生
      结果
    • 你将掌握一些原则:
      • 创建者:规则的实例具有结果的实例的初始化信息,并在创建时传递
      • 信息专家:信息专家将负责将履行职责所需的大部分信息交给班级
    副作用:

    • 耦合:您将提高
      规则
      数据
      之间的耦合:
      • 您需要将整个数据集传递给每个
        规则
      • 这意味着每个
        规则
        都应该能够决定将应用哪些数据

    那么,在我的场景中,要让类工厂真正有意义,有什么需要改变的呢?@max:我不知道。运用常识,看看哪种方法更简单。我想将
    规则
    转换为工厂可能是一种选择,如果您可以通过构造函数传递所有数据来分别创建
    结果
    实例。但是如果您总是需要
    规则
    来创建
    结果
    ,那么它应该是一个ctor参数;我没有提到它,但是
    Rules
    是大型类层次结构的根。因此,如果我想将转换代码放入规则中,我当然可以将其放入这个层次结构的根中。感谢链接,我现在正在阅读Craig Larman的《它引用的书》。也许我误解了什么,但在我看来,Creator模式理所当然地认为A类实例是在A的构造函数中创建的,并且只讨论了哪个类应该调用该构造函数?请告诉我您的想法,以及是否可以解决您的问题。我仍然不确定什么是有效的;当我更好地理解时,我会更新。