0

I am using a factory pattern to get objects that shouldn't be instantiated other than the factory class. These objects are of type ViolationType, which represent violations on a set of rule. Here is the summary of the factory and the available violation types:

class ViolationFactory:
    def __init__(self):
        raise ValueError('%s cannot be instantiated' % self.__class__.__name__)

    class ViolationType:
        def __init__(self, name):
            self.name = name

    _violations = (
        ViolationType('RULE_X'),
        ViolationType('RULE_Y'),
        # the rest of the types...
    )
    _violations_dict = {v.name: v for v in _violations}

    @staticmethod
    def get(violation_name):
        if violation_name not in ViolationFactory._violations_dict:
            raise ValueError('Invalid ViolationType')
        return ViolationFactory._violations_dict[violation_name]

A ViolationType is primarily used to instantiate a Violation:

violation = Violation(ViolationFactory.get('RULE_X'), **kwargs)

The problem with this is that if I misspell the string passed to the get() factory method I won't know there is an error until that particular piece of code is ran. So if I try doing ViolationFactory.get('RULE_Z') and such type doesn't exist, it should throw an error when running the program

I think the current design simply doesn't allow such behavior, so: how could I redesign it so that I get a load time error rather than a run time one?

2
  • docs.python.org/3/library/enum.html enumeration ? I don't really know however if your IDE will show it or a syntax error will be thrown on loading thescript before running it. Commented Jun 22, 2017 at 11:48
  • I'm on Python 2.7, should've mentioned it. Commented Jun 22, 2017 at 12:56

1 Answer 1

0

You could use enums as rule identifiers. That way, you would know if you made a mistake at compile time. Something along these lines:

enum Rules
{
   Rule_X = 0,
   Rule_Y = 1,
   Rule_Z = 2
}

Then, the call would look like this:

violation = Violation(ViolationFactory.get(Rules.Rule_X), **kwargs)

Alternatively, you could implement every rule as a plugin, in their own assembly, and load the assemblies dynamically. Then, if the plugin is not loaded correctly, throw an exception and you will know that there was a problem at load time. The downside is that if you have many rules, you will have many assemblies.

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.