On Thu, August 4, 2005 2:12 pm, Dave Newton said:
> Frank W. Zammetti wrote:
>
>>ArrayList getClientList();
>>ClientDTO getClientInfo(String id);
>>boolean saveClient(ClientDTO client);
>>boolean deleteClient(String id);
>
> (Hey, shouldn't getClientList return a List? ;)

Yep, I suppose it should :)  I have a bad habit of specifying
implementations rather than interfaces for collections.  Some day I'll
break myself of it :)

> I've never actually switched persistence mechanisms, of course, which
> leads me to wonder if I really need[ed] to do all that work. :/

I've yet to do it either, although I may have to with my most recent app. 
I'm not really looking forward to it... I don't mind learning new stuff as
part of a new project, but retrofitting tends to be more annoying than
fun, for me anyway.

>>I even toyed at one point with the idea of doing all of the above from a
>>config file and reducing the app to a single specialized Action in most
>>places.  When you find that most of your Actions look like the above,
>>that's a fairly appealing idea!
>>
>>
> That's actually where I'm headed right now for generic CMS/CRUD, but I'm
> getting bogged down.
>
> *sigh*

This kind of goes with the whole framework discussions around here
recently... this is the kind of thing I'd like to see in a new framework. 
I think there are large chunks of most webapps that can be "developed" in
a purely declarative way, if the system is robust enough.  I should only
have to write code for the more fringe cases (maybe not QUITE fringe
cases, but I think you know what I mean).

> Well, yes and no--Common Lisp implements its OO by using generic methods:
>
> (when (isValid cfbh cfb)
>   (save cfb cdto))
>
> so you still write an isValid and a save for each useful combination of
> FB and FBHelpers, but methods are dispatchedd based on the types of the
> parameters. More or less the same as if you wrote a class like this:
>
> public class SortaGeneric {
>     public static boolean isValid(ClientFBHelper cfbh_, ClientDTO cdto_) {
>         // ... and then a miracle occurs
>         return resultsOfClientDtoValidation;
>     }
>     public static boolean isValid(CompanyFBHelper cfbh_, CompanyDTO cdto_)
> {
>         // ... you get the idea
>     }
> }
>
> and did
>
> if (SortaGeneric.isValid(cfbh, cdto)) {
>     if (SortaGeneric.save(cdto)) {
>     }
> }
>
> but in Lisp you can define the generics in a more appropriate place than
> a non-local static method class.
>
> The only real difference between this and what you've done is the
> location of those methods--basically OO-by-hand rather than letting the
> system do it for you. With mild config and reflection you could remove
> the class depedencies in the actions, which is where my low-level stuff
> seems to be heading at the moment.

Interesting stuff!  I like the comment about removing the class
dependencies from the Actions, that's really what my declarative version
did, at least as far as the proof-of-concept went... I added some config
elements to struts-config that allowed you to declare what FBs and
FBHelpers each Action needed.  So, you might see:

<actionDependencies action="action1">
  <object name="ClientFB">com.company.app.ClientFB</object>
  <object name="ClientFBHelper">com.company.app.ClientFBHelper</object>
</actionDependencies>

So, in a sense, those dependencies were injected into the Action.  You
just did the action work with them, everything else was handled outside.

Then I had a special Action base class that worked against an XML file. 
So, in keeping with my examples from before, you might see:

<action name="action1">
  <function id="1">createDTO:ClientDTO</function>
  <function id="2">copyActionForm:ClientDTO</function>
  <function
id="3">callMethod:ClientHelper.isClientValid(ClientDTO)</function>
  <check sourceid="3">
    <if outcome="false">returnForward:clientnotvalid</if>
  </check>
  <function id="4">callMethod:ClientFB.saveClient(ClientDTO)</function>
  <check sourceid="4">
    <if outcome="true">returnForward:goodsave</if>
    <if outcome="false">returnForward:badsave</if>
  </check>
</action>

The createDTO, copyActionForm, callMethod and returnForward were standard
"commands" I could issue.  I got it working to this point, never took the
exercise any further... there were some obvious problems that would have
taken a bit more effort to solve, but more importantly I wasn't really
sure it was actually better... declarative over code is almost always true
for me, but there is a certain point where the declarative complexity
outweighs just writing the code.  This might have been one of those cases,
I'm not sure :)

Even still, I think the idea is an interesting one, if done well.

Frank

---------------------------------------------------------------------
To unsubscribe, e-mail: [EMAIL PROTECTED]
For additional commands, e-mail: [EMAIL PROTECTED]

Reply via email to