SlideShare ist ein Scribd-Unternehmen logo
1 von 98
Downloaden Sie, um offline zu lesen
Postobjektové
programovanie v Ruby
    @tkramar, @jsuchal
Paradigma
model, súbor princípov, spôsob uchopenia
                problému
Aké paradigmy poznáte?
           procedurálna (C, Basic, COBOL, ..)
      zdieľané dáta, procedúry operujúce nad dátami
            objektová (Ruby, Java, Python, ..)
  zapuzdrené dáta, metódy operujúce nad stavom objektu
        funkcionálna (Lisp, Haskell, Scheme, ..)
    dáta = program, čisté výrazy, bez vedľajších efektov
                    logická (PROLOG)
deklaratívne programovanie - fakty a predikáty, odvodzovanie
Objekt
 identita

  stav

správanie
class Person
  @name = ''

  def initialize(name)
    @name = name
  end

  def say
    "Ahoj, ja som #{@name}"
  end
end
Person
                   Stav
@name

                Správanie
def say
  "Ahoj, ja som #{@name}"
end

                 Identita
p = Person.new('Janko')
o.object_id
Identita
        sú dva objekty rovnaké?
                  ==

sú dva objekty rovnaké a rovnakého typu?
                   eql?

        sú dva objekty totožné?
               equals?
Identita
p1 = Person.new('Janko')
#=> #<Person:0x00000001b5c100 @name="Janko">
p2 = Person.new('Janko')
#=> #<Person:0x00000001b556e8 @name="Janko">

family = []
family << p1
family << p2

family.uniq
#=> [#<Person:0x00000001b5c100 @name="Janko">,
     #<Person:0x00000001b556e8 @name="Janko">]
class Person
  def ==(other)
    other.name == @name
  end

  def eql?(other)
    self == other
  end
end
Identita
p1 = Person.new('Janko')
#=> #<Person:0x00000001b5c100 @name="Janko">
p2 = Person.new('Janko')
#=> #<Person:0x00000001b556e8 @name="Janko">

family = []
family << p1
family << p2

family.uniq
#=> [#<Person:0x00000001b5c100 @name="Janko">,
     #<Person:0x00000001b556e8 @name="Janko">]
class Person
  def hash
    @name.hash
  end
end
Identita
p1 = Person.new('Janko')
#=> #<Person:0x00000001b5c100 @name="Janko">
p2 = Person.new('Janko')
#=> #<Person:0x00000001b556e8 @name="Janko">

family = []
family << p1
family << p2

family.uniq
#=> [#<Person:0x00000001b5c100 @name="Janko">]
Základné koncepty
         inheritance (dedenie)

method overloading (preťažovanie metód)

method overriding (prekonávanie metód)
Dedenie
class Instrument
  def tune
    ...
  end
end

class Violin < Instrument
  def play
    tune
    "Taa daa"
  end
end
Overloading v ruby nefunguje
class Instrument
  def play
    "Ta da"
  end

  def play(octave)
    "Ta da #{octave}"
  end
end

i = Instrument.new
i.play #=> ArgumentError: wrong number of arguments (0 for 1)
i.play('c dur') #=> "Ta da c dur"
Overriding
class Instrument
  def play
    "Ta da"
  end
end

class Violin < Instrument
  def play
    "Tiii diii tiii"
  end
end

v = Violin.new
v.play #=> "Tiii diii tiii"
Polymorfia
class Instrument
  def play
  end
end
class Violin < Instrument
  def play
    "Taa daa"
  end
end

class Drum < Instrument
  def play
    "Dum dum"
  end
end

orchestra = [Violin.new, Violin.new, Drum.new]
orchestra.each { |i| i.play }
#=> "Taa daa", "Taa daa", "Dum dum"
Všetko v Ruby je Objekt
Aj nil
Object.class #=> Class
nil.class    #=> NilClass
ActiveSupport try
p = Person.find(params[:id])

p.address.downcase
#=> NoMethodError: undefined method `downcase'
#   for nil:NilClass

p.address.try :downcase #=> nil
Aj metóda
class Person
  def greet(other_person)
    "Ahoj #{other_person}"
  end
end

m = Person.instance_method(:greet)
m.class #=> UnboundMethod
m.arity #=> 1
m.name #=> :greet
m.parameters #=> [[:req, :other_person]]
Aj trieda
Class.class #=> Class

      .. o metaprogramovaní inokedy
Moduly
def Class < Module
Modul ako namespace
module Rubyslava
  class OOP
  end
end

module Pyvo
  class OOP
  end
end

Rubyslava::OOP == Pyvo::OOP #=> false
Modul ako nositeľ kódu
module Rubyslava
  def hello
    "Rubyslava"
  end
end
Mixiny
class RubyslavaAPyvo
  include Rubyslava
end

rp = RubyslavaAPyvo.new
rp.hello #=> "Rubyslava"

class RubyslavaAPyvo
  extend Rubyslava
end

RubyslavaAPyvo.hello #=> "Rubyslava"
Viacnásobné dedenie
class RubyslavaAPyvo < Array
  include Rubyslava, Pyvo
end

RubyslavaAPyvo.ancestors
#=> [RubyslavaAPyvo, Rubyslava, Pyvo
#    Array, Object, Kernel, BasicObject]
Viditeľnosť v moduloch
    moduly zdieľajú všetko

   inštančné premenné (@)

           metódy
module AdditionalBehaviour
  def show
    greet
  end
end

class Test
  include AdditionalBehaviour

  def greet
    "hello"
  end
end

Test.new.show #=> "hello"
module GreetingBehavior
  def greet
    "hello"
  end
end

module RelyOnGreetingBehavior
  def show
    greet
  end
end

class Test
  include GreetingBehavior, RelyOnGreetingBehavior
end
Test.new.show #=> "hello"
Zo života
     Enumerable

      acts_as_..

ActiveSupport::Concern
class Tree
  include Enumerable

  def each(&block)
    leafs.each do { |n| yield n }
  end
end

t = Tree.new
t.map
t.inject
t.sum
...
class Post
  acts_as_taggable
end

p = Post.find(1)
p.tag_list #=> ["Ruby", "OOP"]
ActiveSupport::Concern
module Annotatable
  extend ActiveSupport::Concern
 included do
   has_many :notes, :as => :annotatable,
            :order => "created_at DESC"
 end

  def most_annotated
    joins(:notes).group(:id).order("COUNT(*) DESC").first
  end
end
class Project < ActiveRecord::Base
  include Annotatable, Importable, Versionable
