1

I was doing some reading here(1,2) and I was wondering if making sure the parameters provided during initialization are correct, violates the guideline that constructors shouldn't do work.

For example (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"))

In my example, I check to make sure the first and last names aren't blank and that the email is valid. Did I violate the guideline?

Update: I'm not asking if it should throw, I'm asking if I'm violating the guideline that constructors shouldn't do work when it validates my parameters.

  • Possible duplicate of [When is it right for a constructor to throw an exception?](https://stackoverflow.com/questions/77639/when-is-it-right-for-a-constructor-to-throw-an-exception) – Raedwald Nov 13 '17 at 09:50

2 Answers2

0

No, validating parameters and inputs is vital for all functions, including constructors. Blindly setting parameters without checking/error handling can lead to serious issues ranging from unexpected performance to the ability for malicious actors to manipulate your program in ways that it was not intended.

JGrindal
  • 793
  • 2
  • 8
  • 23
0

The requirement to provide arguments that satisfy certain conditions is a part of Design by Contract, namely it corresponds to preconditions. The client (of a constructor in your case) should guarantee that the arguments are as expected. If this is not the case, the supplier (the constructor in your case) cannot ensure the resulting object is in a valid state after the constructor returns. In languages that support Design by Contract natively, one would associate a class invariant stating that the names are not empty and the email address follows the naming convention. This could be achieved only when the arguments passed to the constructor are valid.

The conditions you mention would be written as preconditions and could be turned on or off depending on the policy established in the software development process. When enabled, they are checked on entry to the constructor, before its real body is executed. From this point of view, your code is not doing any additional work, but makes sure the arguments are correct. After program verification that ensures the preconditions are satisfied all the time, or extensive testing that gives the feeling that the preconditions are not violated by the client, they can be disabled, thus removing any "additional work".

To summarize:

  • the "additional code" in your examples are preconditions
  • preconditions are part of software contracts
  • the checks of the contracts can be enabled or disabled depending on the adopted policy, it is safe to disable them as soon as all clients guarantee the preconditions are never violated, thus removing any "additional work" from the constructor (or any other software component)
Alexander Kogtenkov
  • 5,770
  • 1
  • 27
  • 35
  • Before I select this as my answer, if I understand you correctly, I'm not violating the rule that the constructor shouldn't do work? As my validations are preconditions before the object is constructed and considered valid. How would I disable them? Can you explain what you mean by that? –  Nov 13 '17 at 14:50
  • I do not know what is the right way to do it in Python. The simplest one would be to have a global static Boolean variable that tells if the check is enabled or not. Then `_validate_` functions would first check this variable. When it is set to true, the checks are done as now. If it is set to false, the checks are ignored. – Alexander Kogtenkov Nov 13 '17 at 15:27
  • Yeah, you can something like that in python. Gave you the check. –  Nov 13 '17 at 16:56