2012-02-13 26 views
5

Data una libreria che implementa qualche protocollo diffuso o qualcosa di simile (ad esempio FTP), come manterrò il mio codice conforme standard separato dal codice che è necessario solo per essere in grado collaborare con sistemi non conformi allo standard?Come separare il buon codice dal codice in modalità legacy/quirks

Un bell'esempio in cui questo avrebbe senso anche IMHO sono librerie come jQuery che devono considerare tutte quelle peculiarità del browser. I progetti che devono mantenere la compatibilità legacy sarebbero probabilmente anche un buon target di riferimento per tali tecniche.

Sono particolarmente interessato alle soluzioni di rubino ma sono benvenuti anche modelli indipendenti dal linguaggio o buoni esempi da altre lingue.

Ho già trovato uno related question qui su StackOverflow, ma ci sono altri approcci?

risposta

3
  1. Definire diverse implementazioni per le diverse modalità (questo impedisce di dover combinare codice "buono" con codice che è solo lì per mantenere la compatibilità all'indietro). Idealmente, il livello legacy è solo un involucro attorno al codice conforme agli standard.
  2. Rileva in che misura il sistema sottostante (browser, server remoto, ...) è conforme agli standard. Il modo in cui ciò viene fatto in dettaglio dipende evidentemente dal caso specifico.
  3. Scegli l'implementazione corretta per il sistema specifico e collegalo in modo trasparente.
  4. Lascia all'utente la possibilità di verificare in quale modalità siamo e forzare una modalità specifica.

Piccolo Rubino esempio:

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

Anche in questo caso, una risposta molto elaborato e completo. Molte grazie. – raphinesse