Warning: file_get_contents(/data/phpspider/zhask/data//catemap/4/video/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
Oop 面向对象初始化策略_Oop_Constructor - Fatal编程技术网

Oop 面向对象初始化策略

Oop 面向对象初始化策略,oop,constructor,Oop,Constructor,我经常需要在对象设计的这两种策略之间做出选择: 一种完全初始化的对象,在构造后可以使用。构造函数通常需要一个复杂的参数列表,因此对象初始化非常重要。所有将其作为成员变量的对象也需要非平凡的构造函数。这可能导致代码的复杂性集中在对象构造函数上,通常使代码难以理解 具有默认构造函数的对象。通过setter方法单独设置对象变量。这种方法的缺点是,大多数方法需要检查对象是否已完全初始化,从而使代码复杂化 你个人对两者的偏好是什么?你如何决定何时使用一个或另一个?在我看来,如果构造函数过于臃肿,那么是时候

我经常需要在对象设计的这两种策略之间做出选择:

  • 一种完全初始化的对象,在构造后可以使用。构造函数通常需要一个复杂的参数列表,因此对象初始化非常重要。所有将其作为成员变量的对象也需要非平凡的构造函数。这可能导致代码的复杂性集中在对象构造函数上,通常使代码难以理解
  • 具有默认构造函数的对象。通过
    setter方法
    单独设置对象变量。这种方法的缺点是,大多数方法需要检查对象是否已完全初始化,从而使代码复杂化

  • 你个人对两者的偏好是什么?你如何决定何时使用一个或另一个?

    在我看来,如果构造函数过于臃肿,那么是时候将对象拆分为更多不同的更小的对象了。在一些罕见的情况下,这可能是不可能的,但在大多数情况下,这是可以做到的。

    在我看来,如果构造函数过于臃肿,那么是时候将对象拆分为更多不同、更小的对象了。在一些罕见的情况下,这可能是不可能的,但在大多数情况下,这是可以做到的。

    初始化构造函数中的所有变量总是好的,但要将其设置为默认值。如果很难获取变量的值(例如,您必须调用某个函数才能获取该值),可以将该值设置为无效值,然后再设置正确的值

    让构造函数如此复杂不是一个好主意,因为你不能在构造函数中返回错误(我不知道在构造函数中抛出异常是否合适,因为我特别不喜欢在任何地方显示异常)。此外,您不能在那里调用虚拟函数,等等

    当类的构造很复杂时,我喜欢的一种方法是创建一个“init”函数。然后我可以做一些类似的事情:

    Person::Person()
    {
        age = -1;
        ...
    }
    
    int Person::Init()
    {
        age = functionThatReturnsTheAgeFromSomeDB();
        if (age == -1 )
        {
            return DB_ERROR;
        }
        ...
    }
    

    依此类推。

    初始化构造函数中的所有变量总是很好的,但是要初始化为默认值。如果很难获取变量的值(例如,您必须调用某个函数才能获取该值),可以将该值设置为无效值,然后再设置正确的值

    让构造函数如此复杂不是一个好主意,因为你不能在构造函数中返回错误(我不知道在构造函数中抛出异常是否合适,因为我特别不喜欢在任何地方显示异常)。此外,您不能在那里调用虚拟函数,等等

    当类的构造很复杂时,我喜欢的一种方法是创建一个“init”函数。然后我可以做一些类似的事情:

    Person::Person()
    {
        age = -1;
        ...
    }
    
    int Person::Init()
    {
        age = functionThatReturnsTheAgeFromSomeDB();
        if (age == -1 )
        {
            return DB_ERROR;
        }
        ...
    }
    

    依此类推。

    如果一个构造函数接受许多参数——你称之为非平凡的对象初始化——并且你不想把你的类拆分成更小的类,那么另一种选择是将参数放入一个构造函数中,然后只将该对象传递给构造函数

    第二,我认为你应该区分

    • 对象属性,如果该对象要执行其工作,则绝对必须设置该属性,并且没有合理的默认值。这些属性应该通过构造函数参数初始化

    • 用户可以选择设置或覆盖的对象属性。虽然可以在构造函数中初始化这些属性,但不必为它们设置单独的构造函数参数。相反,您可以为它们指定一个合理的默认值,用户仍然可以通过setter方法覆盖该值

    第一种类型的属性(必须绝对具有用户提供的值)还有另一种选择:通过重写派生类中的抽象getter提供的属性:

    抽象类复杂化{
    受保护的抽象T getSomeDependency();//替换必需的ctor参数
    }
    

    p.S.:这本书很好地概述了初始化一个对象的各种方法。

    如果一个构造函数有很多参数,你称之为非平凡的对象初始化,你不想把你的类分成更小的类,另一种方法是将参数放入一个构造函数中,然后只将该对象传递给构造函数

    第二,我认为你应该区分

    • 对象属性,如果该对象要执行其工作,则绝对必须设置该属性,并且没有合理的默认值。这些属性应该通过构造函数参数初始化

    • 用户可以选择设置或覆盖的对象属性。虽然可以在构造函数中初始化这些属性,但不必为它们设置单独的构造函数参数。相反,您可以为它们指定一个合理的默认值,用户仍然可以通过setter方法覆盖该值

    第一种类型的属性(必须绝对具有用户提供的值)还有另一种选择:通过重写派生类中的抽象getter提供的属性:

    抽象类复杂化{
    受保护的抽象T getSomeDependency();//替换必需的ctor参数
    }
    
    p.S.:这本书很好地概述了初始化对象的各种方法。

    。 庞大的参数列表表明对象执行了太多操作。在对象具有有效和有用的输出之前,需要设置许多属性,这表明它做得太多了。 因此,就我而言,这两种方法都不是解决方案

    有很多方法可以解决这些问题,但在特定场景之外,唯一的规则是“它需要做”

    聚合到其他对象、“控制器”类、各种通信