views:

386

answers:

4

I was trying to separate my DAL from my Business Layer, and in doing so, I decided to eschew any ActiveRecord approach and go for a DataMapper approach. In other words, my domain objects would not take care of persisting themselves. In doing so, I seem to be encroaching on the "anemic domain model" anti-pattern. For instance, one of the entities in my program is an Organization.

An organization is represented as something like this:

class Organization {
    private $orgId;
    private $orgName;

    // getters and setters
}

So basically this organization does nothing other than act as "bag" (as Martin Fowler says) for some data. In the PHP world it is nothing more than a glorified array. There is zero behaviour associated with it.

And behaviour in the program, I've been sticking in "service level" class like an OrganizationService which mostly serves as an intermediary between these objects and the DAL.

Other than potential scaling issues with PHP (I do have other reasons why I insist on "bagging" my data in these objects), is this approach totally off?

How do you handle your domain models in these situations? Perhaps an organization isn't part of my domain in the first place?

A: 

It might just be anemic now?

For instance, once time I was developing a meeting/conference registration site. It started with only one meeting.

There was still a meeting class and only one instance, but the next year we held the conference, it was expanded and new properties were added (to hold two back-to-back meetings), so clearly it was just not fully developed yet, as we then added meeting groups which could contain multiple meetings.

So I think it's important to keep in mind that domains change over time and your model may end up being refactored, so even if you might think it's anemic, it might just be a little too forward-looking (like your organization class will start to get some settings, rules or preferences or something).

Cade Roux
A: 

Your entity is not anemic because you are taking a reposnsibility that should not be there to begin with. Persisting and fetching entities is reponsibility of Repositories. Really your behavior should be in your entities not in a service layer. But explaining what goes where is way beyond simple answer. DDD by Eric Evans is a good starting point.

epitka
+2  A: 

well, it seems like this at the beginning, but when you'll refactor your code more, you'll get to some behavior for your organization class...

one example that i might think of now is if you have people (employees), you may want to associate them with organization. so, you might have a method AssociateEmployee(User employee) that might find its place in your organization class.

Or you might change location of the company, instead of setting parameters like address, city, state in three steps, you might add ChangeLocation(Street, City, State) method..

Just go step by step, when you encounter some code in you BL/service layer that seems like it should belong into the domain, move it down to the domain. If you read Fowler, you will get it very soon when you see it in your code.

zappan
+1  A: 

You might also consider that if you don't have a lot of business rules, or the domain just isn't that complex, that DDD may be too much overhead for you. DDD is an excellent solution for large, complicated domains, but is a lot of overhead and complexity if you are simply doing data in, data out. DDD is harder to design and inherently adds complexity, so to justify it, the complexity of the problem domain should outweigh that.

That's all I would add to zappan and epitka.

jlembke
I happen to have more complicated business rules in other parts of my domain. This particular application is a system for organizations to set up chinese auctions (http://en.wikipedia.org/wiki/Chinese_auction). Other aspects of the application, like the iteraction with auction prizes and the shopping cart actually do contain fair amounts of logic. All in all, my main goal is not necessarily DDD, but separation of concerns.
blockhead