2012-02-13 65 views
5

鉴于一些库实现了一些广泛的协议或类似的东西(比如FTP),我将如何保持我的标准兼容代码与只需要代码的代码分离与不那么标准的兼容系统合作?如何从传统/怪癖模式代码中分离出良好的代码

一个很好的例子,这也是有意义的恕我直言,像jQuery这样的图书馆必须考虑所有这些浏览器的特性。必须保持传统兼容性的项目可能也会成为此类技术的良好目标受众。

我对ruby解决方案特别感兴趣,但也欢迎语言独立模式或来自其他语言的良好示例。

我已经在stackoverflow上找到了related question这里,但还有其他的方法吗?

回答

3
  1. 为不同的模式定义不同的实现(这可以防止您必须将“良好”代码与恰好存在的代码混合以保持向后兼容性)。理想情况下,遗留层仅仅是符合标准的代码的一个包装。
  2. 检测底层系统(浏览器,远程服务器...)是否符合标准。这是如何详细完成的,显然高度依赖于具体情况。
  3. 为特定系统选择正确的实施方式并将其透明地插入。
  4. 给用户一个机会来检查我们是哪种模式并强制特定模式。

红宝石小例子:

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

同样,一个非常精细和全面的答复。非常感谢。 – raphinesse 2012-02-14 18:30:56