Как это 6 может выровнять метод быть пересмотренным, чтобы быть более читаемым?

В контексте библиотек кода привязка является библиотеками-оболочками, которые образуют мост между двумя языками программирования так, чтобы библиотекой, которая была записана для одного языка, можно было также неявно пользоваться на другом языке.

, Например, libsvn является API для Подрывной деятельности и был записан в C. Если Вы хотите получить доступ к Подрывной деятельности из кода Java, можно использовать libsvn-java. libsvn-java зависит от libsvn быть установленным, потому что libsvn-java является простым мостом между языком программирования Java и libsvn, обеспечивая API, который просто вызывает функции libsvn, чтобы сделать реальную работу.

5
задан Dafydd Rees 23 November 2009 в 11:39
поделиться

4 ответа

Может быть, что-то вроде этого?

def has_just_one_kind_of_thing?(item, controller)
    return case controller
      when 'foos', 'bars'
        item.widgets.blank? || item.doohickeys.blank?
      when 'bazes'
        item.widgets.blank? || item.contraptions.blank?
      else 
        false
    end
  end

Внешний возврат может и не понадобиться (не совсем уверен, что требует Ruby, я все еще новичок в этом), но я предпочитаю уйти это так, что намерение очевидно.

10
ответ дан 18 December 2019 в 05:43
поделиться

Во-первых, Ruby всегда по умолчанию возвращает значение последнего оператора, поэтому мы можем избавиться от if / else:

def has_just_one_kind_of_thing?(item, controller)
    (controller == 'foos' && item.widgets.blank?) || (controller == 'foos' && item.doohickeys.blank?) || (controller == 'bars' && item.widgets.blank?) || (controller == 'bars' && item.doohickeys.blank?) || (controller == 'bazes' && item.widgets.blank?) || (controller == 'bazes' && item.contraptions.blank?)
end

Теперь давайте переформатируем для удобства чтения.

def has_just_one_kind_of_thing?(item, controller)
  (controller == 'foos' && item.widgets.blank?)    || 
  (controller == 'foos' && item.doohickeys.blank?) || 
  (controller == 'bars' && item.widgets.blank?)    || 
  (controller == 'bars' && item.doohickeys.blank?) || 
  (controller == 'bazes' && item.widgets.blank?)   || 
  (controller == 'bazes' && item.contraptions.blank?)
end

Вот, теперь в алгоритме намного легче увидеть закономерности. Похоже, здесь задаются два вопроса: является ли контроллер одним из [foos | bars | bazes] и являются ли виджеты или doohickeys пустыми. Давайте вынесем за скобки первый вопрос:

def has_just_one_kind_of_thing?(item, controller)
  %w[foos bars bazes].include?(controller)  &&
    (item.widgets.blank? || item.doohickeys.blank?)
end

Это уменьшает размер метода до управляемого размера. Но из имени метода я делаю вывод, что вы ищете случай, когда у widgets или doohickeys есть элементы, но не то и другое, и ни то, ни другое. Если это так, XOR может быть более подходящим:

def has_just_one_kind_of_thing?(item, controller)
  %w[foos bars bazes].include?(controller)  &&
    (item.widgets.blank? ^ item.doohickeys.blank?)
end
4
ответ дан 18 December 2019 в 05:43
поделиться

Ребята - похоже, здесь есть потребность в полиморфизме, который просто не может быть решен путем возни с управлением потоком в одном методе.

Вот моя попытка, начиная с расширенной версии:

def has_just_one_kind_of_thing?(item, controller)
  (controller == 'foos' && item.widgets.blank?)    || 
  (controller == 'foos' && item.doohickeys.blank?) || 
  (controller == 'bars' && item.widgets.blank?)    || 
  (controller == 'bars' && item.doohickeys.blank?) || 
  (controller == 'bazes' && item.widgets.blank?)   || 
  (controller == 'bazes' && item.contraptions.blank?)
end

