IMHO you are having trouble applying the video because he isn't really talking about isolated switch statements. In the case of an isolated switch statement, OO merely replaces one sort of switch statement with another. The only way you can get rid of the switch is to replace it with a object belonging to a dynamically chosen class. But how are you going to select the class? Of course with another switch statement! (or other conditional logic)

Generally replacement of switch statements with classes only buys you something if you have a similar switch statement in more than one place. This can happen if

In either of these cases OO lets you reuse the decision that lead to class selection over and over without having to make the actual decision over and over.

In the video his first example (nodes of a parse tree) is of type A - repeated use of the same switch statement. Even though you need a switch statement to assign each node to a class, once you have done so, you can act as if each node in the tree is essentially the same object and avoid messy switch statements whenever you visit a node. All you have to do is call its evaluate(...) method.

The second example in the video - the Update class - is an example of type B - more than one action dependent on type. In the case of the Update class we have the execute(...) and render(...) methods.

That being said, this is what I would do to convert your code:

  1. create a base class with a single method, lets say "frobnicate"
  2. implement the "frobnicate" method of the base class with your default case of the switch statement
  3. for each non-default case in the switch statement, create a subclass
  4. implement the frobnicate method of the subclass with the statements belonging to each non-default case.

To replace the switch statement, I would use three lines:

my $sClass = derive_class($foo); my $oWhatWasOnceASwitchStatementCase = $sClass->new(); $oWhatWasOnceASwitchStatementCase->frobnicate();

The full code looks something like this. To keep it short I've reduced the number of special cases from A,B,C,D to just A,B. I've also set "$foo" from the command line so you can experiment a bit with how different values of "$foo" might behave.

use strict; use warnings; #pretend command line is indirect user input my $foo = \@ARGV; #indirect user input #this replaces your switch statement # use derive_class($foo) to select the class # use frobinate() to replace the action for each if statement branch my $sClass = derive_class($foo); my $oWhatWasOnceASwitchStatementCase = $sClass->new(); $oWhatWasOnceASwitchStatementCase->frobnicate(); #dummy implementation of derive_class($foo) #converts command line arguments to a class sub derive_class { my ($sClass) = $foo->[0]; $sClass = 'Demo::Base' unless $sClass =~ /^Demo::[AB]$/; return $sClass; } #here are your class definitions #implement default case { package Demo::Base; sub new { my ($sClass) = @_; my $self = {}; return bless($self, $sClass); } sub frobnicate { my ($self) = @_; #do similar_to_a print "I'm defaulting to something similar to A\n"; } } #implement when A { package Demo::A; use base 'Demo::Base'; sub frobnicate { my ($self) = @_; #do A print "I'm doing A\n"; } } #implement when B { package Demo::B; use base 'Demo::Base'; sub frobnicate { my ($self) = @_; #do B print "I'm doing B\n"; } }

Best, beth

Update: various edits to improve clarity.


In reply to Re: replace conditionals with polymorphism by ELISHEVA
in thread replace conditionals with polymorphism by Anonymous Monk

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.