On 5/12/2013 12:48 PM, Wayne Werner wrote:
I'll share the anti-pattern that I've seen many times (not actually in Python)class CoolPresenter: def __init__(self): self.view = None self.some_property = None self.other_property = None def initialize(self): self.view.disable() data = self.load_data() self.view.data = data self.view.enable() def reload(self): if self.view is None: raise NotInitializedError("Error: Please setup class") self.view.disable() data = self.load_data() self.view.data = data self.view.enable() Then you would see code like this: presenter = CoolPresenter() presenter.view = CoolView() This is just plain silly for a few reasons: - It's ambiguous. I don't know what's required for the CoolPresenter to function properly. - The temporal coupling mentioned earlier. I can create an instance of a class and then call a function (say `reload`) and then boom! My program crashes. There is *no possible* use case of this class where you can use it without a view.
Thank you for this examples. It makes Steven's point clearer than the 'file object' example. The problem with the latter is that objectors could could point to file path objects, which are used to do some manipulations of files and directory entries on the storage device *without looking at the specific file data*. Such file data, as opposed to directory data, never enters the program data space and with smart enough devices, need not enter the CPU and its RAM. They could then confuse them with file access objects which are used to transfer specific data *between* files and program data space. The confusion is adied by the fact that file path objects are used to create file access objects. They do separate jobs and it seems that they are well kept separate, even if there are languages where file path objects can have file access functions turned on and off.
The motivation behind this anti-pattern that I've seen is the desire to not have a constructor that "does too much". So you end out with an empty constructor and temporal coupling, and a terrible API that doesn't clearly explain the requirements of the class. Your class constructor should *require* everything that is necessary to have a stable state when the class is created (i.e. you should be able to properly call any function, set any property without an exception happening) Why? Less bugs, easier to comprehend, change/update your code. Easier to use the class.
-- Terry Jan Reedy -- http://mail.python.org/mailman/listinfo/python-list
