Exhibits and Presenters


Published on

Briefly about Decorator, Exhibits and Presenter Patterns

Published in: Design, Technology
1 Like
  • Be the first to comment

No Downloads
Total views
On SlideShare
From Embeds
Number of Embeds
Embeds 0
No embeds

No notes for slide

Exhibits and Presenters

  1. 1. @AtifTweetsExhibits and Presenters
  2. 2. @AtifTweetsAgenda• Decorators• Exhibits• Presenters
  3. 3. @AtifTweetsDecoratorsPresentersExhibits
  4. 4. @AtifTweetsDecorators“Decorators attach additional responsibilities to an object dynamically. They provide aflexible alternative to subclassing for extending functionality.” - Design Patterns:Elements of Reusable Object-Oriented Software - GoF
  5. 5. @AtifTweetsDecorators• Decorators: The Cure for Ugly Code• Can easily add responsibility for any object• Delegate any unknown method to object itdecorates• Decorators only copy the type of thecomponent class not the behaviour• Follow open and close philosophy = Open toExtend … Close for Modifications
  6. 6. @AtifTweets
  7. 7. @AtifTweetsThe decorator pattern
  8. 8. @AtifTweetsWhy do we need this?• Only thing constant is the CHANGE• Inheritance Powerful but NOT Flexible orMaintainable design pattern• So we prefer Composition and Delegation
  9. 9. @AtifTweetsExampleexample courtesy Head First Design Patterns
  10. 10. @AtifTweetsCoffeessimo• A big coffee chain• They have some basic coffee drink types• And also customers can customize therecoffee by adding different condiments onoffer• They have coffee types: HouseBlend,DarkRoast, Espresso, Decaf• Condiment types: Milk, Mocha, Soy, Whip
  11. 11. @AtifTweetsClass Explosion
  12. 12. @AtifTweets
  13. 13. @AtifTweetsDark Roastcost()
  14. 14. @AtifTweetsDark Roastcost()Mochacost()
  15. 15. @AtifTweetsDarkRoastcost()Mochacost()WhipCost()Whip Mocha Dark Roast coffee is ready!
  16. 16. @AtifTweetsDarkRoastcost()Mochacost()WhipCost()Cost0.200.100.99€1.29
  17. 17. @AtifTweetsEspressocost()Whipcost()Dynamically created different coffees0.10 0.90Decafcost()Mochacost()0.20 1.20€1.00€1.40Whip Espresso Mocha Decaf
  18. 18. @AtifTweetsExhibits
  19. 19. @AtifTweetsExhibits• Flavor of Decorators• The primary goal of exhibits is to connect amodel object with a context for which itsrendered• Very often youll likely want to add someadditional functionality. Such is the case withexhibits. The additional functionality addedwill extend (but not disrupt) the delegateobject.
  20. 20. @AtifTweetsExhibits• Wraps a single model instance.• Is a true Decorator.• Brings together a model and a context. Exhibits needa reference to a "context" object—either a controlleror a view context—in order to be able to rendertemplates as well as construct URLs for the object orrelated resources.• Encapsulates decisions about how to render anobject. The tell-tale of an Exhibit is telling an object"render yourself", rather than explicitly rendering atemplate and passing the object in as an argument.
  21. 21. @AtifTweetsExampleclass CarExhibit < Decoratordef initialize(car, context)@context = contextsuper(car) # Set up delegationenddef additional_info"Some cars with 2 doors have a back seat, somedont. Brilliant."enddef render@context.render(self)endendclass TextRendererdef render(car)"A shiny car!#{car.additional_info}"endendclass HtmlRendererdef render(car)"A <strong>shiny</strong> car!<em>#{car.additional_info}</em>"endendclass Cardef price1_000_000endendexample courtesy mikepackdev.com
  22. 22. @AtifTweetscar = CarExhibit.new(Car.new, TextRenderer.new)car.render #=> "A shiny car! Some cars with 2 doors have a back seat, some dont.Brilliant.“car.price #=> 1000000car2 = CarExhibit.new(Car.new, HtmlRenderer.new)car2.render #=> "A <strong>shiny</strong> car! <em>Some cars with 2 doors have aback seat, some dont. Brilliant.</em>"
  23. 23. @AtifTweetsPresenters
  24. 24. @AtifTweetsa_view.html.rb<% if entry.image_url.present? %><%= render "/posts/picture_body", post: entry %><% else %><%= render "posts/text_body", post: entry %><% end %>
  25. 25. @AtifTweetsVIEW MODEL
  26. 26. @AtifTweetsPresenters• Presenters were originally formed as a morecomposite-oreinted object, but modern daypresenters are more like decorators.• Presenter deals with view and model• Clean the view by moving the logic to thepresenter class
  27. 27. @AtifTweetsVIEW MODELPRESENTERLogicMain Goal
  28. 28. @AtifTweetsSecondary GoalVIEW MODELPRESENTERHelpermethodsmethods
  29. 29. @AtifTweetsDifference b/w Exhibit and Presenters• A key differentiator between exhibits andpresenters is the language they speak. Exhibitsshouldnt know about the language of the view(eg HTML). Exhibits speak the language of thedecorated object. Presenters speak the languageof the view.• Presenters and exhibits differ in their proximityto the view. Presenters live very close to the viewlayer. In fact, they are meant to be arepresentation of the delegate object within theview.
  30. 30. @AtifTweetsPresenter in actionexample courtesy railscast.com
  31. 31. @AtifTweets
  32. 32. @AtifTweets/app/views/users/show.html.erb<div id="profile"><%= link_to_if @user.url.present?,image_tag("avatars/#{avatar_name(@user)}", class: "avatar"), @user.url%><h1><%= link_to_if @user.url.present?, (@user.full_name.present? ?@user.full_name : @user.username), @user.url %></h1><dl><dt>Username:</dt><dd><%= @user.username %></dd><dt>Member Since:</dt><dd><%= @user.member_since %></dd><dt>Website:</dt><dd><% if @user.url.present? %><%= link_to @user.url, @user.url %><% else %><span class="none">None given</span><% end %></dd><dt>Twitter:</dt>.....
  33. 33. @AtifTweets<%= link_to_if @user.url.present?, image_tag("avatars/#{avatar_name(@user)}", class:"avatar"), @user.url %>Helper Methodmodule UsersHelperdef avatar_name(user)if user.avatar_image_name.present?user.avatar_image_nameelse"default.png"endendendCondition
  34. 34. @AtifTweets/app/presenters/user_presenter.rbclass UserPresenterdef initialize(user, template)@user = user@template = templateenddef avatar@template.link_to_if @user.url.present?, @template.image_tag("avatars/#{avatar_name}", class:"avatar"), @user.urlendprivatedef avatar_nameif @user.avatar_image_name.present?@user.avatar_image_nameelse"default.png"endendend
  35. 35. @AtifTweets/app/views/users/show.html.erb<% present @user do |user_presenter|%><div id="profile"><%= user_presenter.avatar %><!-- Rest of view code omitted --></div><% end %>module ApplicationHelperdef present(object, klass = nil)klass ||= "{object.class}Presenter".constantizepresenter = klass.new(object, self)yield presenter if block_given?presenterendend
  36. 36. @AtifTweetsFurther learning• Head First Design Patterns di Eric Freeman,Elisabeth Freeman, Kathy Sierra e Bert Bates• Design Patterns in Ruby di Russ Olsen• Design Patterns for Dummies• Objects on Rails by Avdi Grimm• http://mikepackdev.com/blog_posts/31-exhibit-vs• http://railscasts.com/episodes/287-presenters-fro
  37. 37. @AtifTweetsGrazie!