Как отделить хороший код от устаревшего кода / кода режима причуд

Учитывая некоторую библиотеку, которая реализует какой-либо широко распространенный протокол или что-то подобное (например, FTP), как я могу сохранить свой стандартный совместимый код отдельно от кода, который необходим только для взаимодействия с несовместимыми со стандартами системами?

Хороший пример, когда это тоже имеет смысл. ИМХО, - это библиотеки вроде jQuery, которые должны учитывать все эти особенности браузера. Проекты, которые должны поддерживать совместимость с наследием, вероятно, также будут хорошей целевой аудиторией для таких методов.

Меня особенно интересуют решения на Ruby, но также приветствуются не зависящие от языка шаблоны или хорошие примеры из других языков.

Я уже нашел вопрос, связанный с здесь, в stackoverflow, но есть ли другие подходы?


person raphinesse    schedule 13.02.2012    source источник


Ответы (1)


  1. Определите разные реализации для разных режимов (это избавит вас от необходимости смешивать «хороший» код с кодом, который существует только для обеспечения обратной совместимости). В идеале унаследованный уровень является лишь оболочкой для кода, совместимого со стандартами.
  2. Определите, в какой степени базовая система (браузер, удаленный сервер и т. Д.) Соответствует стандартам. То, как это делается в деталях, очевидно, сильно зависит от конкретного случая.
  3. Выберите правильную реализацию для конкретной системы и прозрачно подключите ее.
  4. Дайте пользователю возможность проверить, в каком режиме мы находимся, и установить определенный режим.

Небольшой пример 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"
person Niklas B.    schedule 13.02.2012
comment
Опять же, очень подробный и исчерпывающий ответ. Большое спасибо. - person raphinesse; 14.02.2012