end
Idiómy
jazykovo špecifické vzory
Ruby idiómy
         bloky

       a, b = b,a

     a, b, c = array

(cachovanie) @var ||= ..
Bloky
transaction do |transaction|
  transaction.rollback if error?
end

Dir.chdir('/') do
end

with_disabled_keys do
end

with_nested_loop_plan do
end
Vzory
Všeobecné riešenie často sa opakujúceho
problému. Nie je to knižnica, ani kód, skôr
                šablóna.
"When I see patterns in
my programs, I consider it
    a sign of trouble."
        (Paul Graham)
Vzory, ktoré v Ruby
netreba programovať
Singleton
Problém: Zabezpečiť jednotný prístup k zdrojom
               (napr. databáza)
Zlo, česť výnimkám (ActiveSupport::Inflections)
Singleton
class Logger
  def initialize
    @log = File.open("log.txt", "a")
  end

 @@instance = Logger.new

 def self.instance
   @@instance
 end

 def log(msg)
   @log.puts(msg)
 end

  private_class_method :new
end
Logger.instance.log('message 1')
Singleton (lepšie)
require 'singleton'

class Logger
  include Singleton

  def initialize
    @log = File.open("log.txt", "a")
  end

  def log(msg)
    @log.puts(msg)
  end
end

Logger.instance.log('message 2')
Iterator
Problém: Umožniť manipuláciu s kompozitným
objektom bez odhalenia jeho internej štruktúry
Iterator
class Tree
  include Enumerable

  def each(&block)
    leafs.each { |e| yield e }
  end
end
Decorator
Problém: pridávanie funkcionality do triedy
         počas behu programu

Dekorátor obalí pôvodnú triedu a kde treba
            rozšíri správanie
class StringDecorator < String
  def starts_with? substr
    # ...
  end
end

title = StringDecorator.new("Rubyslava")
Decorator = open classes
class String
  def starts_with? substr
    # ...
  end
end

"aye aye captain".starts_with? "pirate"
#=> false
Delegator
Problém: Skrytie vnútorných závislostí
Delegator
include 'forwardable'
class Car
  extend Forwardable

  def_delegators :@car_computer, :velocity,
                                 :distance

  def initialize
    @car_computer = CarComputer.new
  end
end

c = Car.new
c.velocity
c.distance
Proxy
Problém: Skrytie implementačných detailov
           načítavania zdroja
Proxy
require 'delegate'

class Future < SimpleDelegator
  def initialize(&block)
    @_thread = Thread.start(&block)
  end

  def __getobj__
    __setobj__(@_thread.value) if @_thread.alive?
    super
  end
end

google = Future.new do
  Net::HTTP.get_response(URI('http://www.google.com')).body
end
yahoo = Future.new do
  Net::HTTP.get_response(URI('http://www.yahoo.com')).body
end

puts google
puts yahoo
Ďalšie užitočné vzory
Template method
Problém: Často sa opakujúci boilerplate kód.
       Kostra programu, algoritmu.
class Game
  def play
    prepare_board
    initialize_score
    while not end_of_game?
      make_move
    end
  end
end

class Carcassonne < Game
  def make_move
    tile = tiles.pick_random
    ...
  end
end

class Agricola < Game
  def make_move
    peasant = select_peasant
    ...
  end
end
Composite
Problém: V stromových štruktúrach
zamaskovať implementačný detail:
           uzly a listy.
class Person
  def say
    "#{@name}"
  end
end
class Family
  attr_accessor :members

 def initialize(members)
   @members = members
 end
  def say
    @members.each { |m| m.say }
  end
end

f = Family.new(Person.new('Janko'), Person.new('Tomas'))
t = Family.new(Person.new('Ferko'), f)

t.say #=> "Ferko", "Janko", "Tomas"
Strategy
Problém: Výber vhodného algoritmu
        za behu programu
class FileLogger < Logger
  def log(message)
    File.open('a') { |f| f << message }
  end
end

class DatabaseLogger < Logger
  def log(message)
    Log.create(:message => message)
  end
end
State
Problém: Zmena správania objektu
       v rôznych stavoch
class TrafficLight
  include AlterEgo
 state :proceed, :default => true do
   handle :color do
     "green"
   end
   transition :to => :caution, :on => :cycle!
 end

 state :caution do
   handle :color do
     "yellow"
   end
   transition :to => :stop, :on => :cycle!
 end
  state :stop do
    handle :color do
      "red"
    end
    transition :to => :proceed, :on => :cycle!
  end
end
light = TrafficLight.new
light.color # => "green"
light.cycle!
light.color # => "yellow"
light.cycle!
light.color # => "red"
light.cycle!
light.color # => "green"
Observer
Problém: Oddelenie core funkcionality
 a špecifického správania v určitých
           stavoch objektu.
class Comment < ActiveRecord::Base
end

class CommentObserver < ActiveRecord::Observer
  def after_save(comment)
    Notifications.deliver_comment("admin@do.com",
         "New comment was posted", comment)
  end
end
Zápachy v kóde
 (Bad smells)
Vytváranie vlastného
 typového systému
      is_a?, kind_of?

   lepšie je respond_to?
class Container
  def add(node)
    if node.kind_of? Array
      node.each { |n| @nodes << n }
    else
      @nodes << node
    end
  end
end

container.add(Tree.new('a', 'b')) #=> ???
class Container
  def add(node)
    unless node.respond_to? :each
      node = [node]
    end
    node.each { |n| @nodes << n }
  end
end

container.add(Tree.new('a', 'b')) #=> ['a', 'b']
Protipríklad
      ActiveRecord::sanitize_sql_for_assignment
def sanitize_sql_for_assignment(assignments)
  case assignments
    when Array
      sanitize_sql_array(assignments)
    when Hash
      sanitize_sql_hash_for_assignment(assignments)
    else assignments
  end
end
Visitor + typy
def visit object
  method = "visit_#{object.class.name}"
    send method, object
  end

module Arel
  module Visitors
    class WhereSql < Arel::Visitors::ToSql
      def visit_Arel_Nodes_SelectCore o
        "WHERE #{o.wheres.map { |x| visit x }.join ' AND ' }"
      end
    end
  end
end
Shotgun surgery
ak niečo mením tak musím na viacerých
              miestach

        crosscutting concerns

           AOP (AspectJ)
AspectJ
pointcut writableHeaderMethods() :
  execution(* (WritableRequestHeader|| WritableResponseHeader) .*(..));

before(HeaderWrapper header) :
  writableHeaderMethods() && this(header) {
  ...
}
ActiveRecord::Observer

