You are viewing a plain text version of this content. The canonical link for it is here.
Posted to user@struts.apache.org by Sgarlata Matt <sg...@bah.com> on 2003/10/11 01:04:19 UTC

Re: Keeping Actions clean - separating actions from business modelfrom persistence

I use my own framework because I don't know any better.

I am using Torque as my underlying persistence mechanism, and I have
introduced a very simple level of indirection that I think should keep me
independent of Torque in the future (I plan to swap in Hibernate or OJB on
the next app I work on).  The level of indirection I introduced is
encapsulated in an object I call the DaoManager.  The DaoManager is created
by a Factory class that gives me an instance of the DaoManager that works
for my particular application.  Right now my Factory is creating a
DaoManager that works with Torque, but in the future it will create one that
works with Hibernate or OJB.  (More info on the Factory pattern is in the
Gang of Four book, not the J2EE core patterns book someone recommended to
Sasha earlier today).

public interface IRecordDao {
 public BigDecimal getId();
 public void setId(BigDecimal id);
}

public abstract class DaoManager {
 public abstract IRecordDao createDao(Connection conn, String daoClassName)
  throws DaoException;

 public abstract IRecordDao getDao(Connection conn, String daoClassName,
BigDecimal id)
  throws DaoException;

 public abstract void saveDao(Connection conn, IRecordDao record)
  throws DaoException;

 public abstract void removeDao(Connection conn, String daoClassName,
BigDecimal id)
  throws DaoException;
}

As you may have noticed, this technique introduces the constraint that each
DAO must have a single numeric primary key.  This is not an onerous
constraint, but may be an issue in an existing database where introducing
surrogate keys would cause problems.

I am interested in this topic so I may do some research this weekend to see
if I can think of a better way than I am currently using.

I don't know if there's a better list to discuss this type of thing... so
far this seems to be a pretty good one :)  You might want to prefix your
messages with [OT] (off-topic) if you aren't sure if they are appropriate
for the list.

Matt
----- Original Message ----- 
From: "Sasha Borodin" <sa...@whoissasha.com>
To: "Struts Users Mailing List" <st...@jakarta.apache.org>
Sent: Friday, October 10, 2003 6:44 PM
Subject: Keeping Actions clean - separating actions from business modelfrom
persistence


