2012-04-20 41 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 2012-04-20 17:44:11

+1

這不是問題的要求。在open/closed原則的背景下'關閉'並不意味着在運行時不能'打開'類來添加新的功能(Rubyists通常稱之爲'monkey-patching')。這意味着當*設計您的類和API *您應該嘗試這樣做,以便在需求發生變化時最大限度地減少需要更改類現有功能(而不是添加全新功能)的機會。 – GMA 2016-12-10 16:12:35

2

打開/封閉原則並不完全適用於紅寶石。

定義說..你的類/對象應該打開進行擴展,但關閉修改。這是什麼意思?

這意味着你不應該去修改類來添加新的行爲。您應該使用繼承或組合來實現。

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 

現在支持新型調制解調器..你不必去和修改源代碼。您可以添加新代碼以添加新類型的調制解調器。

這是如何使用繼承實現開放/關閉原則。這個原理可以用許多其他技術來實現。

相關問題