ActiveController::Caching::Sweeper

     before/after/around filtre
Caching
class DocumentController < ApplicationController
  caches_page :show
  caches_action :index

 def show; end
  def index; end
end
Autorizácia
class DocumentController < ApplicationController
  before_filter :find_document
 def show
   # render @document
 end

  private
    def find_document
      @document = Document.find_by_id(params[:id])
    end
end
class DocumentController < ApplicationController
  before_filter :find_document
  around_filer :authorize
  def show
    # render @document
  end

  private
    def find_document
      @document = Document.find_by_id(params[:id])
    end

      def authorize
        if current_user.can_view?(@document)
          yield
        else
            render :not_authorized
        end
      end
end
Ťažko testovateľná trieda
    skúsiť si najprv napísať test

                rcov
Duplicitný kód
      reek

    metric_fu

    rubymine

   refaktoring

  vzor Template
Často sa meniaci kód
        churn
Dlhá metóda
Dlhý zoznam parametrov
            *args

     nahradenie objektom

       fluent interfaces
def params(*args)
  puts args.class
  puts args.inspect
end

params('a', {:hello => 2}, 42)
#=> Array
#=> ["a", {:hello=>2}, 2]
activerecord 2.x
                     vs
              activerecord 3.x
Visit.first(:select => "happened_at",
            :order => "happened_at ASC").happened_at

Visit.select(:happened_at)
     .order("happened_at ASC").first.happened_at
Primitívna obsesia
class Debt < ActiveRecord::Base
  composed_of :debit,
              :class_name => "Money",
              :allow_nil => true,
              :mapping => [%w(debit_amount amount),
                           %w(debit_currency currency)]
end

debt.debit # => Money
switch/case
                 Template polymorfia
<% subject.infos.each do |info| %>
  <%= render :partial => "#{info.class.to_s}_detail",
             :subject => subject %>
<% end %>
Dátová trieda
Skinny controller, fat model
Dátová trieda
class SubjectController < ApplicationController
  def show
    if @subject.updated_at < Time.now - 2.weeks.ago
      @subject.refresh
    end
  end
end

class Subject < ActiveRecord::Base
end
Dátová trieda 2
class SubjectController < ApplicationController
  def show
    @subject.update_if_stale
  end
end
class Subject < ActiveRecord::Base
  def update_if_stale
    refresh if updated_at < Time.now - 2.weeks.ago
  end
end

class Person < Subject
  def update_if_stale
    # update vsetky firmy kde je subjekt
  end
end
Komentáre
# download new version of article
def perform(x)
  # load article from the url 'x'
  ...
end

def download_article(url)
  ...
end
SOLID Principles
Single responsibility
          principle
Objekt by mal mať iba jednu zodpovednosť

               observers

            cache sweepers

        moduly (include, extend)
Open/closed principle
Triedy by mali byť otvorené pre rozširovanie,
        ale uzavreté pre modifikáciu

        v ruby tomu ťažko zabrániť
Liskov substitution principle
  Každý nadtyp by mal byť nahraditeľný
              podtypom

             kruh/kružnica

           čo s polomerom?
Interface segregation
         principle
 Hierarchia v rámci rozhraní - radšej viac
špecifických rozhraní ako jedno obrovské

          v ruby nemá zmysel
Dependency inversion
     principle
Závislosť musí byť na rozhraní, nie na
      konkrétnej implementácii

        dependency injection
Domain driven design
          ambiguous language

Array#first, Array#second, Array#forty_two
class Subject < ActiveRecord::Base
  has_many :debts

  def is_suspicious?
    debts.any? or in_liquidation?
  end
end
Záver
With great power comes great responsibility
               (Spidermanov otec)

Weitere ähnliche Inhalte

Was ist angesagt?

Introduction to Clean Code
Introduction to Clean CodeIntroduction to Clean Code
Introduction to Clean CodeJulio Martinez
 
PYTHON-Chapter 3-Classes and Object-oriented Programming: MAULIK BORSANIYA
PYTHON-Chapter 3-Classes and Object-oriented Programming: MAULIK BORSANIYAPYTHON-Chapter 3-Classes and Object-oriented Programming: MAULIK BORSANIYA
PYTHON-Chapter 3-Classes and Object-oriented Programming: MAULIK BORSANIYAMaulik Borsaniya
 
Anonymous Classes: Behind the Mask
Anonymous Classes: Behind the MaskAnonymous Classes: Behind the Mask
Anonymous Classes: Behind the MaskMark Baker
 
Exploring Ceylon with Gavin King - JUG BB Talk - Belrin 2014
Exploring Ceylon with Gavin King - JUG BB Talk - Belrin 2014Exploring Ceylon with Gavin King - JUG BB Talk - Belrin 2014
Exploring Ceylon with Gavin King - JUG BB Talk - Belrin 2014hwilming
 
Object Oriented Programming with PHP 5 - More OOP
Object Oriented Programming with PHP 5 - More OOPObject Oriented Programming with PHP 5 - More OOP
Object Oriented Programming with PHP 5 - More OOPWildan Maulana
 
Scala presentation by Aleksandar Prokopec
Scala presentation by Aleksandar ProkopecScala presentation by Aleksandar Prokopec
Scala presentation by Aleksandar ProkopecLoïc Descotte
 
The Ring programming language version 1.5.2 book - Part 6 of 181
The Ring programming language version 1.5.2 book - Part 6 of 181The Ring programming language version 1.5.2 book - Part 6 of 181
The Ring programming language version 1.5.2 book - Part 6 of 181Mahmoud Samir Fayed
 
Kotlin on Android: Delegate with pleasure
Kotlin on Android: Delegate with pleasureKotlin on Android: Delegate with pleasure
Kotlin on Android: Delegate with pleasureDmytro Zaitsev
 
Object Calisthenics em Go
Object Calisthenics em GoObject Calisthenics em Go
Object Calisthenics em GoElton Minetto
 
Lecture on Rubinius for Compiler Construction at University of Twente
Lecture on Rubinius for Compiler Construction at University of TwenteLecture on Rubinius for Compiler Construction at University of Twente
Lecture on Rubinius for Compiler Construction at University of TwenteDirkjan Bussink
 
Creating Domain Specific Languages in Python
Creating Domain Specific Languages in PythonCreating Domain Specific Languages in Python
Creating Domain Specific Languages in PythonSiddhi
 
Object oriented programming with python
Object oriented programming with pythonObject oriented programming with python
Object oriented programming with pythonArslan Arshad
 