> Ted, Matt, Joe, and all the other helpful folks that chimed in earlier on
> persistence mechanisms:
>
> In trying to keep with best practices, I've managed to remove all "model"
> related code (business logic, and persistence) out of the Actions'
execute()
> method.  Now I'd like to take it one step further and decouple the
business
> model classes from the implementing persistence technology (btw, settled
on
> OJB for now :).  From Joe's post, it seems like the DAO pattern is called
> for to accomplish this.
>
> My (slightly off topic) question is this:  who develops their own DAO
> framework (like the dao and dao factory interfaces), and who uses a 3rd
> party framework (like iBATIS's Database Layer) and why?  There was
something
> mentioned about the discovery of the persistence mechanism as well...
>
> Any references to webpages/books would be appreciated.
>
> BTW, I've been shamelessly posting to this list questions that are
probably
> better directed elsewhere.  What would be a more appropriate list?
>
> Thank you,
>
> -Sasha
>
>
> ---------------------------------------------------------------------
> To unsubscribe, e-mail: struts-user-unsubscribe@jakarta.apache.org
> For additional commands, e-mail: struts-user-help@jakarta.apache.org
>


---------------------------------------------------------------------
To unsubscribe, e-mail: struts-user-unsubscribe@jakarta.apache.org
For additional commands, e-mail: struts-user-help@jakarta.apache.org


Re: Keeping Actions clean - separating actions from businessmodel from persistence

Posted by Sgarlata Matt <sg...@bah.com>.
Hi Sasha, sorry it has taken me so long to get back to you.  I've been
putting a lot of thought into my response, and I would still like to think
about the issues here a little more.  Specifically, I want to evaluate using
the iBATIS DAO layer instead of my own custom DaoManager.  I will probably
send a follow-up email in a couple weeks.  Comments below...
----- Original Message ----- 
From: "Sasha Borodin" <sa...@whoissasha.com>
To: "Struts Users Mailing List" <st...@jakarta.apache.org>
Sent: Friday, October 10, 2003 11:32 PM
Subject: Re: Keeping Actions clean - separating actions from businessmodel
from persistence


> What I'm trying to grasp is where it it best for the business object <--->
> dao interaction to take place.  OK, let's make an example, cause I'm
having
> trouble thinking abstractly tonight...
>
> An online store customer selects several products, clicks "check out",
which
> calls a CheckOutAction.  From there:
>
> 1.  The CheckOutAction retrieves a Customer and a List of Product's from
the
> session; it creates an Order out of those components; it then calls
> placeOrder(Order) on a Store business class.
>
> 2.  Store.placeOrder(Order) saves the Order to persistent storage; then
uses
> an Emailer business class to emailOrderConfirmation(Order).
>
> ----------now the question:
>
> 1.  Which component is responsible for discovering the DaoManager,
> retrieving the OrderDao from that manager, and telling the dao to save()?
> Is it:
>     a. the Store.placeOrder() method?
>         -or-
>     b. the Order business object itself?

If you get a copy of the Core J2EE patterns book that someone recommended,
then the answer is "well, it depends".  If you are using business objects as
described in the book, the business object's job is to shield the rest of
your application from the underlying persistence mechanism.  It could do
this using the DaoManager.

However, I would still guess that Store.placeOrder() would tell the Order
business object when the save needs to take place, and the Order business
object would delegate this command to the save() method of the DaoManager.
Otherwise the business object knows when to save itself... that sounds to me
like a TV knowing when to turn itself on/off ;)

> Is it the business entity object's responsibility to discover and use its
> dao's, or that object's *user's* responsibility?
>
> Matt, you seem to forgo business entity classes and create DAO's right in
> your action, passing those to business "use case" classes...

Yes, that is exactly what I do for the sake of simplicity.  The Core J2EE
patterns book says that when the data model closely represents the domain
model this approach is valid.

> Mahesh, your business "use case" components seem to be the ones
responsible
> for discovering the right DaoManager implementation, and retrieving the
> needed DAO classes...
>
> Anyone make the business entity classes themselves responsible for finding
> and using their respective dao's (say, when an Order is issued a save()
> command)?
>
> Thanks for all your input!
>
> -Sasha
>
>
> On 10/10/03 20:25, "Sgarlata Matt" <sg...@bah.com> wrote:
>
> > I have a 4 tier architecture.
> >
> > PRESENTATION TIER
> > - Struts
> > - Action classes
> >
> > BUSINESS TIER
> > - Business Objects
> >
> > INTEGRATION & PERSISTENCE TIER
> > - DAO Manager
> > - DAOs
> > - Other database access mechanisms (I do some JDBC using a fancy
home-grown
> > SQL building mechanism when dealing with particularly complex queries)
> >
> > RESOURCE TIER
> > - Databases
>
>
> ---------------------------------------------------------------------
> To unsubscribe, e-mail: struts-user-unsubscribe@jakarta.apache.org
> For additional commands, e-mail: struts-user-help@jakarta.apache.org
>


---------------------------------------------------------------------
To unsubscribe, e-mail: struts-user-unsubscribe@jakarta.apache.org
For additional commands, e-mail: struts-user-help@jakarta.apache.org


Re: Keeping Actions clean - separating actions from business model from persistence

Posted by Sasha Borodin <sa...@whoissasha.com>.
What I'm trying to grasp is where it it best for the business object <--->
dao interaction to take place.  OK, let's make an example, cause I'm having
trouble thinking abstractly tonight...

An online store customer selects several products, clicks "check out", which
calls a CheckOutAction.  From there:

