It doesn't even reduce conditionals. It moves one conditional from outside to being one conditional inside. Okay, I'll grant that it can reduce conditionals if you have to follow that pattern more than once outside of the class. But I don't find the major benefit to be "fewer conditionals". I find the major benefit to be "isolate more (cohesive) knowledge inside the class". And that latter benefit applies even if the outer 'if' only occurred once.

Just for counter-point, I'll note that sometimes you can improve cohesion by going in the opposite direction (with an example that actually involves polymorphism). If you have a class that is responsible for intelligently applying changes, knowing whether save() needs to do insert() or update() or nothing [or delete()], then it can be better to write:

sub save { ... $item->update() if $item->is_dirty(); ... }

in that one class than to have each type of item include code like:

sub update_if_dirty { ... return if ! $self->is_dirty(); ... }

(Though, I suspect that such a system might be even cleaner if is_dirty() isn't even tracked by the items but instead is handled by the "knows how to apply updates" wrapper.)

But, yes, I did make too strong of a correlation between your opening sentence and your best example. Part of the reason I did that is because I have actually seen (several times) "replace 'if' with polymorphism" used as a justification for doing things almost as crazy as having an "is_dirty" class separate from an "is_clean" class. And I have actually (more than once) felt the pain of trying to make a small change in the resulting system and having this bifurcation (or worse) of classes get profoundly in the way.

So I see need to highlight the problems with over applying that meme.

I also did it because I really didn't see anything in your write-up that acknowledged the difference between what the linked article discussed and what you discussed. I was quite surprised to find the linked article so limited in scope. And not just because the scope was much more limited compared to the topic you covered, but because I had repeatedly seen that "replace 'if' with polymorphism" phrase used to describe practices far broader than what you discussed.

So much so that I've come to associate that phrase with a pretty bad form of OO Kool-Aid. The article shows that I may not be the only one since DanMuller notes "As a blanket guideline, I find this to be bad advice bordering on the absurd. [....] Prefer clarity over dogmatic purity".

I think it can be valuable to consider whether the interface you use for a class seems likely to be useful under polymorphism. It can help you notice internal details that are not well encapsulated and thus not hidden.

In only the last few years, I noticed that the "best practices" that I was learning to reject because I was noticing that they lead to maintenance problems in the long term (inheritance being the most popular of those)... I noticed that those practices were interfering with modularity.

So I am now paying much, much more attention to modularity, that relatively ancient programming best practice that seemed to have become so widely acknowledged that people stopped even talking much about it.

Minimize (and simplify) the interfaces of your classes. Maximize the cohesiveness of your classes. There are a lot of more specific best practices that can be very useful in helping one see more ways in which they could increase modularity. But many of them also can be followed in ways that hurt modularity.

So I now tend to double check my application of good ideas to verify that the end result actually improved modularity. I've found that "check" step to be very useful. And extremely practical, especially much later when I have to re-visit some code to perform maintenance.

- tye        


In reply to Re^3: Programming patterns (modularity) by tye
in thread Programming patterns by McA

Title:
Use:  <p> text here (a paragraph) </p>
and:  <code> code here </code>
to format your post, it's "PerlMonks-approved HTML":



  • Posts are HTML formatted. Put <p> </p> tags around your paragraphs. Put <code> </code> tags around your code and data!
  • Titles consisting of a single word are discouraged, and in most cases are disallowed outright.
  • Read Where should I post X? if you're not absolutely sure you're posting in the right place.
  • Please read these before you post! —
  • Posts may use any of the Perl Monks Approved HTML tags:
    a, abbr, b, big, blockquote, br, caption, center, col, colgroup, dd, del, details, div, dl, dt, em, font, h1, h2, h3, h4, h5, h6, hr, i, ins, li, ol, p, pre, readmore, small, span, spoiler, strike, strong, sub, summary, sup, table, tbody, td, tfoot, th, thead, tr, tt, u, ul, wbr
  • You may need to use entities for some characters, as follows. (Exception: Within code tags, you can put the characters literally.)
            For:     Use:
    & &amp;
    < &lt;
    > &gt;
    [ &#91;
    ] &#93;
  • Link using PerlMonks shortcuts! What shortcuts can I use for linking?
  • See Writeup Formatting Tips and other pages linked from there for more info.