模型的粒化?

Dec*_*ler 5 law-of-demeter models granularity

我正在开发一个主要基于Zend Framework组件的CMS.此CMS的一些数据库表如下:

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

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

site_locale // link sites with locales
| siteId | languageCode | regionCode | isActive | isDefault |
-------------------------------------------------------------
Run Code Online (Sandbox Code Playgroud)

我有一个名为的模型Site,其中包括以下方法:

getId()
getName()
listLocales() // list all locales for this site
Run Code Online (Sandbox Code Playgroud)

我对如何定义模型的规模化有所了解:

一种选择是从方法返回SiteLocale对象/模型(换句话说,DB表表示)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()
Run Code Online (Sandbox Code Playgroud)

另一种选择是在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
Run Code Online (Sandbox Code Playgroud)

你觉得什么是正确的方法?为什么?

此外,第一种选择(或者甚至两种选择)是否会违反得墨忒耳定律

编辑(22月1日)
虽然我喜欢杰夫的回答,但我仍然对新的/其他观点持开放态度.

Jef*_*eff 3

首先,关于数据库表:您可能可以进一步规范化数据库。locale 和 site_locale 表之间存在重复。当然,我在这里没有看到大局,所以你的做法背后可能有一些东西。

坦率地说,任何一个选择都很好。我会选择使您的代码更具可读性和可维护性的设计。例如,如果您选择第一个选项,您最终会得到这样的循环吗?

site_locales = site.listLocales()
foreach (site_locale in site_locales) {
    if site_locale.isDefault() {
        do_something(site_locale.getLocale())
    }
}
Run Code Online (Sandbox Code Playgroud)

如果是这样,那么我会避免它并选择第二个选项,最终得到:

do_something(site.getDefaultLocale())
Run Code Online (Sandbox Code Playgroud)

快速浏览一下就更容易理解了。也许它甚至会提高您网站的性能。

但是,如果您认为将来要做很多利用 SiteLocales 列表的工作,但您不确切知道除了getDefaultLocale()listActiveLocales()和 之外还要做什么listAllLocales(),那么第一个选择可能是理想的。或者您甚至可以结合使用两者。

至于德墨忒尔法则,它更像是德墨忒尔准则。打破任何规则都是可以的,只要你有意识地去做,理解为什么这样做,并理解后果(如果有的话)。例如,如果违反法律会导致代码更易于维护和可读,但您仍然在应用程序中保留高级别的关注点分离,那么通常是可以的。所以我不担心这两种选择是否违法。