1.  The CheckOutAction retrieves a Customer and a List of Product's from the
session; it creates an Order out of those components; it then calls
placeOrder(Order) on a Store business class.

2.  Store.placeOrder(Order) saves the Order to persistent storage; then uses
an Emailer business class to emailOrderConfirmation(Order).

----------now the question:

1.  Which component is responsible for discovering the DaoManager,
retrieving the OrderDao from that manager, and telling the dao to save()?
Is it:
    a. the Store.placeOrder() method?
        -or-
    b. the Order business object itself?

Is it the business entity object's responsibility to discover and use its
dao's, or that object's *user's* responsibility?

Matt, you seem to forgo business entity classes and create DAO's right in
your action, passing those to business "use case" classes...

Mahesh, your business "use case" components seem to be the ones responsible
for discovering the right DaoManager implementation, and retrieving the
needed DAO classes...

Anyone make the business entity classes themselves responsible for finding
and using their respective dao's (say, when an Order is issued a save()
command)?

Thanks for all your input!

-Sasha


On 10/10/03 20:25, "Sgarlata Matt" <sg...@bah.com> wrote:

> I have a 4 tier architecture.
> 
> PRESENTATION TIER
> - Struts
> - Action classes
> 
> BUSINESS TIER
> - Business Objects
> 
> INTEGRATION & PERSISTENCE TIER
> - DAO Manager
> - DAOs
> - Other database access mechanisms (I do some JDBC using a fancy home-grown
> SQL building mechanism when dealing with particularly complex queries)
> 
> RESOURCE TIER
> - Databases


---------------------------------------------------------------------
To unsubscribe, e-mail: struts-user-unsubscribe@jakarta.apache.org
For additional commands, e-mail: struts-user-help@jakarta.apache.org


Re: Keeping Actions clean - separating actions from businessmodel from persistence

Posted by Sgarlata Matt <sg...@bah.com>.
----- Original Message ----- 
From: "Sasha Borodin" <sa...@whoissasha.com>
To: "Struts Users Mailing List" <st...@jakarta.apache.org>
Sent: Friday, October 10, 2003 8:33 PM
Subject: Re: Keeping Actions clean - separating actions from businessmodel
from persistence


> Matt, thanks for your quick feedback.
>
> > I use my own framework because I don't know any better.
> >
> > public abstract class DaoManager {
> > public abstract IRecordDao createDao(Connection conn, String
daoClassName)
> > throws DaoException;
>
> Which tier calls your DaoManager?  It seems from your code that the caller
> of DaoManager is responsible to knowing the database configuration
> information, as well as the implementing DAO class.  Is it the Action?

I have a 4 tier architecture.

PRESENTATION TIER
- Struts
- Action classes

BUSINESS TIER
- Business Objects

INTEGRATION & PERSISTENCE TIER
- DAO Manager
- DAOs
- Other database access mechanisms (I do some JDBC using a fancy home-grown
SQL building mechanism when dealing with particularly complex queries)

RESOURCE TIER
- Databases

In addition to the 4 tiers, my applications are separated into two parts.
One part is a reusable framework that is shared among many applications.
The second part is the actual application code that is specific to a single
application because of business rules, etc.  (Even if you don't need a
reusable framework for your work, such a thing can be useful because it
allows you to do things like swap out your persistence mechanism without
disturbing your presentation code and business objects)

A single Abstract Factory (informally called Walmart) is responsible for
creating the DAO manager and the business objects in the reusable framework.
The application code must define a concrete implementation of the Abstract
Factory.  This implementation must know how to create a DAO Manager that
works with the persistence mechanism being used.

So, to finally get around to answering your question, the caller of the DAO
manager does not need to know anything about the persistence mechanism used.
The DAO manager's job is to hide this information from its clients.

True, the application code does need to provide the implementation of the
Abstract Factory and an implementation of the DAO manager.  However, since
the DAO manager is an abstract class, its clients can rely only on the API
of the DAO manager rather than relying on the API of the underlying
persistence mechanism.  Thus the clients of the DAO manager need not know
anything about the persistence mechanism being used.  So even though the
application does have to specify what persistence mechanism is used and how
to interact with that mechanism, that definition is in *one place* which
means that it can be changed if need be without impacting the business
objects.

> In other words, who orchestrates the interaction of business and dao
> classes?  Does the action instantiate a business class and populate it
from
> your ActionForm, then get a dao instance from a factory, and pass it the
> business class?  Or is there another pattern to this?

The exact interactions among the components of course depend on the business
rules.  A typical use case is that the Action class creates a few DAOs based
on information in the request and then passes those DAOs to one of the
business objects.  The business objects may in turn retrieve other DAOs,
create DAOs, or even return DAOs to the Action class for further processing
by another business object.

Well that was rather long-winded... did I answer your question or go off on
a useless tangent? ;)

