in reply to replace conditionals with polymorphism
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:
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.
|
---|
Replies are listed 'Best First'. | |
---|---|
Re^2: replace conditionals with polymorphism
by doom (Deacon) on Feb 09, 2009 at 23:24 UTC | |
by tilly (Archbishop) on Feb 10, 2009 at 03:01 UTC | |
by doom (Deacon) on Feb 10, 2009 at 04:24 UTC | |
by tilly (Archbishop) on Feb 10, 2009 at 05:58 UTC | |
by ELISHEVA (Prior) on Feb 10, 2009 at 08:16 UTC | |
|