0

I'm coding in Python, but the question seems independent of programming language.

I have a class that represents some system check:

class Check:
 @abstractmethod
 def run()
 """ You have to define your own run(). As a result, it must set self._ok. """
 ...
 @property
 def is_ok():
 return self._is_ok

Then we have a set of checks by subclassing Check class, and they're used in the following way (simplified):

class Checker:
 checks = [check1, check2...]
 def __call__(self):
 for check in self.checks:
 if not check.is_ok:
 alarm()

The question is: Is it fine to oblige subclass to set some protected object attributes?

Jonathan Eunice
9,8301 gold badge34 silver badges42 bronze badges
asked Nov 5, 2014 at 11:28
1

3 Answers 3

2

Why wouldn't it be okay to require subclasses to do work? The parent is abstract, after all.

The more important question is: why is run() supposed to signal success via an out-of-bound mechanism (setting a global variable) rather than a return value? There are sometimes reasons for doing this (e.g. because it's an extremely entrenched convention, like errno in C), but usually it's a bad sign because of issues with concurrency, maintainability etc.

answered Nov 5, 2014 at 11:31
2
  • I'd like Check to have state. Returning value is an obvious option, but I don't like it in such particular case. Commented Nov 5, 2014 at 11:35
  • 1
    My concern is: Isn't it too much to explain to the child class, and isn't it too hard to verify if child class fits this contract? If we refactor it to return result, it's easier. Just return True/False and that's it. Commented Nov 5, 2014 at 12:20
2

To provide an alternative to letting the value be set by the subclass you can instead have them provide a doRun that returns true/false to signify success and the run assigns that result to self._ok, this also allows more checks like catching exceptions or ensuring it only runs once:

class Check:
 @abstractmethod
 def doRun()
 """ You have to define your own doRun(). As a result, it must return whether it was successful. """
 ...
 def run()
 if not is_ok """ runs once, remove if not needed """
 self._ok = doRun()
 @property
 def is_ok():
 return self._is_ok
answered Nov 5, 2014 at 11:58
1
  • Thanks! Yes, I understand that this can be refactored in a number of ways, but I'd like to know whether my approach violates some design rules or not. Commented Nov 5, 2014 at 12:01
0

One commonly (albeit not universally) accepted principle of object design is that an object should be immutable unless this makes the design substantially more complex. Immutable objects are easier to reason about, can be used in a multithreaded environment more easily and are generally less prone to bugs.

From the code you have shown us, there is no reason I can see why you need mutable objects, so I would use immutable ones.

answered Nov 5, 2014 at 16:20
1
  • Is the rule "keep objects immutable" related to data-driven design? I always thought that objects are data+code by definition, so they can (or should) have state. Commented Nov 6, 2014 at 14:11

Your Answer

Draft saved
Draft discarded

Sign up or log in

Sign up using Google
Sign up using Email and Password

Post as a guest

Required, but never shown

Post as a guest

Required, but never shown

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.