Matt


---------------------------------------------------------------------
To unsubscribe, e-mail: struts-user-unsubscribe@jakarta.apache.org
For additional commands, e-mail: struts-user-help@jakarta.apache.org


Re: Keeping Actions clean - separating actions from business model from persistence

Posted by Sasha Borodin <sa...@whoissasha.com>.
Matt, thanks for your quick feedback.

> I use my own framework because I don't know any better.
> 
> public abstract class DaoManager {
> public abstract IRecordDao createDao(Connection conn, String daoClassName)
> throws DaoException;

Which tier calls your DaoManager?  It seems from your code that the caller
of DaoManager is responsible to knowing the database configuration
information, as well as the implementing DAO class.  Is it the Action?

In other words, who orchestrates the interaction of business and dao
classes?  Does the action instantiate a business class and populate it from
your ActionForm, then get a dao instance from a factory, and pass it the
business class?  Or is there another pattern to this?

Thanks.

> Matt

-Sasha

> ----- Original Message -----
> From: "Sasha Borodin" <sa...@whoissasha.com>
> To: "Struts Users Mailing List" <st...@jakarta.apache.org>
> Sent: Friday, October 10, 2003 6:44 PM
> Subject: Keeping Actions clean - separating actions from business modelfrom
> persistence
> 
> 
>> Ted, Matt, Joe, and all the other helpful folks that chimed in earlier on
>> persistence mechanisms:
>> 
>> In trying to keep with best practices, I've managed to remove all "model"
>> related code (business logic, and persistence) out of the Actions'
> execute()
>> method.  Now I'd like to take it one step further and decouple the
> business
>> model classes from the implementing persistence technology (btw, settled
> on
>> OJB for now :).  From Joe's post, it seems like the DAO pattern is called
>> for to accomplish this.
>> 
>> My (slightly off topic) question is this:  who develops their own DAO
>> framework (like the dao and dao factory interfaces), and who uses a 3rd
>> party framework (like iBATIS's Database Layer) and why?  There was
> something
>> mentioned about the discovery of the persistence mechanism as well...
>> 
>> Any references to webpages/books would be appreciated.
>> 
>> BTW, I've been shamelessly posting to this list questions that are
> probably
>> better directed elsewhere.  What would be a more appropriate list?
>> 
>> Thank you,
>> 
>> -Sasha
>> 
>> 
>> ---------------------------------------------------------------------
>> To unsubscribe, e-mail: struts-user-unsubscribe@jakarta.apache.org
>> For additional commands, e-mail: struts-user-help@jakarta.apache.org
>> 
> 
> 
> ---------------------------------------------------------------------
> To unsubscribe, e-mail: struts-user-unsubscribe@jakarta.apache.org
> For additional commands, e-mail: struts-user-help@jakarta.apache.org


---------------------------------------------------------------------
To unsubscribe, e-mail: struts-user-unsubscribe@jakarta.apache.org
For additional commands, e-mail: struts-user-help@jakarta.apache.org