OO Systems and Roles
 Curtis “Ovid” Poe
 Senior Software Engineer
Copyright 2009 by Curtis “Ovid” Poe.

This presentation is free and you may redistribute it and/or
modify it under the terms of the GNU Free Documentation
License.
Template Copyright 2009 by BBC.


Future Media & Technology                                       BBC MMIX
Not a Tutorial
• #ovidfail
• “How” is easy
• “Why” is not




 Future Media & Technology         BBC MMIX
The Problem Domain

• 5,613 Brands
• 6,755 Series
• 386,943 Episodes
• 394,540 Versions
• 1,106,246 Broadcasts
• 1,701,309 On Demands
 July 2, 2009



  Future Media & Technology    BBC MMIX
A Brief History of Pain

•Simula 67
 –Classes
 –Polymorphism
 –Encapsulation
 –Inheritance

 Future Media & Technology    BBC MMIX
Multiple Inheritance

•C++
•Eiffel
•Perl
•CLOS

 Future Media & Technology     BBC MMIX
Single Inheritance

•C#
•Java
•BETA
•Ruby

 Future Media & Technology      BBC MMIX
Handling Inheritance

•Liskov
•Strict equivalence
•Interfaces
•Mixins
•C3
 Future Media & Technology    BBC MMIX
Four Decades of Pain

•Code smell
 –In the language!




 Future Media & Technology    BBC MMIX
B:: Object Hierarchy




Future Media & Technology    BBC MMIX
A Closer Look




Future Media & Technology       BBC MMIX
A Closer Look

• Multiple Inheritance




 Future Media & Technology       BBC MMIX
B::PVIV Pseudo-Code

• B::PVIV Internals

 bless => {
   pv => 'three',
   iv => 3,
 } => 'B::PVIV';

 Future Media & Technology    BBC MMIX
Printing Numbers?
• Perl
 my $number = 3;
 $number   += 2;
 print "I have $number apples";

• Java
 int number = 3;
 number    += 2;
 System.out.println(
   "I have " + number + " apples"
 );



  Future Media & Technology          BBC MMIX
Class Details

• More pseudo-code
 package B::PVIV;
 use parent qw( B::PV B::IV );

 sub B::PV::as_string { $_[0]->{pv} }
 sub B::IV::as_string { $_[0]->{iv} }


• Printing:
 print $pviv->as_string;        # Str
 print $pviv->B::IV::as_string; # Int


  Future Media & Technology              BBC MMIX
Real World Pain




Future Media & Technology      BBC MMIX
Real World Pain




Future Media & Technology      BBC MMIX
Real World Pain




Future Media & Technology      BBC MMIX
Real World Pain




Future Media & Technology      BBC MMIX
Systems Grow




Future Media & Technology     BBC MMIX
The Problem

• Responsibility
  –Wants larger classes
• Reuse
  –Wants smaller classes



 Future Media & Technology       BBC MMIX
Solution




Decouple!
Future Media & Technology           BBC MMIX
Solutions

• Interfaces
   –Reimplementing




 Future Media & Technology          BBC MMIX
Solutions

• Delegation
  –Scaffolding
  –Communication




 Future Media & Technology          BBC MMIX
Solutions

• Mixins
  –Ordering




 Future Media & Technology          BBC MMIX
PracticalJoke

• Needs:
  –explode()
  –fuse()




 Future Media & Technology    BBC MMIX
Shared Behavior
                   Method       Description


✓        Bomb::fuse()        Deterministic


         Spouse::fuse()      Non-deterministic


         Bomb::explode()     Lethal



✓        Spouse::explode()   Wish it was lethal


Future Media & Technology                          BBC MMIX
Ruby Mixins
  module Bomb
      def explode
          puts "Bomb explode"
      end
      def fuse
          puts "Bomb fuse"
      end
  end

  module Spouse
      def explode
          puts "Spouse explode"
      end
      def fuse
          puts "Spouse fuse"
      end
  end



Future Media & Technology          BBC MMIX
Ruby Mixins
    class PracticalJoke
        include Spouse
        include Bomb
    end

    joke = PracticalJoke.new()
    joke.fuse
    joke.explode


Prints out:




  Future Media & Technology        BBC MMIX
Ruby Mixins
    class PracticalJoke
        include Spouse
        include Bomb
    end

    joke = PracticalJoke.new()
    joke.fuse
    joke.explode


Prints out:
    Bomb fuse
    Bomb explode




  Future Media & Technology        BBC MMIX
Moose Roles
{
    package Bomb;
    use Moose::Role;
    sub fuse    { say "Bomb explode" }
    sub explode { say "Bomb fuse" }
}
{
    package Spouse;
    use Moose::Role;
    sub fuse    { say "Spouse explode" }
    sub explode { say "Spouse fuse" }
}



    Future Media & Technology               BBC MMIX