Advanced Python, Part 1
Advanced Python, Part 1Advanced Python, Part 1
Advanced Python, Part 1Zaar Hai
 
Object Oriented Programming in PHP
Object Oriented Programming in PHPObject Oriented Programming in PHP
Object Oriented Programming in PHPLorna Mitchell
 

Was ist angesagt? (20)

Introduction to Clean Code
Introduction to Clean CodeIntroduction to Clean Code
Introduction to Clean Code
 
Groovy!
Groovy!Groovy!
Groovy!
 
Values
ValuesValues
Values
 
PYTHON-Chapter 3-Classes and Object-oriented Programming: MAULIK BORSANIYA
PYTHON-Chapter 3-Classes and Object-oriented Programming: MAULIK BORSANIYAPYTHON-Chapter 3-Classes and Object-oriented Programming: MAULIK BORSANIYA
PYTHON-Chapter 3-Classes and Object-oriented Programming: MAULIK BORSANIYA
 
Anonymous Classes: Behind the Mask
Anonymous Classes: Behind the MaskAnonymous Classes: Behind the Mask
Anonymous Classes: Behind the Mask
 
Exploring Ceylon with Gavin King - JUG BB Talk - Belrin 2014
Exploring Ceylon with Gavin King - JUG BB Talk - Belrin 2014Exploring Ceylon with Gavin King - JUG BB Talk - Belrin 2014
Exploring Ceylon with Gavin King - JUG BB Talk - Belrin 2014
 
Beyond java8
Beyond java8Beyond java8
Beyond java8
 
Oop concepts in python
Oop concepts in pythonOop concepts in python
Oop concepts in python
 
Object Oriented Programming with PHP 5 - More OOP
Object Oriented Programming with PHP 5 - More OOPObject Oriented Programming with PHP 5 - More OOP
Object Oriented Programming with PHP 5 - More OOP
 
Scala presentation by Aleksandar Prokopec
Scala presentation by Aleksandar ProkopecScala presentation by Aleksandar Prokopec
Scala presentation by Aleksandar Prokopec
 
The Ring programming language version 1.5.2 book - Part 6 of 181
The Ring programming language version 1.5.2 book - Part 6 of 181The Ring programming language version 1.5.2 book - Part 6 of 181
The Ring programming language version 1.5.2 book - Part 6 of 181
 
Kotlin on Android: Delegate with pleasure
Kotlin on Android: Delegate with pleasureKotlin on Android: Delegate with pleasure
Kotlin on Android: Delegate with pleasure
 
All about scala
All about scalaAll about scala
All about scala
 
Object Calisthenics em Go
Object Calisthenics em GoObject Calisthenics em Go
Object Calisthenics em Go
 
Lecture on Rubinius for Compiler Construction at University of Twente
Lecture on Rubinius for Compiler Construction at University of TwenteLecture on Rubinius for Compiler Construction at University of Twente
Lecture on Rubinius for Compiler Construction at University of Twente
 
Creating Domain Specific Languages in Python
Creating Domain Specific Languages in PythonCreating Domain Specific Languages in Python
Creating Domain Specific Languages in Python
 
Object oriented programming with python
Object oriented programming with pythonObject oriented programming with python
Object oriented programming with python
 
Advanced Python, Part 1
Advanced Python, Part 1Advanced Python, Part 1
Advanced Python, Part 1
 
ddd+scala
ddd+scaladdd+scala
ddd+scala
 
Object Oriented Programming in PHP
Object Oriented Programming in PHPObject Oriented Programming in PHP
Object Oriented Programming in PHP
 

Andere mochten auch

Vojtech Rinik: Internship v USA - moje skúsenosti
Vojtech Rinik: Internship v USA - moje skúsenostiVojtech Rinik: Internship v USA - moje skúsenosti
Vojtech Rinik: Internship v USA - moje skúsenostiJano Suchal
 
Peter Mihalik: Puppet
Peter Mihalik: PuppetPeter Mihalik: Puppet
Peter Mihalik: PuppetJano Suchal
 
Tomáš Čorej: Configuration management & CFEngine3
Tomáš Čorej: Configuration management & CFEngine3Tomáš Čorej: Configuration management & CFEngine3
Tomáš Čorej: Configuration management & CFEngine3Jano Suchal
 
Metaprogramovanie #1
Metaprogramovanie #1Metaprogramovanie #1
Metaprogramovanie #1Jano Suchal
 
Bonetics: Mastering Puppet Workshop
Bonetics: Mastering Puppet WorkshopBonetics: Mastering Puppet Workshop
Bonetics: Mastering Puppet WorkshopJano Suchal
 
Ako si vybrať programovácí jazyk alebo framework?
Ako si vybrať programovácí jazyk alebo framework?Ako si vybrať programovácí jazyk alebo framework?
Ako si vybrať programovácí jazyk alebo framework?Jano Suchal
 
sme.sk čočítať ontožíur-2010
sme.sk čočítať ontožíur-2010sme.sk čočítať ontožíur-2010
sme.sk čočítať ontožíur-2010Jano Suchal
 

Andere mochten auch (7)

Vojtech Rinik: Internship v USA - moje skúsenosti
Vojtech Rinik: Internship v USA - moje skúsenostiVojtech Rinik: Internship v USA - moje skúsenosti
Vojtech Rinik: Internship v USA - moje skúsenosti
 
Peter Mihalik: Puppet
Peter Mihalik: PuppetPeter Mihalik: Puppet
Peter Mihalik: Puppet
 
Tomáš Čorej: Configuration management & CFEngine3
Tomáš Čorej: Configuration management & CFEngine3Tomáš Čorej: Configuration management & CFEngine3
Tomáš Čorej: Configuration management & CFEngine3
 
Metaprogramovanie #1
Metaprogramovanie #1Metaprogramovanie #1
Metaprogramovanie #1
 
Bonetics: Mastering Puppet Workshop
Bonetics: Mastering Puppet WorkshopBonetics: Mastering Puppet Workshop
Bonetics: Mastering Puppet Workshop
 
Ako si vybrať programovácí jazyk alebo framework?
Ako si vybrať programovácí jazyk alebo framework?Ako si vybrať programovácí jazyk alebo framework?
Ako si vybrať programovácí jazyk alebo framework?
 
sme.sk čočítať ontožíur-2010
sme.sk čočítať ontožíur-2010sme.sk čočítať ontožíur-2010
sme.sk čočítať ontožíur-2010
 

Ähnlich wie Postobjektové programovanie v Ruby

