Hi Brian,

I¹ll disagree with you here. The calling code has to know three things:
* How to pass information to the service in the format it wants
* How to tell whether the save succeeded
* How to pass any error messages in a way the display will want to see them
(actually, it¹ll probably just be a conduit for the information, so it is
more likely the view will have to know this).

It needs to know how to pass well formed data to the service otherwise the
save won¹t work. It needs to tell whether the save succeeded as otherwise it
won¹t be able to make the controller decision to say whether to cflocation
to another screen or to redisplay the form (or whatever approach you¹re
using), and it needs to pass the errors along in a way the view can
understand as otherwise the view won¹t be able to display the correct error
messages.

So, whether you make it:
If UserService.isValid()
    UserService.save();
    location(³UserList²);
Else
    Display Form 

OR

Success = UserService.Save()
If Success 
  location(³UserList²)
Else
    DisplayForm

(o rmore likely, a variant where ³Success² is really ErrorCollection and you
test whether ErrorCollection has any members, or is ErrorBean and test
whether ErrorBean.hasErrors())

In any of these cases you are performing both a command and a query. The
command is to save the data and the query is whether it was saved
successfully. Nothing wrong with turning that into a single mixed method
call (some purists might say you should keep commands and queries separated,
but I¹m not that picky), but it isn¹t reducing the amount of information
required or the knowledge of the API. You¹re just doing the command and the
query in a single line so it isn¹t making the controller any dumber ­ just
more concise.

Best Wishes,
Peter


On 1/15/08 12:56 PM, "Brian Kotek" <[EMAIL PROTECTED]> wrote:

> 
> 
> On Jan 15, 2008 11:57 AM, Adam Haskell <[EMAIL PROTECTED]> wrote:
>> I'm much more comfortable with doing 2 calls in my service, model.validate();
>> model.save(), instead of Model.save() and have the save do the validation.
>> Doing model.save makes my service not much more a facade which isn't what I
>> want. Additionally in our environment we have multiple validaters, some of
>> which should not, in my opinion, be part of the domain's concern. An example
>> of this would be Enterprise vs domain specific validation. Something like
>> name is 35 characters and does not have cross sit scripting is Enterprise
>> concerns and part of the validation across all applications irregardless of
>> domain. Where as address must be in the US is domain specific to Contest
>> entries. The converse is true too though if you put too much in the service
>> layer your domain model becomes anemic.
> 
> See, I disagree here. I don't think it should be the job of the calling code
> to know that this is a two step process. I would call myService.save(someData)
> and the validation would happen inside the model. If you have some
> higher-level validation that would take place outside of the actual business
> object, I would still do that in the service; that is its job. I would do that
> validation inside the service, or more probably I would build it into the
> Validators, which means the Validator might internally be leveraging several
> specific Validators to do it's job. So I might do
> 
> myService.save(userData);
> 
> and inside the service I might do:
> 
> user = createUser(userData);
> result = createResult();
> if (user.isValid()) {
> result.setSuccess(true);
> }
> else {
> result.addErrorMessages (user.getErrorMessages());
> result.setOriginalData(userData);
> }
> return result;
> 
> 
>  
>> 
>> Adam Haskell
>> 
>> 
>> 
>> On Jan 15, 2008 8:31 AM, Alan Livie < [EMAIL PROTECTED]> wrote:
>>> 
>>> Good anecdote but I am confused!
>>> 
>>> You said 'in this case the
>>> Service should be earning it's keep and making sure the documents are
>>> valid
>>> and ready for it's client, the model. '
>>> 
>>> Are you sure about this? Shouldn't the model be responsible for making
>>> sure things are valid - ie look after itself.
>>> 
>>> I see the service more as a smart api that delegates to the model for
>>> all the business logic and also can provide 'application-specific'
>>> functionality like logging, email notifications etc
>>> 
>>> But maybe I'm misunderstanding it or taking the anecdote too
>>> seriously! It's more accurate than the MVC song at least :-)
>>> 
>>> Alan
>>> 
>>> On Jan 15, 12:47 pm, "Adam Haskell" <[EMAIL PROTECTED]> wrote:
>>>> > I've used this anecdote before, and I think it is amusing so I'll use it
>>>> > again.  The way I think about it is The model and View are going through
>>>> a 
>>>> > divorce and the controller and service are the lawyers. Now thinking
>>>> about
>>>> > it in these terms, would it make sense for the Controller (the View's
>>>> > lawyer) to be taking care of the Model's Affairs, in this case validating
>>>> > documents for the model? That doesn't make much sense, in this case the
>>>> > Service should be earning it's keep and making sure the documents are
>>>> valid
>>>> > and ready for it's client, the model. Sure the Controller might throw in
>>>> > some JS for the View to do some preliminary checking so the always
>>>> bitchy,
>>>> > soon-to-be ex, spouse won't complain but it really is the spouses
>>>> lawyer's
>>>> > duty to inform the spouse that the documents are valid, or  return the
>>>> > documents to some one telling them to try again, no deal. That being said
>>>> > Brian's earlier statement about calling something from Flex really has
>>>> > helped me clear up what should go where. Anecdotes provide a means to
>>>> > getting over the hump but once you are over the hump real life
>>>> programming
>>>> > drives the point home and Brian's example/thought process is spot on.
>>>> >
>>>> > Adam Haskell
>>>> >
>>>> > On Jan 14, 2008 11:53 PM, Brian Kotek <[EMAIL PROTECTED]> wrote:
>>>> >
>>>>> > > It depends on what you mean by "appropriate methods", but if you're
>>>>> > > talking about something similar to what Peter used an an example:
>>>> >
>>>>> > > If (Order.isValid())
>>>>> > > {
>>>>> > >    Order.save();
>>>>> > > }
>>>>> > > Else
>>>>> > > {
>>>>> > >   Screen = OrderForm;
>>>>> > >   Data = Order;
>>>>> > > };
>>>> >
>>>>> > > No, I wouldn't be doing that in the Controller (and I think we might
be
>>>>> > > getting some miscommunication here because I'm pretty sure Peter and
>>>>> Sean 
>>>>> > > wouldn't either). My Controllers are very dumb. The only thing they do
is
>>>>> > > ask the Model to perform some business logic (via the service layer),
and
>>>>> > > then invoke the appropriate views or execute a redirect. That covers
>>>>> 99% of 
>>>>> > > what my Controllers do.
>>>> >
>>>>> > > The problem with doing something like the above in the Controller
>>>>> means
>>>>> > > that the model is no longer neutral and self-contained. I can't call
>>>>> the 
>>>>> > > service layer from Flex now, because the logic that checks validity
>>>>> and does
>>>>> > > saving is executed by the Controller, not the Model. I would have a
>>>>> method
>>>>> > > in my service named something like "
>>>>> orderService.saveOrder(orderData)",
>>>>> > > and internally that service layer method might create an Order,
>>>>> validate it,
>>>>> > > save it, and return a success or failure result that the Controller
>>>>> can then 
>>>>> > > use to determine how to proceed (cflocation or redisplay form with
>>>>> errors,
>>>>> > > for example). I'm pretty sure that this is what Sean and Peter are
>>>>> also
>>>>> > > talking about.
>>>> >
>>>>> > > On Jan 14, 2008 9:11 PM, Baz <[EMAIL PROTECTED]> wrote:
>>>> >
>>>>>> > > > Sean, Brian, it seems you are both on board with getting a
>>>>>> newUserBean()
>>>>>> > > > from the service in the controller then calling the appropriate
>>>>>> methods on 
>>>>>> > > > that UserBean later on in the controller. Do you also handle
>>>>>> queries or
>>>>>> > > > multiple objects in the same way that Peter does? That is, do you
code
>>>>>> > > > gateway-type methods into your service that interact with a
>>>>>> DAO/Gateway to
>>>>>> > > > return multiple instances of your object?
>>>> >
>>>>>> > > > Baz
>>>> >
>>>>>> > > > On Jan 14, 2008 4:40 PM, Brian Kotek < [EMAIL PROTECTED]
>>>>>> <mailto:[EMAIL PROTECTED]>  > wrote:
>>>> >
>>>>>>> > > > > Absolutely, I didn't mean to imply that the service actually
does
>>>>>>> > > > > everything itself.
>>>> >
>>>>>>> > > > > On Jan 14, 2008 7:35 PM, Sean Corfield < [EMAIL PROTECTED]
>
>>>>>>> > > > > wrote:
>>>> >
>>>>>>>> > > > > > On Jan 14, 2008 1:19 PM, Brian Kotek < [EMAIL PROTECTED]>
wrote:
>>>>>>>>> > > > > > > I think he is saying that his controllers only interact
with
>>>>>>>> > > > > > services. The
>>>>>>>>> > > > > > > easy rule of thumb for me is: if this was called by Flex
instead 
>>>>>>>> > > > > > of my HTML
>>>>>>>>> > > > > > > controller, would it still work? The answer should be
>>>>>>>>> "yes". Which
>>>>>>>> > > > > > means all
>>>>>>>>> > > > > > > logic of any consequence (beyond doing something like a
>>>>>>>> > > > > > cflocation, which is
>>>>>>>>> > > > > > > specific to the HTML view anyway) should be handled in the
model.
>>>> >
>>>>>>>> > > > > > Right, but that can still be in the domain object rather than
the 
>>>>>>>> > > > > > service. You just need to expose the API via the service for
remote
>>>>>>>> > > > > > interaction. It doesn't mean all the business logic is in the
>>>>>>>> > > > > > *service* which is at the heart of Baz's question, I believe.
>>>>>>>> > > > > > --
>>>>>>>> > > > > > Sean A Corfield -- (904) 302-SEAN
>>>>>>>> > > > > > An Architect's View --http://corfield.org/
>>>> >
>>>>>>>> > > > > > "If you're not annoying somebody, you're not really alive."
>>>>>>>> > > > > > -- Margaret Atwood
>>> 
>> 
>> 
>> 
> 
> 
> > 
> 



--~--~---------~--~----~------------~-------~--~----~
You received this message because you are subscribed to the Google Groups 
"CFCDev" group.
To post to this group, send email to [email protected]
To unsubscribe from this group, send email to [EMAIL PROTECTED]
For more options, visit this group at 
http://groups.google.com/group/cfcdev?hl=en
-~----------~----~----~----~------~----~------~--~---

Reply via email to