Итак, существует три различных поведения - по одному на контроллер .... Если бы каждый контроллер был достаточно умен, чтобы принимать решения, зависящие от контроллера, и вы передаете фактическому контроллеру не просто имя Контроллер, вы сокращаете метод до следующего:

def has_just_one_kind_of_thing?(item, controller)
  controller.has_just_one_kind_of_thing?(item)
end

Это требует, чтобы каждый контроллер выполнял соответствующую обработку элементов для того типа контроллера, которым он является. Итак, давайте определим метод для каждого из foos, bars и bazes с именем has_just_one_kind_of_thing?

Пример для foos:

def has_just_one_kind_of_thing?(item)
   item.widgets.blank? || item.doohickeys.blank?
end

Пример для bazes:

def has_just_one_kind_of_thing?(item)
   item.widgets.blank? || item.contraptions.blank?
end

На каждом контроллере, который вы хотите вернуть false , просто примените " pattern:

def has_just_one_kind_of_thing?(item)
  false
end

Этот код будет работать даже быстрее, потому что теперь нам не нужно выполнять столько проверок, сколько существует типов контроллеров - мы просто отправляем один метод для контроллера.

Итак, он быстрее в интерпретируемом рубине - и он может даже работать намного быстрее в jruby или одном из других рубинов, которые могут значительно оптимизировать диспетчеризацию методов ...

Возможно, мы могли бы сделать его еще умнее, но мне нужно знать, в каком классе находится этот метод, и, возможно, еще кое-что о item .

Альтернативный рефакторинг заключался бы в том, чтобы сделать элемент умным и иметь разные методы для каждого типа элемента . Опять же, нам нужно больше узнать об объектной модели, чтобы определить, какая из них лучше ...

Тем не менее, это первый вариант.

pattern:

def has_just_one_kind_of_thing?(item)
  false
end

Этот код будет работать даже быстрее, потому что теперь нам не нужно выполнять столько проверок, сколько существует типов контроллеров - мы просто отправляем один метод для контроллера.

Итак он быстрее в интерпретируемом рубине - и он может даже работать намного быстрее в jruby или одном из других рубинов, которые могут значительно оптимизировать диспетчеризацию методов ...

Возможно, мы могли бы сделать его еще умнее, но мне нужно знать, в каком классе находится этот метод, и, возможно, еще кое-что о item .

Альтернативный рефакторинг заключался бы в том, чтобы сделать элемент умным и иметь разные методы для каждого типа элемента . Опять же, нам нужно больше узнать об объектной модели, чтобы определить, какая из них лучше ...

Тем не менее, это первый вариант.

def has_just_one_kind_of_thing?(item)
  false
end

Этот код будет работать даже быстрее, потому что теперь нам не нужно выполнять столько проверок, сколько существует типов контроллеров - мы просто выполняем диспетчеризацию одного метода для контроллера.

Итак, он быстрее в интерпретируемом рубине - и он может даже работать намного быстрее в jruby или одном из других рубинов, которые могут значительно оптимизировать диспетчеризацию методов ...

Возможно, мы могли бы сделать его еще умнее, но мне нужно знать, в каком классе находится этот метод, и, возможно, еще кое-что о item .

Альтернативный рефакторинг заключался бы в том, чтобы сделать элемент умным и иметь разные методы для каждого типа элемента . Опять же, нам нужно больше узнать об объектной модели, чтобы определить, какая из них лучше ...

Тем не менее, это первый вариант.

def has_just_one_kind_of_thing?(item)
  false
end

Этот код будет работать даже быстрее, потому что теперь нам не нужно выполнять столько проверок, сколько существует типов контроллеров - мы просто выполняем диспетчеризацию одного метода для контроллера.

Итак он быстрее в интерпретируемом рубине - и он может даже работать намного быстрее в jruby или одном из других рубинов, которые могут значительно оптимизировать диспетчеризацию методов ...

