> as it's probably the most helpful conversation I've ever had about domain logic.
I absolutely agree and I just don't want this thread to end...
Besides already mentioned Martin Fowler's book (just bought it), what
books/resources would you suggest are worth reading on this subject?
Ideally something more conceptual/philosophical (rather than too
concrete, with some examples though), web application oriented if
possible... (I have not "googled" anything yet.)
Thanks again for inspiration.
Regards,
Marian
On 28.7.2008 18:54, Jonathan Lebensold wrote:
> Hi Adam,
>
> I've found that the Repository Pattern (PoEAA) has done me a lot of good
> in medium-scale projects. When you might have a complex underlying data
> model (with 1-m m-m and 1-1), it doesn't make sense to expose multiple
> aggregate roots (ways of persisting) since it complicates the
> interaction between the controller, which is interesting in client
> interaction, and the persistence of data.
>
> I start out by identifying aggregate roots and create repositories
> around them. These repositories serve up data transfer objects (which
> can be Doctrine or Zend_Db data objects) and then persist them.
>
> The big advantages to this approach are thin controllers and
> transactionality since repositories, by definition have a unit of work
> associated with them. For me, its the Repository that provides the
> "coarse api" that Bryce was referring to. If you're clever, you can
> store multiple data transfer object types in one repository's Unit of
> Work, thereby doing commits atomically.
>
> Also, Zend_Form helps keep things thin. On my own projects, I've managed
> to keep a small controller for complex forms by doing validation in
> Zend_Form and flushing out the persistData() method (which in turn fires
> against the Repositories in question). So with the example you gave, I
> would've relegated that to a Zend_Form-inherited object's persistData()
> method.
>
> This way, the repositories, as the project grows, can be refactored into
> classes that live inside inside the domain, which can be tested and that
> the controller doesn't need to deal with.
>
> my 2 cents,
>
> Jon Lebensold
> http://jon.lebensold.ca
>
> On 28-Jul-08, at 11:58 AM, Bryce Lohr wrote:
>
>> Hi Adam,
>>
>> Adam Jensen wrote:
>>> 1. A good domain model is unaware of its own underlying data source
>>> (or even that it has one), and therefore cannot really be responsible
>>> for its own persistence.
>>> 2. Code using the domain model (e.g., a controller action) shouldn't
>>> really be aware of the technical details of persistence either.
>>>
>>
>> This is where the philosophy part comes in to play: your rule #1
>> precludes perfectly valid patterns, such as Active Record, that "know"
>> something about the data source structure. You have to decide based on
>> your own philosophy, the app's requirements, and the trade-offs of
>> different data source strategies, which approach is really the most
>> useful.
>>
>>> [code]
>>> public function someAction()
>>> {
>>> // The Mapper here is the only object that knows
>>> // anything about the underlying data source.
>>> $mapper = new Travel_DataMapper();
>>>
>>> // Use the mapper to retrieve an existing domain object
>>> $model = $mapper->findTrip(14);
>>>
>>> // Change some arbitrary data
>>> $model->traveler = 'Adam';
>>> $model->departure = '2008-09-01';
>>> $model->getDestinationByOffset(2)->country = 'MX';
>>>
>>> // Pass the modified domain object back to the mapper for persistence
>>> $mapper->save($model);
>>> }
>>> [/code]
>>>
>>> This seems ALMOST correct to me, but I'm still not sure I'm entirely
>>> satisfied. The thing is, the controller is now aware of the
>>> persistence layer, which seems to violate rule #2 above.
>>>
>>
>> To me, this doesn't violate rule #2 (based on my very superficial
>> knowledge of what you're trying to achieve). Here, the data mapper has
>> a fairly abstract interface that doesn't appear to tie you to any
>> specific data source structure other than one identifying Trip objects
>> by an integer. This would probably be flexible enough for most of the
>> examples I've seen so far in this thread.
>>> Then again, although the controller is aware of the persistence layer,
>>> it doesn't know anything about the details of the persistence process.
>>> So maybe it's not the worst thing in the world...after all, it seems
>>> like persistence in a web application is mainly necessary due to the
>>> stateless nature of HTTP transactions, and HTTP transactions are the
>>> bread and butter of the controller layer.
>>>
>>
>> I agree: in MVC web applications, I think the controller's main job is
>> to translate HTTP requests into some form of request upon the
>> application's domain model, and then to express the domain model's
>> results as something meaningful in HTTP. This means managing the
>> interaction with domain model objects, and persistence is still part
>> of the model layer.
>>
>> That said, if you want, you can use something like a Service Layer [1]
>> to cleanly separate the HTTP-specific code from the domain-object
>> management code. Use the Service Layer as a facade to create a very
>> coarse API that would roughly correspond to what each controller
>> action needs to do with the domain model. You'd have to decide if this
>> would really be worth the effort for your application.
>>> Anyway...I really appreciate the continued discussion here...we almost
>>> ought to turn this into a tutorial, as it's probably the most helpful
>>> conversation I've ever had about domain logic. Even the philosophical
>>> parts...turns out I actually have a philosophy degree, so that's right
>>> up my alley :)
>>>
>>> Thanks!
>>> Adam
>>>
>>
>> Hope this helps,
>> Bryce Lohr
>>
>> [1] http://martinfowler.com/eaaCatalog/serviceLayer.html
>>
>> August 1st is National Minority Organ Donor Awareness Day
>>
>
没有评论:
发表评论