Desarrollando aplicaciones web en minutos
Desarrollando aplicaciones web en minutosDesarrollando aplicaciones web en minutos
Desarrollando aplicaciones web en minutosEdgar Suarez
 
Metaprogramming 101
Metaprogramming 101Metaprogramming 101
Metaprogramming 101Nando Vieira
 
Attributes Unwrapped: Lessons under the surface of active record
Attributes Unwrapped: Lessons under the surface of active recordAttributes Unwrapped: Lessons under the surface of active record
Attributes Unwrapped: Lessons under the surface of active record.toster
 
A tour on ruby and friends
A tour on ruby and friendsA tour on ruby and friends
A tour on ruby and friends旻琦 潘
 
Ruby 程式語言入門導覽
Ruby 程式語言入門導覽Ruby 程式語言入門導覽
Ruby 程式語言入門導覽Wen-Tien Chang
 
Ruby Programming Language
Ruby Programming LanguageRuby Programming Language
Ruby Programming LanguageDuda Dornelles
 
A linguagem de programação Ruby - Robson "Duda" Sejan Soares Dornelles
A linguagem de programação Ruby - Robson "Duda" Sejan Soares DornellesA linguagem de programação Ruby - Robson "Duda" Sejan Soares Dornelles
A linguagem de programação Ruby - Robson "Duda" Sejan Soares DornellesTchelinux
 
Ruby/Rails
Ruby/RailsRuby/Rails
Ruby/Railsrstankov
 
Ruby: OOP, metaprogramming, blocks, iterators, mix-ins, duck typing. Code style
Ruby: OOP, metaprogramming, blocks, iterators, mix-ins, duck typing. Code styleRuby: OOP, metaprogramming, blocks, iterators, mix-ins, duck typing. Code style
Ruby: OOP, metaprogramming, blocks, iterators, mix-ins, duck typing. Code styleAnton Shemerey
 
Uses & Abuses of Mocks & Stubs
Uses & Abuses of Mocks & StubsUses & Abuses of Mocks & Stubs
Uses & Abuses of Mocks & StubsPatchSpace Ltd
 
Rapid Development with Ruby/JRuby and Rails
Rapid Development with Ruby/JRuby and RailsRapid Development with Ruby/JRuby and Rails
Rapid Development with Ruby/JRuby and Railselliando dias
 
Blocks by Lachs Cox
Blocks by Lachs CoxBlocks by Lachs Cox
Blocks by Lachs Coxlachie
 
jRuby: The best of both worlds
jRuby: The best of both worldsjRuby: The best of both worlds
jRuby: The best of both worldsChristopher Spring
 

Ähnlich wie Postobjektové programovanie v Ruby (20)

Desarrollando aplicaciones web en minutos
Desarrollando aplicaciones web en minutosDesarrollando aplicaciones web en minutos
Desarrollando aplicaciones web en minutos
 
An introduction to Ruby
An introduction to RubyAn introduction to Ruby
An introduction to Ruby
 
Language supports it
Language supports itLanguage supports it
Language supports it
 
Why ruby
Why rubyWhy ruby
Why ruby
 
Metaprogramming 101
Metaprogramming 101Metaprogramming 101
Metaprogramming 101
 
Attributes Unwrapped: Lessons under the surface of active record
Attributes Unwrapped: Lessons under the surface of active recordAttributes Unwrapped: Lessons under the surface of active record
Attributes Unwrapped: Lessons under the surface of active record
 
Ruby
RubyRuby
Ruby
 
A tour on ruby and friends
A tour on ruby and friendsA tour on ruby and friends
A tour on ruby and friends
 
Designing Ruby APIs
Designing Ruby APIsDesigning Ruby APIs
Designing Ruby APIs
 
Ruby 程式語言入門導覽
Ruby 程式語言入門導覽Ruby 程式語言入門導覽
Ruby 程式語言入門導覽
 
Ruby Basics
Ruby BasicsRuby Basics
Ruby Basics
 
Ruby tricks2
Ruby tricks2Ruby tricks2
Ruby tricks2
 
Ruby Programming Language
Ruby Programming LanguageRuby Programming Language
Ruby Programming Language
 
A linguagem de programação Ruby - Robson "Duda" Sejan Soares Dornelles
A linguagem de programação Ruby - Robson "Duda" Sejan Soares DornellesA linguagem de programação Ruby - Robson "Duda" Sejan Soares Dornelles
A linguagem de programação Ruby - Robson "Duda" Sejan Soares Dornelles
 
Ruby/Rails
Ruby/RailsRuby/Rails
Ruby/Rails
 
Ruby: OOP, metaprogramming, blocks, iterators, mix-ins, duck typing. Code style
Ruby: OOP, metaprogramming, blocks, iterators, mix-ins, duck typing. Code styleRuby: OOP, metaprogramming, blocks, iterators, mix-ins, duck typing. Code style
Ruby: OOP, metaprogramming, blocks, iterators, mix-ins, duck typing. Code style
 
Uses & Abuses of Mocks & Stubs
Uses & Abuses of Mocks & StubsUses & Abuses of Mocks & Stubs
Uses & Abuses of Mocks & Stubs
 
Rapid Development with Ruby/JRuby and Rails
Rapid Development with Ruby/JRuby and RailsRapid Development with Ruby/JRuby and Rails
Rapid Development with Ruby/JRuby and Rails
 
Blocks by Lachs Cox
Blocks by Lachs CoxBlocks by Lachs Cox
Blocks by Lachs Cox
 
jRuby: The best of both worlds
jRuby: The best of both worldsjRuby: The best of both worlds
jRuby: The best of both worlds
 

Mehr von Jano Suchal

Slovensko.Digital: Čo ďalej?
Slovensko.Digital: Čo ďalej?Slovensko.Digital: Čo ďalej?
Slovensko.Digital: Čo ďalej?Jano Suchal
 
Improving code quality
Improving code qualityImproving code quality
Improving code qualityJano Suchal
 
Beyond search queries
Beyond search queriesBeyond search queries
Beyond search queriesJano Suchal
 
Rank all the things!
Rank all the things!Rank all the things!
Rank all the things!Jano Suchal
 
Rank all the (geo) things!
Rank all the (geo) things!Rank all the (geo) things!
Rank all the (geo) things!Jano Suchal
 
Ako si vybrať programovací jazyk a framework?
Ako si vybrať programovací jazyk a framework?Ako si vybrať programovací jazyk a framework?
Ako si vybrať programovací jazyk a framework?Jano Suchal
 
