Groups | Search | Server Info | Keyboard shortcuts | Login | Register [http] [https] [nntp] [nntps]


Groups > comp.lang.python > #45188

Re: object.enable() anti-pattern

Path csiph.com!newsfeed.hal-mli.net!feeder3.hal-mli.net!newsfeed.hal-mli.net!feeder1.hal-mli.net!newsfeed.xs4all.nl!newsfeed3.news.xs4all.nl!xs4all!post.news.xs4all.nl!not-for-mail
Return-Path <wayne@waynewerner.com>
X-Original-To python-list@python.org
Delivered-To python-list@mail.python.org
X-Spam-Status OK 0.002
X-Spam-Evidence '*H*': 1.00; '*S*': 0.00; 'patterns': 0.04; 'python)': 0.05; 'explicit': 0.07; 'none:': 0.07; 'agrees': 0.09; 'constructor': 0.09; 'function,': 0.09; 'method,': 0.09; 'method:': 0.09; 'properly.': 0.09; 'api': 0.11; 'cc:addr:python- list': 0.11; 'def': 0.12; '"does': 0.16; '(say': 0.16; 'constructor.': 0.16; 'coupling': 0.16; 'earlier.': 0.16; 'fine.': 0.16; 'kern': 0.16; 'naming': 0.16; 'programmers.': 0.16; 'silly': 0.16; 'specific,': 0.16; 'to:addr:robert.kern': 0.16; 'to:name:robert kern': 0.16; 'underlying': 0.16; 'exception': 0.16; 'all.': 0.16; 'wrote:': 0.18; '(not': 0.18; 'code.': 0.18; 'bit': 0.19; 'file,': 0.19; 'properly': 0.19; 'not,': 0.20; 'separate': 0.22; 'cc:addr:python.org': 0.22; 'header:User- Agent:1': 0.23; 'instead.': 0.24; 'file.': 0.24; 'cc:2**0': 0.24; 'cc:no real name:2**0': 0.24; "i've": 0.25; 'class.': 0.26; 'permission': 0.26; 'this:': 0.26; 'pass': 0.26; 'least': 0.26; 'header:In-Reply-To:1': 0.27; 'idea': 0.28; 'point': 0.28; 'function': 0.29; 'raise': 0.29; "doesn't": 0.30; 'moved': 0.30; 'robert': 0.30; 'said,': 0.30; 'then.': 0.30; "i'm": 0.30; 'code': 0.31; 'easier': 0.31; 'about.': 0.31; "d'aprano": 0.31; 'motivation': 0.31; 'object.': 0.31; 'steven': 0.31; 'view.': 0.31; 'class': 0.32; 'another': 0.32; 'open': 0.33; 'everyone': 0.33; '(i.e.': 0.33; 'entirely': 0.33; 'fri,': 0.33; 'plain': 0.33; 'programmers': 0.33; 'sense': 0.34; 'skip:_ 10': 0.34; "i'd": 0.34; 'created': 0.35; 'but': 0.35; 'there': 0.35; 'curious': 0.36; 'done,': 0.36; 'instances': 0.36; 'object,': 0.36; 'done': 0.36; 'useful': 0.36; 'charset:us-ascii': 0.36; "i'll": 0.36; 'should': 0.36; 'behind': 0.37; 'experience,': 0.37; 'wrong': 0.37; 'too': 0.37; 'requirements': 0.37; 'others.': 0.38; 'security,': 0.38; 'stable': 0.38; 'explain': 0.39; 'does': 0.39; 'either': 0.39; 'skip:p 20': 0.39; 'mentioned': 0.61; 'first': 0.61; 'discuss': 0.62; 'times': 0.62; "you've": 0.63; 'show': 0.63; 'more': 0.64; 'talking': 0.65; 'to:addr:gmail.com': 0.65; 'natural': 0.68; 'design.': 0.68; '*no': 0.84; 'continuum': 0.84; 'doubts': 0.84; 'entity,': 0.84; 'rubbish': 0.84; 'subject:skip:o 10': 0.84; 'terrible': 0.84; '2013,': 0.91; 'novice': 0.91; 'reasons,': 0.91; 'why?': 0.91; 'story.': 0.93
Date Sun, 12 May 2013 11:48:58 -0500 (CDT)
From Wayne Werner <wayne@waynewerner.com>
X-X-Sender wayne@gilgamesh
To Robert Kern <robert.kern@gmail.com>
Subject Re: object.enable() anti-pattern
In-Reply-To <kmiojk$12i$1@ger.gmane.org>
References <518a123c$0$11094$c3e8da3@news.astraweb.com> <Z1Eit.289$oB7.283@newsfe02.iad> <518b32ef$0$11120$c3e8da3@news.astraweb.com> <roy-8428A6.09074209052013@news.panix.com> <518be931$0$29997$c3e8da3$5496439d@news.astraweb.com> <mailman.1501.1368124461.3114.python-list@python.org> <518c5bbc$0$29997$c3e8da3$5496439d@news.astraweb.com> <roy-6D8B98.23095509052013@news.panix.com> <518c7f8e$0$29997$c3e8da3$5496439d@news.astraweb.com> <Hm0jt.6$I26.5@newsfe26.iad> <518cd360$0$29997$c3e8da3$5496439d@news.astraweb.com> <kmiojk$12i$1@ger.gmane.org>
User-Agent Alpine 2.02 (DEB 1266 2009-07-14)
MIME-Version 1.0
Content-Type TEXT/PLAIN; charset=US-ASCII; format=flowed
Cc python-list@python.org
X-BeenThere python-list@python.org
X-Mailman-Version 2.1.15
Precedence list
List-Id General discussion list for the Python programming language <python-list.python.org>
List-Unsubscribe <http://mail.python.org/mailman/options/python-list>, <mailto:python-list-request@python.org?subject=unsubscribe>
List-Archive <http://mail.python.org/pipermail/python-list/>
List-Post <mailto:python-list@python.org>
List-Help <mailto:python-list-request@python.org?subject=help>
List-Subscribe <http://mail.python.org/mailman/listinfo/python-list>, <mailto:python-list-request@python.org?subject=subscribe>
Newsgroups comp.lang.python
Message-ID <mailman.1585.1368377382.3114.python-list@python.org> (permalink)
Lines 95
NNTP-Posting-Host 2001:888:2000:d::a6
X-Trace 1368377382 news.xs4all.nl 15953 [2001:888:2000:d::a6]:47606
X-Complaints-To abuse@xs4all.nl
Xref csiph.com comp.lang.python:45188

