Hey Peter, so you are doing the equivalent of a separate validate() and
save() right on the bean itself, which, in this example, doesn't make too
big a difference. But some problems can arise if we look at a more complex
yet realistic use-case.

Let's say a user submits an order and we need to:

   - partially update the user (perhaps they changed a communication
   preference during the order process)
   - create an order
   - create a billing address
   - update an independent statistics table that executive management
   uses

There are several objects involved here - possible composed, possibly not,
it doesn't really matter - and each would probably have a layer of
validation. One way of performing the save is to have one main function
saveOrder() (located in some service) that goes about creating, validating
and saving each object then aggregating the error messages into one final
ErrorCollection. This provides a nice, clean, simple interface for a complex
process. But then what do you return from that function - just the
ErrorCollection? What about the objects at hand, such as the newly created
billing address, how do we get references to those? Perhaps we can reload
everything on a subsequent broadcast, but using which OrderID?

On the flip side we can break apart the jumbo method and start calling
smaller methods independently each of them returning appropriate data that
we need back to the controller. But of course, the more you do that, the
smarter your controller is getting and the less re-usable your code.

So the tighter and cleaner you make your service functions, the more awkward
or problematic the returntypes. And the more flexible or atomic you make the
service the more intelligence your controller has to hold. In the
aformentioned case it seems that there is no level of real cleanliness.

Thoughts?
Baz




On Jan 13, 2008 6:20 PM, Peter Bell <[EMAIL PROTECTED]> wrote:

>  Hi Baz,
>
> I can't think of a case where I'd be saving 10 independent objects. In my
> experience, I'm either saving one object, I'm saving a collection of objects
> of the same type (e.g. To update the price on 8 different products using a
> single form or grid) or I'm saving an object which may have composed or
> associated objects that also require saving.
>
> My real code assumes a collection of n-objects of the same type, and a
> single object is just a special case where n=1, so imagine the code I sent
> you within a cfloop and you'll get the idea. For composed objects I let my
> ORM do the lifting. If I really had a use case where I had to save multiple
> completely independent objects (that don't have any association or
> composition relationships) , I'd probably create an appropriate service
> class for handling that and would write a method within it that would
> orchestrate the independent method calls to the various object services. To
> date that use case has never arisen in the projects I've built.
>
> As for returning errors, I've been playing with a number of different
> approaches since obviously you want both the bean data and the error
> messages. I'm moving towards something like:
>
> If User.isValid()
>   User.save()
> /If
>
> And with a User.getInvalidFieldList() and/or a User.isValid(PropertyName)
> and User.errorMessage(PropertyName). Also, as this is an IBO, it can
> contain a collection of users, so I can loop through them and store
> validation status and error messages for each, making this equally easy to
> work with for one object or for a collection of objects as the single is
> just the special case of n-objects where n=1. With this approach, I just
> pass the bean around and it contains both the data the user tried to enter
> and the associated errors.
>
> Right now I do something a little different each time I touch validation
> so I can get a feel for the different approaches and decide what to
> standardize on.
>
> Best Wishes,
> Peter
>
>
> On 1/13/08 8:40 PM, "Baz" <[EMAIL PROTECTED]> wrote:
>
> If the form submission was a lot more complex and required the saving of,
> say, 10 different objects. Would you still interact with each object
> individually in the controller, or move all of that to a service function
> that orchestrates the interactions? If you would choose the latter, and
> given that in the another post you said that you would handle the creation
> of objects in the service rather than the controller, you are then faced
> with the issue of how to return the bean(s) and/or errorcollection from the
> save() method...
>
> You know?
>
> Baz
>
>
> On Jan 13, 2008 5:15 PM, Baz <[EMAIL PROTECTED]> wrote:
>
> Hey Peter,
>
> Looks very tidy! So I guess the validation occurs in the save() method.
> What would that method return, True/False? And then later on you would
> evaluate the result to see whether to retrieve the error collection?
>
> Cheers,
> Baz
>
>
> On Jan 13, 2008 5:08 PM, Peter Bell <[EMAIL PROTECTED]
> <mailto:[EMAIL PROTECTED]> <[EMAIL PROTECTED]> > wrote:
>
> Hi Baz,
>
> Why not just:
>
> var Result = ";
> var User = UserService.new(User);
> User.LoadStruct(form);
> Result = User.save();
> AddResult(Result);
>
> I have some generic code so I don't have to type this for every controller
> that handles a form, but this is generally what I do.
>
> Best Wishes,
> Peter
>
>
>
> On 1/13/08 8:00 PM, "Baz" <[EMAIL PROTECTED]> wrote:
>
> Another design choice I see go both ways is whether to perform validation
> in the save() method or to call each method separately. Example controller
> functions could be (pseudo code):
>
> - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
> - - - - - - - -
>
> *SEPARATE SAVE & VALIDATE
> *var UserService=getBean('UserService');
> var FormVariables=getAllValues();
>
> var ValidationResult='';
> var SaveResult='';
>
> set ValidationResult=UserService.validate(FormVariables); // returns an
> error collection object
>
> if ValidationResult.hasErrors()
>      setValue('ReturnObject', ValidationResult);
>      addResult('Fail');
> else
>      set SaveResult=UserService.save (FormVariables); // returns a
> populated user bean object
>      setValue('ReturnObject', SaveResult);
>      addResult('Success');
> end
>
> - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
> - - - - - - - -
>
> *COMBINED SAVE & VALIDATE V1.0
> *var UserService=getBean('UserService');
> var FormVariables=getAllValues();
>
> var UserBean=UserService.newUser();
> var SaveResult='';
>
> set UserBean.setMemento(FormValues);
> set SaveResult=UserService.save(UserBean); // returns true if saved
> successfully, or false if validation errors exist (the error collection
> would be saved in the bean itself for retrieval later)
>
> setValue('ReturnObject', UserBean);
>
> if SaveResult is True
>      addResult('Success');
> else
>      addResult('Fail');
> end
>
> - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
> - - - - - - - -
>
> *COMBINED SAVE & VALIDATE V2.0
> *var UserService=getBean('UserService');
> var FormVariables=getAllValues();
>
> var SaveResult=UserService.save(FormVariables); // returns a complex
> result object with properties: STATUS ('Success', ValidationError') and
> PAYLOAD (that contains either a UserBean or ErrorCollection depending on the
> STATUS)
>
> setValue('ReturnObject ', SaveResult.getPayload() );
>
> if SaveResult.getStatus() is 'Success'
>      addResult('Success');
>
> else SaveResult.getStatus() is 'Validation'
>      addResult('Fail');
> end
>
> - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
> - - - - - - - -
>
> CONS OF KEEPING THEM SEPARATE:
>
>    - Controller has to be smarter, which is bad, because there will be
>    more code duplication if you change the presentation layer to flex, for
>    example.
>    - Function coupling: Coders have to "remember" to always validate()
>    before saving() - an unnecessary additional complexity (unless, of course,
>    there are times in your app where you save() by defining all values 
> yourself
>    (thereby knowing the values are correct) rather than from user input)
>
> CONS OF COMBINING THEM COMBINED
>
>    - Requires complex and unnatural result handling (either by
>    affecting the bean by reference, or using a special RESULT object)
>
>
> Cheers,
> Baz
>
>
>
>
>
>
>
>
>
>
>
>
>
> >
>

--~--~---------~--~----~------------~-------~--~----~
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