在OOP中打开/关闭主体?

时间:2012-04-20 13:50:51

标签: ruby

经常听说Open / Closed主体说一个类应该是Open for extension而Closed是为了修改。 听起来很抽象。

但在Ruby OOP领域是否有任何实际使用的示例?

2 个答案:

答案 0 :(得分:5)

Ruby类都是开放的。没有封闭的课程。

示例:

class String
  def foo
    puts "bar"
  end
end

'anything'.foo

#bar

答案 1 :(得分:2)

开放/封闭原则确实适用于Ruby。

定义说..你的类/对象应该是开放的扩展,但是关闭以进行修改。这是什么意思?

这意味着您不应该去修改类以添加新行为。你应该使用继承或组合来实现它。

E.g。

class Modem
  HAYES = 1
  COURRIER = 2
  ERNIE = 3
end


class Hayes
  attr_reader :modem_type

  def initialize
    @modem_type = Modem::HAYES
  end
end

class Courrier
  attr_reader :modem_type

  def initialize
    @modem_type = Modem::COURRIER
  end
end

class Ernie
  attr_reader :modem_type

  def initialize
    @modem_type = Modem::ERNIE
  end
end



class ModemLogOn

  def log_on(modem, phone_number, username, password)
    if (modem.modem_type == Modem::HAYES)
      dial_hayes(modem, phone_number, username, password)
    elsif (modem.modem_type == Modem::COURRIER)
      dial_courrier(modem, phone_number, username, password)
    elsif (modem.modem_type == Modem::ERNIE)
      dial_ernie(modem, phone_number, username, password)
    end
  end

  def dial_hayes(modem, phone_number, username, password)
    puts modem.modem_type
    # implmentation
  end


  def dial_courrier(modem, phone_number, username, password)
    puts modem.modem_type
    # implmentation
  end

  def dial_ernie(modem, phone_number, username, password)
    puts modem.modem_type
    # implementation
  end
end

要支持新型调制解调器,你必须去修改这个类。

使用继承。你可以抽象出调制解调器功能。并且

# Abstration
class Modem

  def dial
  end

  def send
  end

  def receive
  end

  def hangup
  end

end

class Hayes < Modem
  # Implements methods
end


class Courrier < Modem
  # Implements methods
end

class Ernie < Modem
  # Implements methods
end


class ModelLogON

  def log_on(modem, phone_number, username, password)
    modem.dial(phone_number, username, password)
  end

end

现在支持新型调制解调器..您不必去修改源代码。您可以添加新代码以添加新类型的调制解调器。

这是使用继承实现开放/封闭原则的方式。使用许多其他技术可以实现该原理。