Show key headers only | View raw


On Fri, 10 May 2013, Robert Kern wrote:

> On 2013-05-10 12:00, Steven D'Aprano wrote:
>
>> But either way, that's fine. You've found an object where it does make
>> sense to have an explicit "make it go" method: first one entity has
>> permission to construct the object, but not to open the underlying file.
>> Another entity has permission to open the underlying file, but not to
>> create the object. I have no idea whether this is a reasonable security
>> design or not, it actually sounds a bit rubbish to me but what do I know?
>> So let's treat it as a reasonable design.
>> 
>> As I've said, repeatedly, that's not what I'm talking about.
>> 
>> When you DON'T have useful things that can be done with the object before
>> calling "enable", then it is an anti-pattern to require a separate call
>> to "enable" method, and the enable functionality should be moved into the
>> object constructor. If you DO have useful things that can be done, like
>> pass the object to another entity, for security, then that's a whole
>> 'nuther story.
>
> I'd be curious to see in-the-wild instances of the anti-pattern that you are 
> talking about, then. I think everyone agrees that entirely unmotivated 
> "enable" methods should be avoided, but I have my doubts that they come up 
> very often. Do programmers have a natural tendency to make an extra, 
> completely unnecessary method? I would think that they have a natural 
> tendency to the opposite.
>
> In my experience, everyone has a reason in mind when they follow a 
> pattern/anti-pattern. It is pretty rare that someone just does some specific, 
> nameable thing for no reason at all. There is no need to call out an 
> anti-pattern for which no one has a reason to do it. But there is a continuum 
> of reasons. Some reasons are better than others. Some reasons only apply in a 
> small set of circumstances but seem like they would apply more generally, at 
> least to novice programmers. Programmers can be wrong about what they think 
> the (anti-)pattern actually achieves. The whole point of naming an 
> anti-pattern is to discuss those reasons, show where they are misapplied, 
> where YAGNI, why novices overuse it, other patterns that should be used 
> instead, and also the circumstances where it is actually a good pattern 
> instead.

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.


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.