SQL: Query optimization in practice
SQL: Query optimization in practiceSQL: Query optimization in practice
SQL: Query optimization in practiceJano Suchal
 
Garelic: Google Analytics as App Performance monitoring
Garelic: Google Analytics as App Performance monitoringGarelic: Google Analytics as App Performance monitoring
Garelic: Google Analytics as App Performance monitoringJano Suchal
 
Miroslav Šimulčík: Temporálne databázy
Miroslav Šimulčík: Temporálne databázyMiroslav Šimulčík: Temporálne databázy
Miroslav Šimulčík: Temporálne databázyJano Suchal
 
Profiling and monitoring ruby & rails applications
Profiling and monitoring ruby & rails applicationsProfiling and monitoring ruby & rails applications
Profiling and monitoring ruby & rails applicationsJano Suchal
 
Aký programovací jazyk a framework si vybrať a prečo?
Aký programovací jazyk a framework si vybrať a prečo?Aký programovací jazyk a framework si vybrať a prečo?
Aký programovací jazyk a framework si vybrať a prečo?Jano Suchal
 
Petr Joachim: Redis na Super.cz
Petr Joachim: Redis na Super.czPetr Joachim: Redis na Super.cz
Petr Joachim: Redis na Super.czJano Suchal
 
PostgreSQL: Advanced features in practice
PostgreSQL: Advanced features in practicePostgreSQL: Advanced features in practice
PostgreSQL: Advanced features in practiceJano Suchal
 
elasticsearch - advanced features in practice
elasticsearch - advanced features in practiceelasticsearch - advanced features in practice
elasticsearch - advanced features in practiceJano Suchal
 
Odporúčacie systémy a služba sme.sk čo čítať
Odporúčacie systémy a služba sme.sk čo čítaťOdporúčacie systémy a služba sme.sk čo čítať
Odporúčacie systémy a služba sme.sk čo čítaťJano Suchal
 

Mehr von Jano Suchal (17)

Slovensko.Digital: Čo ďalej?
Slovensko.Digital: Čo ďalej?Slovensko.Digital: Čo ďalej?
Slovensko.Digital: Čo ďalej?
 
Datanest 3.0
Datanest 3.0Datanest 3.0
Datanest 3.0
 
Improving code quality
Improving code qualityImproving code quality
Improving code quality
 
Beyond search queries
Beyond search queriesBeyond search queries
Beyond search queries
 
Rank all the things!
Rank all the things!Rank all the things!
Rank all the things!
 
Rank all the (geo) things!
Rank all the (geo) things!Rank all the (geo) things!
Rank all the (geo) things!
 
Ako si vybrať programovací jazyk a framework?
Ako si vybrať programovací jazyk a framework?Ako si vybrať programovací jazyk a framework?
Ako si vybrať programovací jazyk a framework?
 
SQL: Query optimization in practice
SQL: Query optimization in practiceSQL: Query optimization in practice
SQL: Query optimization in practice
 
Garelic: Google Analytics as App Performance monitoring
Garelic: Google Analytics as App Performance monitoringGarelic: Google Analytics as App Performance monitoring
Garelic: Google Analytics as App Performance monitoring
 
Miroslav Šimulčík: Temporálne databázy
Miroslav Šimulčík: Temporálne databázyMiroslav Šimulčík: Temporálne databázy
Miroslav Šimulčík: Temporálne databázy
 
Profiling and monitoring ruby & rails applications
Profiling and monitoring ruby & rails applicationsProfiling and monitoring ruby & rails applications
Profiling and monitoring ruby & rails applications
 
Aký programovací jazyk a framework si vybrať a prečo?
Aký programovací jazyk a framework si vybrať a prečo?Aký programovací jazyk a framework si vybrať a prečo?
Aký programovací jazyk a framework si vybrať a prečo?
 
Čo po GAMČI?
Čo po GAMČI?Čo po GAMČI?
Čo po GAMČI?
 
Petr Joachim: Redis na Super.cz
Petr Joachim: Redis na Super.czPetr Joachim: Redis na Super.cz
Petr Joachim: Redis na Super.cz
 
PostgreSQL: Advanced features in practice
PostgreSQL: Advanced features in practicePostgreSQL: Advanced features in practice
PostgreSQL: Advanced features in practice
 
elasticsearch - advanced features in practice
elasticsearch - advanced features in practiceelasticsearch - advanced features in practice
elasticsearch - advanced features in practice
 
Odporúčacie systémy a služba sme.sk čo čítať
Odporúčacie systémy a služba sme.sk čo čítaťOdporúčacie systémy a služba sme.sk čo čítať
Odporúčacie systémy a služba sme.sk čo čítať
 