Возможно, мы могли бы сделать его еще умнее, но мне нужно знать, в каком классе находится этот метод, и, возможно, еще кое-что о item .

Альтернативный рефакторинг заключался бы в том, чтобы сделать элемент умным и иметь разные методы для каждого типа элемента . Опять же, нам нужно больше узнать об объектной модели, чтобы определить, какая из них лучше ...

Тем не менее, это первый вариант.

нам не нужно выполнять столько проверок, сколько существует типов контроллеров - мы просто отправляем один метод для контроллера.

Итак он быстрее в интерпретируемом рубине - и он может даже работать намного быстрее в jruby или одном из других рубинов, которые могут значительно оптимизировать диспетчеризацию методов ...

Возможно, мы могли бы сделать его еще умнее, но мне нужно знать, в каком классе находится этот метод, и, возможно, еще кое-что о item .

Альтернативный рефакторинг заключался бы в том, чтобы сделать элемент умным и иметь разные методы для каждого типа элемента . Опять же, нам нужно больше узнать об объектной модели, чтобы определить, какая из них лучше ...

Тем не менее, это первый вариант.

нам не нужно выполнять столько проверок, сколько существует типов контроллеров - мы просто отправляем один метод для контроллера.

Итак он быстрее в интерпретируемом рубине - и он может даже работать намного быстрее в jruby или одном из других рубинов, которые могут значительно оптимизировать диспетчеризацию методов ...

Возможно, мы могли бы сделать его еще умнее, но мне нужно знать, в каком классе находится этот метод, и, возможно, еще кое-что о item .

Альтернативный рефакторинг заключался бы в том, чтобы сделать элемент умным и иметь разные методы для каждого типа элемента . Опять же, нам нужно больше узнать об объектной модели, чтобы определить, какая из них лучше ...

Тем не менее, это первый вариант.

Необходимо выполнить столько проверок, сколько существует типов контроллеров - мы просто выполняем диспетчеризацию одного метода для контроллера.

Итак, он быстрее в интерпретируемом рубине - и он может даже работать намного быстрее в jruby или одном из других рубинов, которые могут значительно оптимизировать диспетчеризацию методов ...

Возможно, мы могли бы сделать его еще умнее, но мне нужно знать, в каком классе находится этот метод, и, возможно, еще кое-что о item .

Альтернативный рефакторинг заключался бы в том, чтобы сделать элемент умным и иметь разные методы для каждого типа элемента . Опять же, нам нужно больше узнать об объектной модели, чтобы определить, какая из них лучше ...

Тем не менее, это первый вариант.

Необходимо выполнить столько проверок, сколько существует типов контроллеров - мы просто выполняем диспетчеризацию одного метода для контроллера.

Итак он быстрее в интерпретируемом рубине - и он может даже работать намного быстрее в jruby или одном из других рубинов, которые могут значительно оптимизировать диспетчеризацию методов ...

Возможно, мы могли бы сделать его еще умнее, но мне нужно знать, в каком классе находится этот метод, и, возможно, еще кое-что о item .

Альтернативный рефакторинг заключался бы в том, чтобы сделать элемент умным и иметь разные методы для каждого типа элемента . Опять же, нам нужно больше узнать об объектной модели, чтобы определить, какая из них лучше ...

Тем не менее, это первый вариант.

работает быстрее в интерпретируемом рубине - и он может даже работать намного быстрее в jruby или одном из других рубинов, которые могут сильно оптимизировать диспетчеризацию методов ...

Мы, вероятно, могли бы сделать его еще умнее но мне нужно знать, в каком классе живет этот метод, и, возможно, еще кое-что о item .

Альтернативный рефакторинг заключался бы в том, чтобы сделать элемент умным и иметь разные методы для каждого типа элемента . Опять же, нам нужно больше узнать об объектной модели, чтобы определить, какая из них лучше ...

Тем не менее, это первый вариант.

работает быстрее в интерпретируемом рубине - и он может даже работать намного быстрее в jruby или одном из других рубинов, которые могут сильно оптимизировать диспетчеризацию методов ...

