<?xml version="1.0" encoding="windows-1252"?>
<node id="317548" title="Re: Often Overlooked OO Programming Guidelines" created="2003-12-29 16:00:15" updated="2005-07-07 14:28:40">
<type id="11">
note</type>
<author id="195718">
hardburn</author>
<data>
<field name="doctext">
&lt;p&gt;&lt;em&gt;Some argue that the behavior or subclasses (or subtypes) should not change . . . &lt;/em&gt;&lt;/p&gt;

&lt;p&gt;I dunno. [cpan://HTML::Template::Dumper] significantly changes the behavior of [cpan://HTML::Template]. If people want to argue that this breaks Liskov, that's fine, but it doesn't stop HTML::Template::Dumper from being useful.&lt;/p&gt;

&lt;p&gt;&lt;em&gt;$object-&gt;as_string&lt;/em&gt;&lt;/p&gt;

&lt;p&gt;One important benifit is that YAML/Data::Dumper only show the state of the object's internal data structure, but not lexicals used for storing private data (see below). It might be private, but if it's for debugging or human-readability, it might still be important to print it out. So a mere &lt;code&gt;Dump($obj);&lt;/code&gt; is often not enough.&lt;/p&gt;

&lt;p&gt;Other observations:&lt;/p&gt;

&lt;p&gt;1) One thing I often see is people storing things in the object's structure that should be private, or storing things in lexicals that should be accessible to subclasses. As a general rule, if you want a subclass to get at it, it should be in the blessed reference of the object. Or provide accessors/mutators that are only available to subclasses (&lt;b&gt;not&lt;/b&gt; public, unless your design explicitly calls for it). If the data needs to be truely private, put it in lexicals declared at the top of the package.&lt;/p&gt;

&lt;p&gt;2) If you have a factory method, do not hardcode the name of the class. Instead, put it in a subroutine, like this:&lt;/p&gt;

&lt;code&gt;
package My::Foo;

sub BAR_CLASS { 'My::Bar' }

sub bar_factory 
{
    my $my_class = shift;
    my $bar_class = $class-&gt;BAR_CLASS;
    bless { }, $bar_class;
}
&lt;/code&gt;

&lt;p&gt;This better supports subclasses, which would otherwise need to override the entire &lt;code&gt;bar_factory&lt;/code&gt; method (which could be extremely complex). Now they only need to say &lt;code&gt;sub BAR_CLASS { 'My::Bar::Subclass' }&lt;/code&gt; to change exact output of the factory method. (It's the responsibility of the subclass to make sure &lt;code&gt;My::Bar::Subclass&lt;/code&gt; implements the same methods as &lt;code&gt;My::Bar&lt;/code&gt;).&lt;/p&gt;

&lt;p&gt;3) Calling all your own methods should be done in &lt;code&gt;$obj-&gt;method( @args )&lt;/code&gt; form. Not &lt;code&gt;method( $obj, @args )&lt;/code&gt; or (worse) &lt;code&gt;method( @args )&lt;/code&gt;. Both the bad examples break inheirtance, and the second one isn't a method at all. I could see an argument made for the &lt;code&gt;method( $obj, @args )&lt;/code&gt; form if performance is a concern and you don't care about subclasses or if it's a private method, but I see no excuse for the second form.&lt;/p&gt;

&lt;p&gt;4) Document protected methods. Unlike some other languages, Perl doesn't have any very good ways to specify what methods should only be accessible to subclasses (though it has a multitude of hacked solutions). Ultimately, you need to document your protected methods, with warnings of fire coming down from heaven if somebody on the outside uses them. And make sure fire &lt;em&gt;won't&lt;/em&gt; come down on ligitimate subclasses.&lt;/p&gt;

&lt;div class="pmsig"&gt;&lt;div class="pmsig-195718"&gt;
&lt;p&gt;----&lt;br&gt;&lt;em&gt;I wanted to explore how Perl's closures can be manipulated, and ended up creating an object system by accident.&lt;/em&gt; &lt;br&gt;
-- [Schemer]&lt;/p&gt;

&lt;p&gt;&lt;code&gt;: () { :|:&amp; };:&lt;/code&gt;&lt;/p&gt;
&lt;p&gt;&lt;b&gt;Note&lt;/b&gt;: All code is untested, unless otherwise stated&lt;/p&gt;

&lt;/div&gt;&lt;/div&gt;</field>
<field name="root_node">
317520</field>
<field name="parent_node">
317520</field>
</data>
</node>