-W

Back to comp.lang.python | Previous | NextPrevious in thread | Next in thread | Find similar | Unroll thread


Thread

object.enable() anti-pattern Steven D'Aprano <steve+comp.lang.python@pearwood.info> - 2013-05-08 08:52 +0000
  Re: object.enable() anti-pattern Christian Heimes <christian@python.org> - 2013-05-08 11:51 +0200
  Re: object.enable() anti-pattern Robert Kern <robert.kern@gmail.com> - 2013-05-08 11:13 +0100
    Re: object.enable() anti-pattern Steven D'Aprano <steve+comp.lang.python@pearwood.info> - 2013-05-08 12:30 +0000
  Re: object.enable() anti-pattern Roy Smith <roy@panix.com> - 2013-05-08 09:17 -0400
  Re: object.enable() anti-pattern Duncan Booth <duncan.booth@invalid.invalid> - 2013-05-08 14:27 +0000
    Re: object.enable() anti-pattern Dan Sommers <dan@tombstonezero.net> - 2013-05-09 02:38 +0000
      Re: object.enable() anti-pattern Steven D'Aprano <steve+comp.lang.python@pearwood.info> - 2013-05-09 05:37 +0000
        Re: object.enable() anti-pattern Chris Angelico <rosuav@gmail.com> - 2013-05-09 15:52 +1000
    Re: object.enable() anti-pattern Steven D'Aprano <steve+comp.lang.python@pearwood.info> - 2013-05-09 03:12 +0000
  Re: object.enable() anti-pattern Dan Sommers <dan@tombstonezero.net> - 2013-05-09 02:42 +0000
    Re: object.enable() anti-pattern Steven D'Aprano <steve+comp.lang.python@pearwood.info> - 2013-05-09 05:23 +0000
      Re: object.enable() anti-pattern Terry Jan Reedy <tjreedy@udel.edu> - 2013-05-09 02:41 -0400
      Re: object.enable() anti-pattern Gregory Ewing <greg.ewing@canterbury.ac.nz> - 2013-05-09 19:54 +1200
        Re: object.enable() anti-pattern Cameron Simpson <cs@zip.com.au> - 2013-05-09 18:23 +1000
          Re: object.enable() anti-pattern Steven D'Aprano <steve+comp.lang.python@pearwood.info> - 2013-05-09 11:30 +0000
            Re: object.enable() anti-pattern Cameron Simpson <cs@zip.com.au> - 2013-05-10 09:36 +1000
              Re: object.enable() anti-pattern Steven D'Aprano <steve+comp.lang.python@pearwood.info> - 2013-05-10 05:00 +0000
                Re: object.enable() anti-pattern Roy Smith <roy@panix.com> - 2013-05-10 01:50 -0400
                Re: object.enable() anti-pattern Steven D'Aprano <steve+comp.lang.python@pearwood.info> - 2013-05-10 09:47 +0000
                Re: object.enable() anti-pattern Roy Smith <roy@panix.com> - 2013-05-10 09:22 -0400
                Re: object.enable() anti-pattern Cameron Simpson <cs@zip.com.au> - 2013-05-11 08:25 +1000
                Re: object.enable() anti-pattern Mark Janssen <dreamingforward@gmail.com> - 2013-05-10 20:16 -0700
                Re: object.enable() anti-pattern Thomas Rachel <nutznetz-0c1b6768-bfa9-48d5-a470-7603bd3aa915@spamschutz.glglgl.de> - 2013-05-11 06:21 +0200
                Re: object.enable() anti-pattern Mark Janssen <dreamingforward@gmail.com> - 2013-05-10 21:00 -0700
                Re: object.enable() anti-pattern Dennis Lee Bieber <wlfraed@ix.netcom.com> - 2013-05-11 15:04 -0400
        Re: object.enable() anti-pattern Greg Ewing <greg.ewing@canterbury.ac.nz> - 2013-05-10 10:56 +1200
      Re: object.enable() anti-pattern Roy Smith <roy@panix.com> - 2013-05-09 09:07 -0400
        Re: object.enable() anti-pattern Oscar Benjamin <oscar.j.benjamin@gmail.com> - 2013-05-09 14:51 +0100
        Re: object.enable() anti-pattern Steven D'Aprano <steve+comp.lang.python@pearwood.info> - 2013-05-09 18:21 +0000
          Re: object.enable() anti-pattern MRAB <python@mrabarnett.plus.com> - 2013-05-09 19:34 +0100
            Re: object.enable() anti-pattern Steven D'Aprano <steve+comp.lang.python@pearwood.info> - 2013-05-10 02:30 +0000
              Re: object.enable() anti-pattern Roy Smith <roy@panix.com> - 2013-05-09 23:09 -0400
                Re: object.enable() anti-pattern Mark Janssen <dreamingforward@gmail.com> - 2013-05-09 20:19 -0700
                Re: object.enable() anti-pattern Chris Angelico <rosuav@gmail.com> - 2013-05-10 13:46 +1000
                Re: object.enable() anti-pattern Steven D'Aprano <steve+comp.lang.python@pearwood.info> - 2013-05-10 05:03 +0000
                Re: object.enable() anti-pattern Dan Sommers <dan@tombstonezero.net> - 2013-05-10 06:22 +0000
                Re: object.enable() anti-pattern Steven D'Aprano <steve+comp.lang.python@pearwood.info> - 2013-05-10 11:00 +0000
                Re: object.enable() anti-pattern Robert Kern <robert.kern@gmail.com> - 2013-05-10 13:19 +0100
                Re: object.enable() anti-pattern Roy Smith <roy@panix.com> - 2013-05-10 10:01 -0400
                Re: object.enable() anti-pattern Oscar Benjamin <oscar.j.benjamin@gmail.com> - 2013-05-10 15:29 +0100
                Re: object.enable() anti-pattern Roy Smith <roy@panix.com> - 2013-05-10 10:37 -0400
                Re: object.enable() anti-pattern Chris Angelico <rosuav@gmail.com> - 2013-05-11 00:46 +1000
                Re: object.enable() anti-pattern Roy Smith <roy@panix.com> - 2013-05-10 10:54 -0400
                Re: object.enable() anti-pattern Chris Angelico <rosuav@gmail.com> - 2013-05-11 01:09 +1000
                Re: object.enable() anti-pattern Roy Smith <roy@panix.com> - 2013-05-10 11:21 -0400
                Re: object.enable() anti-pattern Chris Angelico <rosuav@gmail.com> - 2013-05-11 01:44 +1000
                Re: object.enable() anti-pattern Robert Kern <robert.kern@gmail.com> - 2013-05-10 16:33 +0100
                Re: object.enable() anti-pattern Serhiy Storchaka <storchaka@gmail.com> - 2013-05-10 18:44 +0300
                Re: object.enable() anti-pattern André Malo <ndparker@gmail.com> - 2013-05-11 17:33 +0200
                Re: object.enable() anti-pattern Chris Angelico <rosuav@gmail.com> - 2013-05-12 02:04 +1000
                Re: object.enable() anti-pattern Robert Kern <robert.kern@gmail.com> - 2013-05-10 18:20 +0100
                Re: object.enable() anti-pattern Steven D'Aprano <steve+comp.lang.python@pearwood.info> - 2013-05-11 07:51 +0000
                Re: object.enable() anti-pattern Roy Smith <roy@panix.com> - 2013-05-11 09:31 -0400
                Re: object.enable() anti-pattern Robert Kern <robert.kern@gmail.com> - 2013-05-11 20:55 +0100
                Re: object.enable() anti-pattern Chris Angelico <rosuav@gmail.com> - 2013-05-12 08:39 +1000
                Re: object.enable() anti-pattern Chris Angelico <rosuav@gmail.com> - 2013-05-11 03:24 +1000
                Re: object.enable() anti-pattern Mark Janssen <dreamingforward@gmail.com> - 2013-05-10 19:43 -0700
                Re: object.enable() anti-pattern Wayne Werner <wayne@waynewerner.com> - 2013-05-12 11:48 -0500
                Re: object.enable() anti-pattern Terry Jan Reedy <tjreedy@udel.edu> - 2013-05-12 16:23 -0400
                Re: object.enable() anti-pattern Mark Janssen <dreamingforward@gmail.com> - 2013-05-09 20:51 -0700
              Re: object.enable() anti-pattern Chris Angelico <rosuav@gmail.com> - 2013-05-10 13:08 +1000
          Re: object.enable() anti-pattern roy@panix.com (Roy Smith) - 2013-05-09 14:59 -0400
            Re: object.enable() anti-pattern Chris Angelico <rosuav@gmail.com> - 2013-05-10 07:55 +1000
      Re: object.enable() anti-pattern Nobody <nobody@nowhere.com> - 2013-05-10 17:59 +0100
        Re: object.enable() anti-pattern Roy Smith <roy@panix.com> - 2013-05-10 13:32 -0400
          Re: object.enable() anti-pattern Dennis Lee Bieber <wlfraed@ix.netcom.com> - 2013-05-11 15:24 -0400
        Re: object.enable() anti-pattern Steven D'Aprano <steve+comp.lang.python@pearwood.info> - 2013-05-11 07:05 +0000
  Re: object.enable() anti-pattern Mark Janssen <dreamingforward@gmail.com> - 2013-05-08 19:53 -0700
  Re: object.enable() anti-pattern Mark Janssen <dreamingforward@gmail.com> - 2013-05-08 19:56 -0700
  Re: object.enable() anti-pattern Wayne Werner <wayne@waynewerner.com> - 2013-05-09 06:08 -0500
    Re: object.enable() anti-pattern Steven D'Aprano <steve+comp.lang.python@pearwood.info> - 2013-05-09 11:51 +0000
    Re: object.enable() anti-pattern Gregory Ewing <greg.ewing@canterbury.ac.nz> - 2013-05-10 11:43 +1200
      Re: object.enable() anti-pattern Michael Speer <knomenet@gmail.com> - 2013-05-09 20:18 -0400
        Re: object.enable() anti-pattern Roy Smith <roy@panix.com> - 2013-05-09 20:50 -0400
      Re: object.enable() anti-pattern Wayne Werner <wayne@waynewerner.com> - 2013-05-12 12:14 -0500
      Re: object.enable() anti-pattern Terry Jan Reedy <tjreedy@udel.edu> - 2013-05-12 16:03 -0400
      Re: object.enable() anti-pattern Greg Ewing <greg.ewing@canterbury.ac.nz> - 2013-05-13 11:18 +1200
      Re: object.enable() anti-pattern Fábio Santos <fabiosantosart@gmail.com> - 2013-05-13 07:32 +0100
      Re: object.enable() anti-pattern Chris Angelico <rosuav@gmail.com> - 2013-05-13 17:36 +1000
      Re: object.enable() anti-pattern Fábio Santos <fabiosantosart@gmail.com> - 2013-05-13 09:09 +0100
      Re: object.enable() anti-pattern Wayne Werner <wayne@waynewerner.com> - 2013-05-13 08:15 -0500

csiph-web