Мы, вероятно, могли бы сделать его еще умнее но мне нужно знать, в каком классе живет этот метод, и, возможно, еще кое-что о item .

Альтернативный рефакторинг заключался бы в том, чтобы сделать элемент умным и иметь разные методы для каждого типа элемента . Опять же, нам нужно больше узнать об объектной модели, чтобы определить, какая из них лучше ...

Тем не менее, это первый вариант.

d нужно знать, в каком классе живет этот метод, и, возможно, еще кое-что о элементе .

Альтернативный рефакторинг заключался бы в том, чтобы сделать элемент умным и иметь разные методы для каждого типа элемента . Опять же, нам нужно больше узнать об объектной модели, чтобы определить, какая из них лучше ...

Тем не менее, это первый вариант.

d нужно знать, в каком классе живет этот метод, и, возможно, еще кое-что о элементе .

Альтернативный рефакторинг заключался бы в том, чтобы сделать элемент умным и иметь разные методы для каждого типа элемента . Опять же, нам нужно больше узнать об объектной модели, чтобы определить, какая из них лучше ...

Тем не менее, это первый вариант.

13
ответ дан 18 December 2019 в 05:43
поделиться

Теорема де Моргана о булевой логике имеет два утверждения.

1. (A и B) эквивалентно not (notA или notB)

not (A и B) эквивалентно (notA или notB)

2. (A или B) эквивалентно не (notA и notB)

not (A или B) эквивалентно (notA и notB)

..

  1. покупайте бутерброд, если он (менее 2 долларов и он лосось) = не покупайте бутерброд, если он есть (не меньше 2 долларов или не лосось).

  2. смотрите телевизор, если (V включен или аватар включен) = не смотреть телевизор, если (V выключен, а Аватар выключен).

Дополнительная логическая алгебра, среди прочего,

  1. (A и B) или (A и C) = A и (B или C)

  2. (A или B) или C = A, B или C


Исходная логика:

  (controller == 'foos' && item.widgets.blank?)    || 
  (controller == 'foos' && item.doohickeys.blank?) || 

  (controller == 'bars' && item.widgets.blank?)    || 
  (controller == 'bars' && item.doohickeys.blank?) || 

  (controller == 'bazes' && item.widgets.blank?)   || 
  (controller == 'bazes' && item.contraptions.blank?)


Сокращение
(foos and widgets) или (foos and hickeys) = foos and (widgets or hickeys):

  (
    (controller == 'foos' &&
      (item.widgets.blank? || item.doohickeys.blank?)
    ) || 

    (controller == 'bars' &&
      (item.widgets.blank? || item.doohickeys.blank?)
    ) || 

    (controller == 'bazes' &&
      (item.widgets.blank? || item.contraptions.blank?)
    )
  )


Сокращение
(foos and items) или (bars and items) = (foos or bars) and items:

  (
    (controller == 'foos' || controller == 'bars') &&
    (item.widgets.blank? || item.doohickeys.blank?)
  ) ||

  (controller == 'bazes' &&
    (item.widgets.blank? || item.contraptions.blank?)
  )


Логическое сокращение уменьшилось до 3,5 строк с исходных 6 строк. Несмотря на то, что в этом упражнении не использовались простые логические алгебраические манипуляции де Моргана, метод де Моргана часто применяется в других ситуациях.

Вы можете сказать, почему я должен испытывать такие проблемы каждый раз, когда мы пишем кучу логических утверждений ? Сокращенная логика не имеет никакого сходства с оригиналом, и это не лучший самодокументирующийся код.

Точно! Сокращенная логика позволяет вам увидеть это в более простых терминах, а оригинал не имеет никакого сходства с более простой логикой, которая должна была быть у вас с самого начала.

3
ответ дан 18 December 2019 в 05:43
поделиться
Другие вопросы по тегам:

Похожие вопросы: