views:

75

answers:

1

I'm developing a CMS largely based on Zend Framework components. Some of the database tables for this CMS are as followed:

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

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

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

I have a model named Site which consists, amongst others, of the following methods:

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

I'm kind of on the fence on how granularized I should define models:

One option would be to return SiteLocale objects/models (in other words a DB table representation) from the listLocales() method, where these SiteLocale objects contain the following methods:

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()

The other option would be to simply create the following methods in the Site model, and be done with it:

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

What do you feel is the right way to go? And why?

Furthermore, would the first option (or perhaps even both options) violate the Law of Demeter?

EDIT (22 jan)
Although I like Jeff's answer, Im still open for new/other perspectives.

+2  A: 

First, regarding the database tables: You could probably normalize the database further. There's duplication between the locale and site_locale tables. Of course, I'm not seeing the big picture here so there might be something behind the way you've done it.

Frankly, either option is fine. I would choose the design that makes your code more readable and maintainable. For instance, if you chose the first option, would you end up with loops like this all over the place?

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

If so, then I'd avoid it and go with the second option and end up with:

do_something(site.getDefaultLocale())

This is much more understandable with a quick glance. Maybe it'd even improve your site's performance.

However, if you think you're going to do a lot of work that utilizes lists of SiteLocales in the future, but you don't know exactly what you're going to do beyond getDefaultLocale(), listActiveLocales(), and listAllLocales(), then perhaps the first option might be ideal. Or you could even use a combination of the two.

As for the Law of Demeter, it's more like the Guideline of Demeter. It's OK to break any rule as long as you do it consciously, understand why you're doing it, and understand the consequences, if any. For instance, if breaking the law leads to more maintainable and readable code, yet you still preserve a high-level separation of concerns in your application, it's generally OK. So I wouldn't worry about whether or not either option breaks the law.

Jeff
Hi Jeff, thanks for your response. About the duplication, I'm using referential integrity constraints (InnoDB) so the languageCode and regionCode are foreign keys with constraints. I like this style since it makes it easy to fetch the many-to-many rowset without having to join the locale table. But I do want to be able to add locales decoupled from sites. Hope this makes sense. Anyway, I see what you are saying. I think you convinced me to use both options, since I will be utilizing both the scenario's you mentioned (first in the frontend, second in the admin backend). Thanks for your input.
fireeyedboy
Thanks again Jeff. I'm gonna have my cake and eat it too. :)
fireeyedboy