How to separate good code from legacy / quirks-mode code

Given some library that implements some widespread protocol or something similar (for example, FTP), how will I store my standard compatible code separately from the code that is necessary only to be able to cooperate with non-standard standards?

A good example where this will make sense too IMHO - these are libraries like jQuery, which should take into account all these features of the browser. Projects that must be compatible with previous versions are also likely to be a good target audience for such methods.

I am particularly interested in ruby ​​solutions, but language independent templates or good examples from other languages ​​are also welcome.

I already found the question here on stackoverflow, but are there any other approaches?

+5
source share
1 answer
  • Define different implementations for different modes (this does not allow you to mix “good” code with code that just needs to support backward compatibility). Ideally, an inherited layer is just a wrapper around standard code.
  • Determine to what extent the underlying system (browser, remote server, ...) complies with the standards. How this is done in detail, obviously, is highly dependent on the specific case.
  • Choose the correct implementation for your particular system and transparently connect it.
  • Give the user the opportunity to check what mode we are in, and forced mode.

Small Ruby Example:

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"
+3

All Articles