F.R.I.E.N.D.S WAY OF UNDERSTANDING "COMBINING OBJECTS WITH COMPOSITION"

By: Saurav

2017-10-23 05:40:00 UTC

1. Composition is the act of combining distinct parts in to a complex whole such that the whole becomes more than the sum of its parts

Composition1

If you watch FRIENDS, you will know that while the show's episode scenes contains the individual characters, a scene itself is way more than that.

2. You can create software the same way, by using object oriented composition to combine simple, independent, distinct natured objects in to a larger, more complex yet enjoyable wholes.

In composition, the larger object (F.R.I.E.N.D.S, a scene) is connected to its parts (joey, chandler ross, rachel, phoebe, monica) by a has -a relationship

Composition3

Inherent within the definition of composition itself is the idea that not only does the show (say an episode scene) has all the characters, but each scene communicates with a character via an interface (audioplay). That's how every scene becomes epic

3. In composition, the bigger containing object interacts with the smaller contained objects or roles through an interface (Or simply a public method in the bigger object which when executed, gives insight into another objects properties )

We will create few scenes with help of composition.

Lets say we have a Scene class which should respond to audioplay message. This audioplay message should return a list of all dialogues by all characters as well all sounds in that scene.

Since a scene has characters, in a has-a relationship, lets go ahead and create a class Characters which holds a list of all characters and can account to which dialogue belongs to which character.

Composition4

The sequence diagram above illustrates this idea. Every Scene needs a Characters object, part of what it means to be a Scene is to "have-a" Characters.

**This naming convention to use plural class name to denote a group property has been suggested by Sandi Metz in the book POODR

Composition5

The diagram above shows the Scene and Characters classes connected by a line. The line attaches to Scene with a black diamond; this diamond indicates composition

Lets start with some code:

Step 1: Creating Scene

class Scene
 attr_reader :name, :characters

 def initialize(args = {})
  @name = args[:name]
  @characters = args[:characters]
 end

 def audioplay
   characters.audioplay
 end

end

Scene is now responsible for knowing its name, and holding onto its Characters and answering its audioplay

Most of the scene behaviors are dealt in Characters.

Step 2. Creating Characters

class Characters
  attr_reader :crowd_laughter, :apartment_sounds, :NYC_street_sounds

  def initialize(args = {})
    @crowd_laughter = args[:crowd_laughter] || default_crowd_laughter
    @apartment_sounds = args[:apartment_sounds] || default_apartment_sounds
    @NYC_street_sounds = args[:NYC_street_sounds] || default_NYC_street_sounds
    post_initialize(args)
  end

  def audioplay{
    {  crowd_laughter: crowd_laughter, apartment_sounds: 
       apartment_sounds,NYC_street_sounds: NYC_street_sounds}.merge(dialogues)
    }
  end
  
  def post_initialize(args)
   nil
 end

  def default_crowd_laughter
    'hahahaha hahaha'
  end

  def default_apartment_sounds
    'NYC apartment sounds'
  end

  def default_NYC_street_sounds
    police car sounds'
  end

  def dialogues
   {}
  end
  
end

-----------------------------------------------------------------------------------------------------------------------------
class Chandler< Characters
  attr_reader :sarcastic_dialogues

  def post_initialize(args)
    sarcastic_dialogues = args[:sarcastic_dialogues]
    chandler_accent = args[:chandler_accen]
  end
  
  def dialogues
    {sarcastic_dialogues: sarcastic_dialogues}
  end

end

Composition6

The code works great and with composition now we can play the chandler's scene for episode

the_one_where_chandler_can't_remember_which_sister_scene_5 = Scene.new(name: 'the_one_where_chandler_can't_remember_which_sister_scene_5', characters: Chandler.new(sarcastic_dialogues: 'Yeah! jell-o just like mom used to make.', chandler_accent: 'british'))

the_one_where_chandler_can't_remember_which_sister_scene_5.audioplay 
#{:crowd_laughter => 'hahahaha hahaha', :apartment_sounds: 
    => NYC apartment sounds', :NYC_street_sounds => 'police car sounds', :dialogues => 'Yeah! jell-o just like mom used to make.'

Composition7

Each characters interact with a scene using the interface audioplay. A whole audioplay for a scene is created as result of composition of each characters dialogue. So, if we want to extend any more characters, all we need to do is implement this interface.

Lets add Mark for "the One with All the Jealousy Scene 6" :

class Mark < Characters
  attr_reader :thoughtful_dialogues, :ross_accent

  def post_initialize(args)
    suave_dialogues = args[:suave_dialogues]
    mark_accent = args[:mark_accent]
  end
  
  def dialogues
    {suave_dialogues: suave_dialogues}
  end

end

Now MarkDialogues will implement the same interface dialogues to interact with Scene and we will can make a new scene with a new character Mark

the_one_with_all_the_jealousy_scene_6 = Scene.new(name: 'the_one_with_all_the_jealousy_scene_6', characters: Mark.new(suave_dialogues: 'Oh! hey its Mark', makr_accent: 'american'))

the_one_with_all_the_jealousy_scene_6.audioplay 
# {:crowd_laughter => 'hahahaha hahaha', :apartment_sounds: 
    => 'NYC apartment sounds', :NYC_street_sounds => 'police car sounds', :dialogues => 'Oh! hey its Mark.'

And the last one for Ross

class Ross < Characters
  attr_reader :thoughtful_dialogues, :ross_accent

  def post_initialize(args)
    thoughtful_dialogues = args[:thoughtful_dialogues]
    ross_accent = args[:ross_accent]
  end
  
  def dialogues
    {thoughtful_dialogues: thoughtful_dialogues}
  end

end

**This code may undergo more refactoring, I will re-share if any changes is made.

Please let me know your suggestions and what you think :)

twitter: sprakash24oct

Owned & Maintained by Saurav Prakash

If you like what you see, you can help me cover server costs or buy me a cup of coffee though donation :)