Как отделить хороший код от кода устаревшего режима - PullRequest
5 голосов
/ 13 февраля 2012

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

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

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

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

1 Ответ

3 голосов
/ 13 февраля 2012
  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"
...