代码之家  ›  专栏  ›  技术社区  ›  user8852560

构造函数中的验证和构造函数冲突

  •  1
  • user8852560  · 技术社区  · 6 年前

    我在这里看书( 1 , 2 )我想知道是否确保初始化期间提供的参数正确,违反了构造函数不应该工作的准则。

    例如(Python):

    class Employee:
        def __init__(self, empFirstname, empLastname, empEmail):
    
            self._validate_employee(empFirstname, "First Name")
            self._validate_employee(empLastname, "Last name")
            self._validate_employee(empEmail, "Email")
            self._validate_email(empEmail, "Email")
    
            self.empFirstname = empFirstname
            self.empLastname = empLastname
            self.empEmail = empEmail
    
        @property
        def email(self):
            return self.empEmail
    
        def _validate_employee(self, parameter, error_message):
            if not parameter:
                raise TypeError("{0} {1}" .format(error_message, "is missing"))
    
        def _validate_email(self, email, parameter):
            if "@" not in email or "." not in email:
                raise TypeError("{0} {1}" .format(parameter, " is invalid"))
    

    在我的示例中,我检查以确保名字和姓氏不是空白的,并且电子邮件是有效的。我违反了规定吗?

    更新: 我不是问它是否应该抛出,我是问我是否违反了构造函数在验证我的参数时不应该工作的准则。

    2 回复  |  直到 6 年前
        1
  •  0
  •   Alexander Kogtenkov    6 年前

    提供满足某些条件的参数的要求是 Design by Contract ,即它对应于先决条件。客户端(在您的案例中是构造函数的客户端)应该保证参数如预期的那样。如果不是这样,则供应商(您案例中的构造函数)无法确保生成的对象在构造函数返回后处于有效状态。在本机支持契约式设计的语言中,人们会关联一个类不变量,说明名称不是空的,并且电子邮件地址遵循命名约定。只有当传递给构造函数的参数有效时,才能实现这一点。

    您提到的条件将作为先决条件编写,可以根据软件开发过程中制定的策略打开或关闭。启用后,在执行构造函数的实体之前,在进入构造函数时检查它们。从这个角度来看,您的代码没有做任何额外的工作,但要确保参数是正确的。在确保始终满足先决条件的程序验证,或给人以客户未违反先决条件感觉的广泛测试之后,可以禁用它们,从而删除任何“额外工作”。

    • 示例中的“附加代码”是先决条件
    • 前提条件是软件合同的一部分
    • 根据所采用的策略,可以启用或禁用合同检查,只要所有客户端保证不违反先决条件,就可以安全地禁用它们,从而从构造函数(或任何其他软件组件)中删除任何“额外工作”
        2
  •  0
  •   JGrindal    6 年前

    不,验证参数和输入对于所有函数都至关重要,包括构造函数。在没有检查/错误处理的情况下盲目设置参数可能会导致严重问题,从意外的性能到恶意参与者以非预期方式操纵程序的能力。