object.enable() anti-pattern
Terry Jan Reedy
tjreedy at udel.edu
Sun May 12 16:23:58 EDT 2013
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
More information about the Python-list
mailing list