2012-02-13 16 views
5

Dada una biblioteca que implementa algún protocolo generalizado o algo similar (por ejemplo, FTP), ¿cómo mantendría mi código compatible estándar separado del código que solo es necesario para poder para cooperar con sistemas que no cumplen con los estándares?Cómo separar un buen código del código heredado/de modo peculiar

Un buen ejemplo en el que esto tendría sentido también en mi humilde opinión son bibliotecas como jQuery que deben tener en cuenta todas las peculiaridades del navegador. Los proyectos que tienen que mantener compatibilidad heredada probablemente también sean un buen público objetivo para tales técnicas.

Estoy especialmente interesado en las soluciones de ruby, pero también se aceptan patrones independientes del idioma o buenos ejemplos de otros idiomas.

Ya encontré un related question aquí en stackoverflow, pero ¿hay algún otro enfoque?

Respuesta

3
  1. Define diferentes implementaciones para los diferentes modos (esto evita que tengas que mezclar el código "bueno" con el código que está ahí para mantener la compatibilidad con versiones anteriores). Idealmente, la capa heredada es solo una envoltura alrededor del código que cumple con los estándares.
  2. Detecta en qué medida el sistema subyacente (navegador, servidor remoto, ...) cumple con los estándares. Cómo se hace esto en detalle es obviamente muy dependiente del caso específico.
  3. Elija la implementación correcta para el sistema en particular y conéctelo de manera transparente.
  4. Ofrezca al usuario la posibilidad de comprobar en qué modo estamos y forzar un modo específico.

ejemplo Pequeño Ruby:

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

Una vez más, una respuesta muy elaborada y completa. Muchas gracias. – raphinesse

Cuestiones relacionadas