Moose Roles
      {
          package PracticalJoke;
          use Moose;
          with qw(Bomb Spouse);
      }
      my $joke = PracticalJoke->new();
      $joke->fuse();
      $joke->explode();

Prints out:




  Future Media & Technology               BBC MMIX
Moose Roles
      {
          package PracticalJoke;
          use Moose;
          with qw(Bomb Spouse);
      }
      my $joke = PracticalJoke->new();
      $joke->fuse();
      $joke->explode();

Prints out:
    Due to a method name conflict in roles 'Bomb' and
    'Spouse', the method 'fuse' must be implemented
    or excluded by 'PracticalJoke'




  Future Media & Technology                          BBC MMIX
Moose Roles
    {
        package PracticalJoke;
        use Moose;
        with 'Bomb'   => { excludes => 'explode' },
             'Spouse' => { excludes => 'fuse' };
    }
    my $joke = PracticalJoke->new();
    $joke->fuse();
    $joke->explode();

Prints out:
    Spouse fuse
    Bomb explode




  Future Media & Technology                            BBC MMIX
Moose Roles
  package PracticalJoke;
  use Moose;
  with 'Bomb'   => { excludes    => 'explode' },
       'Spouse' => { excludes    => 'fuse',
                      alias      =>
                        { fuse   => 'random_fuse' }
                   };


And in your actual code:
   $joke->fuse(14);      # timed fuse
   # or
   $joke->random_fuse(); # who knows?




 Future Media & Technology                             BBC MMIX
Role Example
  package Does::Serialize::YAML
  use Moose::Role;
  use YAML::Syck;

  requires 'as_hash';

  sub serialize {
      my $self = shift;
      return Dump($self->as_hash);
  }

  1;


And in your actual code:
  package My::Object;
  use Moose;
  with 'Does::Serialize::YAML';




 Future Media & Technology            BBC MMIX
Back To Work




Future Media & Technology       BBC MMIX
Work + Roles




Future Media & Technology       BBC MMIX
Work + Roles



package Country;
use Moose;
extends "My::ResultSource";
with qw(DoesStatic DoesAuditing);




Future Media & Technology       BBC MMIX
Old BBC ResultSet Classes




 Future Media & Technology    BBC MMIX
New ResultSet Classes




Future Media & Technology    BBC MMIX
Work + Roles

       package BBC::Programme::Episode;
       use Moose;
       extends 'BBC::ResultSet';
       with qw(
          DoesSearch::Broadcasts
          DoesSearch::Tags
          DoesSearch::Titles
          DoesSearch::Promotions
          DoesIdentifier::Universal
       );



Future Media & Technology              BBC MMIX
Conclusion

• Increases comprehension
• Increases safety
• Decreases complexity




 Future Media & Technology        BBC MMIX

