Грануляризация моделей?

Я разрабатываю CMS в основном на основе компонентов Zend Framework. Вот некоторые из таблиц базы данных для этой CMS:

site
| id | name |
-------------

locale
| languageCode | regionCode |
-----------------------------

site_locale // link sites with locales
| siteId | languageCode | regionCode | isActive | isDefault |
-------------------------------------------------------------

У меня есть модель с именем Site, которая состоит, среди прочего, из следующих методов:

getId()
getName()
listLocales() // list all locales for this site

Я как бы на грани того, насколько детализировано я должен определять модели:

Одним из вариантов может быть возвращение SiteLocale объектов/моделей (другими словами, представление таблицы БД) из listLocales() метода, где эти SiteLocale объекты содержат следующие методы:

getSite() // returns the Site model
getLocale() // returns a Zend_Locale
isActive() // is this locale active for the site this model represents?
isDefault() // is this the default locale for the site this model represents()

Другой вариант — просто создать следующие методы в модели Site и покончить с этим:

getDefaultLocale() // simply return the default site locale as Zend_Locale
listActiveLocales() // simply return all active site locales as Zend_Locales
listAllLocales() // simply return all site locales as Zend_Locales

Какой путь вы считаете правильным? И почему?

Кроме того, будет ли первый вариант (или, возможно, даже оба варианта) нарушать Закон Деметры?

EDIT (22 января)
Хотя мне нравится Джеффа ответ, я все еще открыт для новых/других перспектив.


person Decent Dabbler    schedule 18.01.2010    source источник


Ответы (1)


Во-первых, относительно таблиц базы данных: возможно, вы могли бы еще больше нормализовать базу данных. Между таблицами locale и site_locale есть дублирование. Конечно, я не вижу здесь общей картины, поэтому за тем, как вы это сделали, может быть что-то стоящее.

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

site_locales = site.listLocales()
foreach (site_locale in site_locales) {
    if site_locale.isDefault() {
        do_something(site_locale.getLocale())
    }
}

Если это так, то я бы избегал этого и выбрал второй вариант и в итоге получил:

do_something(site.getDefaultLocale())

Это гораздо понятнее при беглом взгляде. Возможно, это даже улучшит производительность вашего сайта.

Однако, если вы думаете, что в будущем вам предстоит много работать со списками SiteLocales, но вы точно не знаете, что собираетесь делать дальше getDefaultLocale(), listActiveLocales() и listAllLocales(), то, возможно, первое вариант может быть идеальным. Или вы могли бы даже использовать комбинацию из двух.

Что касается Закона Деметры, то он больше похож на Руководство Деметры. Можно нарушать любое правило, если вы делаете это сознательно, понимаете, почему вы это делаете, и понимаете последствия, если таковые имеются. Например, если нарушение закона приводит к более легкому сопровождению и читабельности кода, но при этом сохраняется высокоуровневое разделение задач в приложении, в целом это нормально. Так что я бы не беспокоился о том, нарушает ли тот или иной вариант закон.

person Jeff    schedule 22.01.2010
comment
Привет Джефф, спасибо за ваш ответ. Что касается дублирования, я использую ограничения ссылочной целостности (InnoDB), поэтому languageCode и regionCode являются внешними ключами с ограничениями. Мне нравится этот стиль, так как он упрощает получение набора строк «многие ко многим» без необходимости присоединения к таблице локалей. Но я хочу иметь возможность добавлять локали отдельно от сайтов. Надеюсь, это имеет смысл. Во всяком случае, я вижу, что вы говорите. Я думаю, вы убедили меня использовать оба варианта, так как я буду использовать оба упомянутых вами сценария (первый во внешнем интерфейсе, второй в админке). Спасибо за ваш вклад. - person Decent Dabbler; 22.01.2010
comment
Еще раз спасибо, Джефф. Я возьму свой торт и съем его тоже. :) - person Decent Dabbler; 28.01.2010