2012-04-20 3 views
2

オープン/クローズドプリンシパルについてよく聞きますが、クラスは拡張のためにオープンし、クローズは変更する必要があります。 抽象的なレベルで素晴らしいサウンドです。OOP Rubyのオープン/クローズドプリンシパル?

Ruby OOPの土地に実際のユースケースの例が適用されていますか?

答えて

5

Rubyクラスはすべて開いています。クローズドクラスはありません。

例:

class String 
    def foo 
    puts "bar" 
    end 
end 

'anything'.foo 

#bar 
+0

この原則はOOPの核となる定義ではなく、次のように定義されています。http://en.wikipedia.org/wiki/Open/closed_principle – texasbruce

+1

これは質問の内容とは異なります。オープン/クローズドの原則の中で「閉じた」とは、実行時に新しい機能を追加するためにクラスを「開く」ことができないということを意味するわけではありません(Rubyistsが通常「猿パッチ」と呼ぶもの)。 *クラスとAPIの設計*要件が変更された場合、クラスの既存の機能を変更する必要性が最小限に抑えられるようにする(完全に新しい機能を追加するのではなく)。 – GMA

2

開放/閉鎖原則は、Rubyにも適用されます。

定義は..あなたのクラス/オブジェクトは拡張のためにオープンされていなければならないが、変更のために閉じなければならない。どういう意味ですか?

これは、新しい動作を追加するためにクラスを変更してはいけないということです。継承や合成を使って達成する必要があります。

など。

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 

新しいタイプのモデムをサポートするために、ソースコードを変更する必要はありません。新しいコードを追加して、新しいタイプのモデムを追加することができます。

継承を使用してオープン/クローズの原理を実現する方法です。原則は他の多くの技術を用いて達成することができる。