Inheritance Versus Roles

  • 1.
    OO Systems andRoles Curtis “Ovid” Poe Senior Software Engineer Copyright 2009 by Curtis “Ovid” Poe. This presentation is free and you may redistribute it and/or modify it under the terms of the GNU Free Documentation License. Template Copyright 2009 by BBC. Future Media & Technology  BBC MMIX
  • 2.
    Not a Tutorial •#ovidfail • “How” is easy • “Why” is not Future Media & Technology  BBC MMIX
  • 3.
    The Problem Domain •5,613 Brands • 6,755 Series • 386,943 Episodes • 394,540 Versions • 1,106,246 Broadcasts • 1,701,309 On Demands July 2, 2009 Future Media & Technology  BBC MMIX
  • 4.
    A Brief Historyof Pain •Simula 67 –Classes –Polymorphism –Encapsulation –Inheritance Future Media & Technology  BBC MMIX
  • 5.
  • 6.
  • 7.
  • 8.
    Four Decades ofPain •Code smell –In the language! Future Media & Technology  BBC MMIX
  • 9.
    B:: Object Hierarchy FutureMedia & Technology  BBC MMIX
  • 10.
    A Closer Look FutureMedia & Technology  BBC MMIX
  • 11.
    A Closer Look •Multiple Inheritance Future Media & Technology  BBC MMIX
  • 12.
    B::PVIV Pseudo-Code • B::PVIVInternals bless => { pv => 'three', iv => 3, } => 'B::PVIV'; Future Media & Technology  BBC MMIX
  • 13.
    Printing Numbers? • Perl my $number = 3; $number += 2; print "I have $number apples"; • Java int number = 3; number += 2; System.out.println( "I have " + number + " apples" ); Future Media & Technology  BBC MMIX
  • 14.
    Class Details • Morepseudo-code package B::PVIV; use parent qw( B::PV B::IV ); sub B::PV::as_string { $_[0]->{pv} } sub B::IV::as_string { $_[0]->{iv} } • Printing: print $pviv->as_string; # Str print $pviv->B::IV::as_string; # Int Future Media & Technology  BBC MMIX
  • 15.
    Real World Pain FutureMedia & Technology  BBC MMIX
  • 16.
    Real World Pain FutureMedia & Technology  BBC MMIX
  • 17.
    Real World Pain FutureMedia & Technology  BBC MMIX
  • 18.
    Real World Pain FutureMedia & Technology  BBC MMIX
  • 19.
    Systems Grow Future Media& Technology  BBC MMIX
  • 20.
    The Problem • Responsibility –Wants larger classes • Reuse –Wants smaller classes Future Media & Technology  BBC MMIX
  • 21.
    Solution Decouple! Future Media &Technology  BBC MMIX
  • 22.
    Solutions • Interfaces –Reimplementing Future Media & Technology  BBC MMIX
  • 23.
    Solutions • Delegation –Scaffolding –Communication Future Media & Technology  BBC MMIX
  • 24.
    Solutions • Mixins –Ordering Future Media & Technology  BBC MMIX
  • 25.
    PracticalJoke • Needs: –explode() –fuse() Future Media & Technology  BBC MMIX
  • 26.
    Shared Behavior Method Description ✓ Bomb::fuse() Deterministic Spouse::fuse() Non-deterministic Bomb::explode() Lethal ✓ Spouse::explode() Wish it was lethal Future Media & Technology  BBC MMIX
  • 27.
    Ruby Mixins module Bomb def explode puts "Bomb explode" end def fuse puts "Bomb fuse" end end module Spouse def explode puts "Spouse explode" end def fuse puts "Spouse fuse" end end Future Media & Technology  BBC MMIX
  • 28.
    Ruby Mixins class PracticalJoke include Spouse include Bomb end joke = PracticalJoke.new() joke.fuse joke.explode Prints out: Future Media & Technology  BBC MMIX
  • 29.
    Ruby Mixins class PracticalJoke include Spouse include Bomb end joke = PracticalJoke.new() joke.fuse joke.explode Prints out: Bomb fuse Bomb explode Future Media & Technology  BBC MMIX
  • 30.
    Moose Roles { package Bomb; use Moose::Role; sub fuse { say "Bomb explode" } sub explode { say "Bomb fuse" } } { package Spouse; use Moose::Role; sub fuse { say "Spouse explode" } sub explode { say "Spouse fuse" } } Future Media & Technology  BBC MMIX
  • 31.
    Moose Roles { package PracticalJoke; use Moose; with qw(Bomb Spouse); } my $joke = PracticalJoke->new(); $joke->fuse(); $joke->explode(); Prints out: Future Media & Technology  BBC MMIX
  • 32.
    Moose Roles { package PracticalJoke; use Moose; with qw(Bomb Spouse); } my $joke = PracticalJoke->new(); $joke->fuse(); $joke->explode(); Prints out: Due to a method name conflict in roles 'Bomb' and 'Spouse', the method 'fuse' must be implemented or excluded by 'PracticalJoke' Future Media & Technology  BBC MMIX
  • 33.
    Moose Roles { package PracticalJoke; use Moose; with 'Bomb' => { excludes => 'explode' }, 'Spouse' => { excludes => 'fuse' }; } my $joke = PracticalJoke->new(); $joke->fuse(); $joke->explode(); Prints out: Spouse fuse Bomb explode Future Media & Technology  BBC MMIX
  • 34.
    Moose Roles package PracticalJoke; use Moose; with 'Bomb' => { excludes => 'explode' }, 'Spouse' => { excludes => 'fuse', alias => { fuse => 'random_fuse' } }; And in your actual code: $joke->fuse(14); # timed fuse # or $joke->random_fuse(); # who knows? Future Media & Technology  BBC MMIX
  • 35.
    Role Example package Does::Serialize::YAML use Moose::Role; use YAML::Syck; requires 'as_hash'; sub serialize { my $self = shift; return Dump($self->as_hash); } 1; And in your actual code: package My::Object; use Moose; with 'Does::Serialize::YAML'; Future Media & Technology  BBC MMIX
  • 36.
    Back To Work FutureMedia & Technology  BBC MMIX
  • 37.
    Work + Roles FutureMedia & Technology  BBC MMIX
  • 38.
    Work + Roles packageCountry; use Moose; extends "My::ResultSource"; with qw(DoesStatic DoesAuditing); Future Media & Technology  BBC MMIX
  • 39.
    Old BBC ResultSetClasses Future Media & Technology  BBC MMIX
  • 40.
    New ResultSet Classes FutureMedia & Technology  BBC MMIX
  • 41.
    Work + Roles package BBC::Programme::Episode; use Moose; extends 'BBC::ResultSet'; with qw( DoesSearch::Broadcasts DoesSearch::Tags DoesSearch::Titles DoesSearch::Promotions DoesIdentifier::Universal ); Future Media & Technology  BBC MMIX
  • 42.
    Conclusion • Increases comprehension •Increases safety • Decreases complexity Future Media & Technology  BBC MMIX