2012-02-13 11 views
5

Biorąc pod uwagę bibliotekę, która implementuje jakiś rozpowszechniony protokół lub coś podobnego (na przykład FTP), w jaki sposób zachowałbym mój standardowy kod zgodny z kodem, który jest potrzebny tylko do tego, aby był w stanie współpracować z nie tak standardowymi, zgodnymi systemami?Jak oddzielić dobry kod od starego/dziwnego kodu trybu

Dobrym przykładem, w którym to byłoby zbyt sensowne, IMHO to biblioteki takie jak jQuery, które muszą uwzględniać wszystkie te osobliwości przeglądarki. Projekty, które muszą zachować zgodność ze starszymi wersjami, prawdopodobnie byłyby również dobrym odbiorcą dla takich technik.

Jestem szczególnie zainteresowany rozwiązaniami ruby, ale mile widziane są również wzorce niezależne od języka lub dobre przykłady z innych języków.

Już znalazłem related question tutaj na stackoverflow, ale czy są jakieś inne podejścia?

Odpowiedz

3
  1. Definiowanie różnych implementacji dla różnych trybów (to zapobiega konieczności mieszania "dobrego" kodu z kodem, który jest po to, aby zachować kompatybilność wsteczną). Najlepiej, jeśli starsza warstwa jest tylko opakowaniem wokół kodu zgodnego ze standardami.
  2. Wykryto, w jakim stopniu podstawowy system (przeglądarka, zdalny serwer, ...) jest zgodny ze standardami. Sposób, w jaki odbywa się to w sposób szczegółowy, jest oczywiście wysoce zależny od konkretnego przypadku.
  3. Wybierz odpowiednią implementację dla konkretnego systemu i przezroczyście podłącz ją.
  4. Daj użytkownikowi szansę sprawdzenia, w którym jesteśmy trybie i wymuszenia określonego trybu.

Small Ruby przykład:

class GoodServer 
    def calculate(expr) 
    return eval(expr).to_s 
    end 
end 

class QuirkyServer 
    def calculate(expr) 
    # quirky server prefixes the result with "result: " 
    return "result: %s" % eval(expr) 
    end 
end 

module GoodClient 
    def calculate(expr) 
    @server.calculate(expr) 
    end 
end 

# compatibility layer 
module QuirkyClient 
    include GoodClient 
    def calculate(expr) 
    super(expr).gsub(/^result: /, '') 
    end 
end 

class Client 
    def initialize(server) 
    @server = server 
    # figure out if the server is quirky and mix in the matching module 
    if @server.calculate("1").include?("result") 
     extend QuirkyClient 
    else 
     extend GoodClient 
    end 
    end 
end 

good_server = GoodServer.new 
bad_server = QuirkyServer.new 

# we can access both servers using the same interface 
client1 = Client.new(good_server) 
client2 = Client.new(bad_server) 

p client1.is_a? QuirkyClient # => false 
p client1.calculate("1 + 2") # => "3" 

p client2.is_a? QuirkyClient # => true 
p client2.calculate("1 + 2") # => "3" 
+0

Ponownie, odpowiedź bardzo rozbudowane i kompleksowe. Wielkie dzięki. – raphinesse

Powiązane problemy