Postobjektové programovanie v Ruby

  • 2. Paradigma model, súbor princípov, spôsob uchopenia problému
  • 3. Aké paradigmy poznáte? procedurálna (C, Basic, COBOL, ..) zdieľané dáta, procedúry operujúce nad dátami objektová (Ruby, Java, Python, ..) zapuzdrené dáta, metódy operujúce nad stavom objektu funkcionálna (Lisp, Haskell, Scheme, ..) dáta = program, čisté výrazy, bez vedľajších efektov logická (PROLOG) deklaratívne programovanie - fakty a predikáty, odvodzovanie
  • 4. Objekt identita stav správanie
  • 5. class Person @name = '' def initialize(name) @name = name end def say "Ahoj, ja som #{@name}" end end
  • 6. Person Stav @name Správanie def say "Ahoj, ja som #{@name}" end Identita p = Person.new('Janko') o.object_id
  • 7. Identita sú dva objekty rovnaké? == sú dva objekty rovnaké a rovnakého typu? eql? sú dva objekty totožné? equals?
  • 8. Identita p1 = Person.new('Janko') #=> #<Person:0x00000001b5c100 @name="Janko"> p2 = Person.new('Janko') #=> #<Person:0x00000001b556e8 @name="Janko"> family = [] family << p1 family << p2 family.uniq #=> [#<Person:0x00000001b5c100 @name="Janko">, #<Person:0x00000001b556e8 @name="Janko">]
  • 9. class Person def ==(other) other.name == @name end def eql?(other) self == other end end
  • 10. Identita p1 = Person.new('Janko') #=> #<Person:0x00000001b5c100 @name="Janko"> p2 = Person.new('Janko') #=> #<Person:0x00000001b556e8 @name="Janko"> family = [] family << p1 family << p2 family.uniq #=> [#<Person:0x00000001b5c100 @name="Janko">, #<Person:0x00000001b556e8 @name="Janko">]
  • 11. class Person def hash @name.hash end end
  • 12. Identita p1 = Person.new('Janko') #=> #<Person:0x00000001b5c100 @name="Janko"> p2 = Person.new('Janko') #=> #<Person:0x00000001b556e8 @name="Janko"> family = [] family << p1 family << p2 family.uniq #=> [#<Person:0x00000001b5c100 @name="Janko">]
  • 13. Základné koncepty inheritance (dedenie) method overloading (preťažovanie metód) method overriding (prekonávanie metód)
  • 14. Dedenie class Instrument def tune ... end end class Violin < Instrument def play tune "Taa daa" end end
  • 15. Overloading v ruby nefunguje class Instrument def play "Ta da" end def play(octave) "Ta da #{octave}" end end i = Instrument.new i.play #=> ArgumentError: wrong number of arguments (0 for 1) i.play('c dur') #=> "Ta da c dur"
  • 16. Overriding class Instrument def play "Ta da" end end class Violin < Instrument def play "Tiii diii tiii" end end v = Violin.new v.play #=> "Tiii diii tiii"
  • 17. Polymorfia class Instrument def play end end class Violin < Instrument def play "Taa daa" end end class Drum < Instrument def play "Dum dum" end end orchestra = [Violin.new, Violin.new, Drum.new] orchestra.each { |i| i.play } #=> "Taa daa", "Taa daa", "Dum dum"
  • 18. Všetko v Ruby je Objekt
  • 19. Aj nil Object.class #=> Class nil.class #=> NilClass
  • 20. ActiveSupport try p = Person.find(params[:id]) p.address.downcase #=> NoMethodError: undefined method `downcase' # for nil:NilClass p.address.try :downcase #=> nil
  • 21. Aj metóda class Person def greet(other_person) "Ahoj #{other_person}" end end m = Person.instance_method(:greet) m.class #=> UnboundMethod m.arity #=> 1 m.name #=> :greet m.parameters #=> [[:req, :other_person]]
  • 22. Aj trieda Class.class #=> Class .. o metaprogramovaní inokedy
  • 24. Modul ako namespace module Rubyslava class OOP end end module Pyvo class OOP end end Rubyslava::OOP == Pyvo::OOP #=> false
  • 25. Modul ako nositeľ kódu module Rubyslava def hello "Rubyslava" end end
  • 26. Mixiny class RubyslavaAPyvo include Rubyslava end rp = RubyslavaAPyvo.new rp.hello #=> "Rubyslava" class RubyslavaAPyvo extend Rubyslava end RubyslavaAPyvo.hello #=> "Rubyslava"
  • 27. Viacnásobné dedenie class RubyslavaAPyvo < Array include Rubyslava, Pyvo end RubyslavaAPyvo.ancestors #=> [RubyslavaAPyvo, Rubyslava, Pyvo # Array, Object, Kernel, BasicObject]
  • 28. Viditeľnosť v moduloch moduly zdieľajú všetko inštančné premenné (@) metódy
  • 29. module AdditionalBehaviour def show greet end end class Test include AdditionalBehaviour def greet "hello" end end Test.new.show #=> "hello"
  • 30. module GreetingBehavior def greet "hello" end end module RelyOnGreetingBehavior def show greet end end class Test include GreetingBehavior, RelyOnGreetingBehavior end Test.new.show #=> "hello"
  • 31. Zo života Enumerable acts_as_.. ActiveSupport::Concern
  • 32. class Tree include Enumerable def each(&block) leafs.each do { |n| yield n } end end t = Tree.new t.map t.inject t.sum ...
  • 33. class Post acts_as_taggable end p = Post.find(1) p.tag_list #=> ["Ruby", "OOP"]
  • 34. ActiveSupport::Concern module Annotatable extend ActiveSupport::Concern included do has_many :notes, :as => :annotatable, :order => "created_at DESC" end def most_annotated joins(:notes).group(:id).order("COUNT(*) DESC").first end end class Project < ActiveRecord::Base include Annotatable, Importable, Versionable end
  • 36. Ruby idiómy bloky a, b = b,a a, b, c = array (cachovanie) @var ||= ..
  • 37. Bloky transaction do |transaction| transaction.rollback if error? end Dir.chdir('/') do end with_disabled_keys do end with_nested_loop_plan do end
  • 38. Vzory Všeobecné riešenie často sa opakujúceho problému. Nie je to knižnica, ani kód, skôr šablóna.
  • 39. "When I see patterns in my programs, I consider it a sign of trouble." (Paul Graham)
  • 40. Vzory, ktoré v Ruby netreba programovať
  • 41. Singleton Problém: Zabezpečiť jednotný prístup k zdrojom (napr. databáza) Zlo, česť výnimkám (ActiveSupport::Inflections)
  • 42. Singleton class Logger def initialize @log = File.open("log.txt", "a") end @@instance = Logger.new def self.instance @@instance end def log(msg) @log.puts(msg) end private_class_method :new end Logger.instance.log('message 1')
  • 43. Singleton (lepšie) require 'singleton' class Logger include Singleton def initialize @log = File.open("log.txt", "a") end def log(msg) @log.puts(msg) end end Logger.instance.log('message 2')
  • 44. Iterator Problém: Umožniť manipuláciu s kompozitným objektom bez odhalenia jeho internej štruktúry
  • 45. Iterator class Tree include Enumerable def each(&block) leafs.each { |e| yield e } end end
  • 46. Decorator Problém: pridávanie funkcionality do triedy počas behu programu Dekorátor obalí pôvodnú triedu a kde treba rozšíri správanie
  • 47. class StringDecorator < String def starts_with? substr # ... end end title = StringDecorator.new("Rubyslava")
  • 48. Decorator = open classes class String def starts_with? substr # ... end end "aye aye captain".starts_with? "pirate" #=> false
  • 50. Delegator include 'forwardable' class Car extend Forwardable def_delegators :@car_computer, :velocity, :distance def initialize @car_computer = CarComputer.new end end c = Car.new c.velocity c.distance
  • 51. Proxy Problém: Skrytie implementačných detailov načítavania zdroja
  • 52. Proxy require 'delegate' class Future < SimpleDelegator def initialize(&block) @_thread = Thread.start(&block) end def __getobj__ __setobj__(@_thread.value) if @_thread.alive? super end end google = Future.new do Net::HTTP.get_response(URI('http://www.google.com')).body end yahoo = Future.new do Net::HTTP.get_response(URI('http://www.yahoo.com')).body end puts google puts yahoo
  • 54. Template method Problém: Často sa opakujúci boilerplate kód. Kostra programu, algoritmu.
  • 55. class Game def play prepare_board initialize_score while not end_of_game? make_move end end end class Carcassonne < Game def make_move tile = tiles.pick_random ... end end class Agricola < Game def make_move peasant = select_peasant ... end end
  • 56. Composite Problém: V stromových štruktúrach zamaskovať implementačný detail: uzly a listy.
  • 57. class Person def say "#{@name}" end end class Family attr_accessor :members def initialize(members) @members = members end def say @members.each { |m| m.say } end end f = Family.new(Person.new('Janko'), Person.new('Tomas')) t = Family.new(Person.new('Ferko'), f) t.say #=> "Ferko", "Janko", "Tomas"
  • 58. Strategy Problém: Výber vhodného algoritmu za behu programu
  • 59. class FileLogger < Logger def log(message) File.open('a') { |f| f << message } end end class DatabaseLogger < Logger def log(message) Log.create(:message => message) end end
  • 60. State Problém: Zmena správania objektu v rôznych stavoch
  • 61. class TrafficLight include AlterEgo state :proceed, :default => true do handle :color do "green" end transition :to => :caution, :on => :cycle! end state :caution do handle :color do "yellow" end transition :to => :stop, :on => :cycle! end state :stop do handle :color do "red" end transition :to => :proceed, :on => :cycle! end end
  • 62. light = TrafficLight.new light.color # => "green" light.cycle! light.color # => "yellow" light.cycle! light.color # => "red" light.cycle! light.color # => "green"
  • 63. Observer Problém: Oddelenie core funkcionality a špecifického správania v určitých stavoch objektu.
  • 64. class Comment < ActiveRecord::Base end class CommentObserver < ActiveRecord::Observer def after_save(comment) Notifications.deliver_comment("admin@do.com", "New comment was posted", comment) end end
  • 65. Zápachy v kóde (Bad smells)
  • 66. Vytváranie vlastného typového systému is_a?, kind_of? lepšie je respond_to?
  • 67. class Container def add(node) if node.kind_of? Array node.each { |n| @nodes << n } else @nodes << node end end end container.add(Tree.new('a', 'b')) #=> ???
  • 68. class Container def add(node) unless node.respond_to? :each node = [node] end node.each { |n| @nodes << n } end end container.add(Tree.new('a', 'b')) #=> ['a', 'b']
  • 69. Protipríklad ActiveRecord::sanitize_sql_for_assignment def sanitize_sql_for_assignment(assignments) case assignments when Array sanitize_sql_array(assignments) when Hash sanitize_sql_hash_for_assignment(assignments) else assignments end end
  • 70. Visitor + typy def visit object method = "visit_#{object.class.name}" send method, object end module Arel module Visitors class WhereSql < Arel::Visitors::ToSql def visit_Arel_Nodes_SelectCore o "WHERE #{o.wheres.map { |x| visit x }.join ' AND ' }" end end end end
  • 71. Shotgun surgery ak niečo mením tak musím na viacerých miestach crosscutting concerns AOP (AspectJ)
  • 72. AspectJ pointcut writableHeaderMethods() : execution(* (WritableRequestHeader|| WritableResponseHeader) .*(..)); before(HeaderWrapper header) : writableHeaderMethods() && this(header) { ... }
  • 74. Caching class DocumentController < ApplicationController caches_page :show caches_action :index def show; end def index; end end
  • 75. Autorizácia class DocumentController < ApplicationController before_filter :find_document def show # render @document end private def find_document @document = Document.find_by_id(params[:id]) end end
  • 76. class DocumentController < ApplicationController before_filter :find_document around_filer :authorize def show # render @document end private def find_document @document = Document.find_by_id(params[:id]) end def authorize if current_user.can_view?(@document) yield else render :not_authorized end end end
  • 77. Ťažko testovateľná trieda skúsiť si najprv napísať test rcov
  • 78. Duplicitný kód reek metric_fu rubymine refaktoring vzor Template
  • 79. Často sa meniaci kód churn
  • 81. Dlhý zoznam parametrov *args nahradenie objektom fluent interfaces
  • 82. def params(*args) puts args.class puts args.inspect end params('a', {:hello => 2}, 42) #=> Array #=> ["a", {:hello=>2}, 2]
  • 83. activerecord 2.x vs activerecord 3.x Visit.first(:select => "happened_at", :order => "happened_at ASC").happened_at Visit.select(:happened_at) .order("happened_at ASC").first.happened_at
  • 84. Primitívna obsesia class Debt < ActiveRecord::Base composed_of :debit, :class_name => "Money", :allow_nil => true, :mapping => [%w(debit_amount amount), %w(debit_currency currency)] end debt.debit # => Money
  • 85. switch/case Template polymorfia <% subject.infos.each do |info| %> <%= render :partial => "#{info.class.to_s}_detail", :subject => subject %> <% end %>
  • 87. Dátová trieda class SubjectController < ApplicationController def show if @subject.updated_at < Time.now - 2.weeks.ago @subject.refresh end end end class Subject < ActiveRecord::Base end
  • 88. Dátová trieda 2 class SubjectController < ApplicationController def show @subject.update_if_stale end end class Subject < ActiveRecord::Base def update_if_stale refresh if updated_at < Time.now - 2.weeks.ago end end class Person < Subject def update_if_stale # update vsetky firmy kde je subjekt end end
  • 89. Komentáre # download new version of article def perform(x) # load article from the url 'x' ... end def download_article(url) ... end
  • 91. Single responsibility principle Objekt by mal mať iba jednu zodpovednosť observers cache sweepers moduly (include, extend)
  • 92. Open/closed principle Triedy by mali byť otvorené pre rozširovanie, ale uzavreté pre modifikáciu v ruby tomu ťažko zabrániť
  • 93. Liskov substitution principle Každý nadtyp by mal byť nahraditeľný podtypom kruh/kružnica čo s polomerom?
  • 94. Interface segregation principle Hierarchia v rámci rozhraní - radšej viac špecifických rozhraní ako jedno obrovské v ruby nemá zmysel
  • 95. Dependency inversion principle Závislosť musí byť na rozhraní, nie na konkrétnej implementácii dependency injection
  • 96. Domain driven design ambiguous language Array#first, Array#second, Array#forty_two
  • 97. class Subject < ActiveRecord::Base has_many :debts def is_suspicious? debts.any? or in_liquidation? end end
  • 98. Záver With great power comes great responsibility (Spidermanov otec)