Дизайн OO в направляющих: Куда поместить материал

В дополнение к уже приведенным ответам, вот версия, которая сначала проверяет, существует ли новая ветвь (так что вы можете безопасно использовать ее в скрипте)

if git ls-remote --heads "$remote" \
    | cut -f2 \
    | sed 's:refs/heads/::' \
    | grep -q ^"$newname"$; then
    echo "Error: $newname already exists"
    exit 1
fi
git push "$oldname" "$remote/$oldname:refs/heads/$newname" ":$oldname"

(проверка взята из этот ответ )

242
задан Dan Rosenstark 4 March 2010 в 14:20
поделиться

3 ответа

Поскольку Rails предоставляет структуру с точки зрения MVC, естественно в конечном итоге использовать только предоставленные вам модели, представления и контейнеры контроллера. Типичная идиома для новичков (и даже некоторых программистов среднего уровня) - втиснуть всю логику в приложении в модель (класс базы данных), контроллер или представление.

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

Тонкие контроллеры, на самом деле, хорошая идея, но следствие - помещать все в модель - на самом деле не лучший план.

В Ruby , у вас есть несколько хороших способов сделать вещи более модульными. Довольно популярный ответ - просто использовать модули (обычно хранящиеся в lib ), которые содержат группы методов, а затем включать модули в соответствующие классы. Это помогает в тех случаях, когда у вас есть категории функциональных возможностей, которые вы хотите повторно использовать в нескольких классах, но когда функциональность все еще условно привязана к классам.

Помните, когда вы включаете модуль в класс, методы становятся методами экземпляра класса, так что вы все равно получите класс, содержащий тонну методов, они ' re просто красиво организован в несколько файлов.

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

Хороший способ подумать об этом - «принцип единой ответственности», который гласит, что класс должен нести ответственность за одну (или небольшое количество) вещей. Ваши модели отвечают за сохранение данных из вашего приложения в базе данных. Ваши контроллеры несут ответственность за получение запроса и возврат жизнеспособного ответа.

Если у вас есть концепции, которые не вписываются в эти рамки (настойчивость, управление запросами / ответами), вы, вероятно, захотите подумать о том, как вы моделирует рассматриваемую идею. Вы можете хранить немодельные классы в app / classes или где-нибудь еще, и добавьте этот каталог в свой путь загрузки, выполнив:

config.load_paths << File.join(Rails.root, "app", "classes")

Если вы используете пассажир или JRuby, вы, вероятно, также захотите добавить свой путь к путям нетерпеливой загрузки:

config.eager_load_paths << File.join(Rails.root, "app", "classes")

Суть в том, что как только вы доберетесь до момент в Rails, где вы задаете этот вопрос, пора усилить свои навыки Ruby и начать моделировать классы, которые не просто классы MVC, которые Rails предоставляет вам по умолчанию.

Обновление: Этот ответ относится к Rails 2.x и выше.

Это просто классы MVC, которые Rails предоставляет вам по умолчанию.

Обновление: Этот ответ относится к Rails 2.x и выше.

Это просто классы MVC, которые Rails предоставляет вам по умолчанию.

Обновление: Этот ответ относится к Rails 2.x и выше.

381
ответ дан 23 November 2019 в 03:12
поделиться

Update: The use of Concerns have been confirmed as the new default in Rails 4.

It really depends on the nature of the module itself. Я обычно помещаю расширения контроллера / модели в папку / issues в приложении.

# concerns/authentication.rb
module Authentication
  ...
end    

# controllers/application_controller.rb
class ApplicationController
  include Authentication
end



# concerns/configurable.rb
module Configurable
  ...
end    

class Model 
  include Indexable
end 

# controllers/foo_controller.rb
class FooController < ApplicationController
  include Indexable
end

# controllers/bar_controller.rb
class BarController < ApplicationController
  include Indexable
end

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

/lib/myapp.rb
module MyApp
  VERSION = ...
end

/lib/myapp/CacheKey.rb
/lib/myapp/somecustomlib.rb

Расширения ядра Ruby / Rails обычно используются в инициализаторах конфигурации, поэтому библиотеки загружаются только один раз в Rails boostrap.

/config/initializer/config.rb
/config/initializer/core_ext/string.rb
/config/initializer/core_ext/array.rb

Для повторно используемых фрагментов кода, Я часто создаю (микро) плагины, чтобы повторно использовать их в других проектах.

Вспомогательные файлы обычно содержат вспомогательные методы, а иногда и классы, когда объект предназначен для использования помощниками (например, построителями форм).

Это это действительно общий обзор. Пожалуйста, предоставьте более подробную информацию о конкретных примерах, если вы хотите получить более индивидуальные предложения. :)

62
ответ дан 23 November 2019 в 03:12
поделиться

... тенденция делать огромные Подклассы ActiveRecord и огромные контроллеры вполне естественно ...

"огромный" - это тревожное слово ...; -)

Как ваши контроллеры становятся огромными? Вот на что стоит обратить внимание: в идеале контроллеры должны быть тонкими. Выбирая эмпирическое правило из воздуха, я бы предположил, что если у вас регулярно есть более, скажем, 5 или 6 строк кода на метод (действие) контроллера, то ваши контроллеры, вероятно, слишком толстые. Есть ли дублирование, которое могло бы перейти во вспомогательную функцию или фильтр? Есть ли бизнес-логика, которую можно внедрить в модели?

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

РЕДАКТИРОВАТЬ: Попытка немного расширить, надеюсь, ничего не искажает слишком сильно ...

Помощники: находятся в app / helpers и в основном используются для упрощения просмотра. Они либо зависят от контроллера (также доступны для всех представлений для этого контроллера), либо общедоступны ( модуль ApplicationHelper в application_helper.rb).

Фильтры: скажем, у вас есть одна и та же строка кода в нескольких действия (довольно часто получение объекта с использованием params [: id] или аналогичных). Это дублирование можно сначала выделить в отдельный метод, а затем полностью исключить из действий, объявив фильтр в определении класса, например before_filter: get_object . См. Раздел 6 в Руководстве по Rails ActionController Пусть декларативное программирование станет вашим другом.

Рефакторинг моделей - это немного более религиозная вещь. Ученики дяди Боба предложат, например, следовать пяти заповедям SOLID . Джоэл и Джефф могут рекомендовать более, э-э, «прагматичный» подход, хотя впоследствии они действительно оказались немного более согласованными . Поиск одного или нескольких методов в классе, которые работают с четко определенным подмножеством его атрибутов, - это один из способов попытаться определить классы, которые могут быть реорганизованы из вашей модели, производной от ActiveRecord.

Кстати, модели Rails не обязательно должны быть подклассами ActiveRecord :: Base. Или, другими словами, модель не обязательно должна быть аналогом таблицы или вообще иметь отношение к чему-либо, хранящемуся в ней. Еще лучше, если вы называете свой файл в app / models в соответствии с Rails '

10
ответ дан 23 November 2019 в 03:12
поделиться
Другие вопросы по тегам:

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