You are viewing a plain text version of this content. The canonical link for it is here.
Posted to user@struts.apache.org by Paul Barry <pa...@nyu.edu> on 2004/04/15 19:13:12 UTC

Struts, Business Logic, DAOs

I have a question about business logic.  The best way I can think to 
explain this is with an example.  I know this is kind of long, but I am 
trying to keep this as simple as possible while still being able to 
illustrate the point.  Let's say I have Users and Widgets.  I would have 
Business Objects for each one, something like this:

public User {
   public int getId();
   public boolean isAdmin();
}

public Widget {
   public int getId();
   public User getCreator();
}

Now assume I am using a DAO like this:

public WidgetDAO {
   public void delete(int id);
}

Assume the implementation of this DAO would delete a row from the widget 
table in the database.  So using struts I would have an action with a 
method like this:

execute(...) {
     WidgetDAO.delete(widgetId);
}

Assume the widgetId came from an ActionForm, the details are irrelevant. 
  The point is this would all work fine, you could call the action with 
a URL like /deleteWidget.do?widgetId=4 and it would delete widget 4. 
Also, assume there is other logic already handling logging in the user 
so there is a UserBO object in a session attribute, which is used to 
populate the creator property of the Widget.

But now let's say I have 2 business rules:

1.  users that are admins can delete any widget
2.  non-admin users can only delete widgets they created

So specifically from the objects above, you can delete a widget if 
user.isAdmin() returns true or widget.getCreator().getId() == 
user.getId().  The question is where should this kind of logic go?

You could get away with putting it in the action, but in a real world 
application this type of logic would be much more complicated and 
probably get re-used across different actions.  The Struts guidelines 
even say this:

"Rather than creating overly complex Action classes, it is generally a 
good practice to move most of the persistence, and "business logic" to a 
separate application layer. When an Action class becomes lengthy and 
procedural, it may be a good time to refactor your application 
architecture and move some of this logic to another conceptual layer; 
otherwise, you may be left with an inflexible application which can only 
be accessed in a web-application environment."

http://jakarta.apache.org/struts/userGuide/building_controller.html#action_classes

I doesn't seem like this logic belongs in the DAO either, because if you 
  don't want that kind of logic mixed in with code to get the data out 
of the database.  Does it belong in the business objects, maybe by 
expanding the Widget object like this?

public Widget {
   public int getId();
   public User getCreator();
   public boolean canDelete(UserBO);
}

And then canDelete would in turn call a DAO to check that?  Or would a 
separate layer be better, like this:

public WidgetLogic {
     public boolean canDeleteWidget(User, Widget);
}


Are there any best practices or sample applications that you know of 
that have a good example of a business logic layer?











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


Re: Struts, Business Logic, DAOs

Posted by Erik Price <er...@mac.com>.
On Apr 15, 2004, at 1:13 PM, Paul Barry wrote:

> I doesn't seem like this logic belongs in the DAO either, because if 
> you  don't want that kind of logic mixed in with code to get the data 
> out of the database.  Does it belong in the business objects, maybe by 
> expanding the Widget object like this?
>
> public Widget {
>   public int getId();
>   public User getCreator();
>   public boolean canDelete(UserBO);
> }

No way.

> And then canDelete would in turn call a DAO to check that?  Or would a 
> separate layer be better, like this:
>
> public WidgetLogic {
>     public boolean canDeleteWidget(User, Widget);
> }

That's better, but... if you're going to create a class that's 
dedicated to supporting a specific function, why not just have the 
class that performs the function encapsulate the details?  The 
following might be considered an implementation of the Command design 
pattern, and does pretty much the same thing but with less steps:

public class DeleteWidgetCommand {
   DeleteWidgetCommand() { }  // no-arg constructor
   void deleteWidget(User u, Widget w);
}

You could also pass the User into the constructor, but one of the nice 
things about having a relatively stateless class like the above is it 
gives you flexibility for pooling/caching etc if that's something you 
end up needing.  The actual connection between DeleteWidgetCommand and 
your persistence layer can be set up in a static initializer or static 
initializer block, assuming you can share a DeleteWidgetCommand object 
between clients.

This is not very different from using a session bean, but it avoids all 
that needless complexity if you're not already using EJB.  (See 
<http://www.corej2eepatterns.com/Patterns2ndEd/ServiceFacade.htm>.)  If 
your needs become more complex, you can refactor into a true service 
layer, which can keep the peanut butter out of your chocolate and the 
chocolate out of your peanut butter.


Just some ideas.  Good luck.



-- 
Erik Price

<http://erikprice.com/>


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


Re: Struts, Business Logic, DAOs

Posted by Nathan Maves <Na...@Sun.COM>.
We have been using http://ibatis.com/ for both sql mapping and it DAO  
framework.  Might be worth it to check it out.  It has good examples of  
both DAO's and Service layers.

Nathan


On Apr 15, 2004, at 11:13 AM, Paul Barry wrote:

> I have a question about business logic.  The best way I can think to  
> explain this is with an example.  I know this is kind of long, but I  
> am trying to keep this as simple as possible while still being able to  
> illustrate the point.  Let's say I have Users and Widgets.  I would  
> have Business Objects for each one, something like this:
>
> public User {
>   public int getId();
>   public boolean isAdmin();
> }
>
> public Widget {
>   public int getId();
>   public User getCreator();
> }
>
> Now assume I am using a DAO like this:
>
> public WidgetDAO {
>   public void delete(int id);
> }
>
> Assume the implementation of this DAO would delete a row from the  
> widget table in the database.  So using struts I would have an action  
> with a method like this:
>
> execute(...) {
>     WidgetDAO.delete(widgetId);
> }
>
> Assume the widgetId came from an ActionForm, the details are  
> irrelevant.  The point is this would all work fine, you could call the  
> action with a URL like /deleteWidget.do?widgetId=4 and it would delete  
> widget 4. Also, assume there is other logic already handling logging  
> in the user so there is a UserBO object in a session attribute, which  
> is used to populate the creator property of the Widget.
>
> But now let's say I have 2 business rules:
>
> 1.  users that are admins can delete any widget
> 2.  non-admin users can only delete widgets they created
>
> So specifically from the objects above, you can delete a widget if  
> user.isAdmin() returns true or widget.getCreator().getId() ==  
> user.getId().  The question is where should this kind of logic go?
>
> You could get away with putting it in the action, but in a real world  
> application this type of logic would be much more complicated and  
> probably get re-used across different actions.  The Struts guidelines  
> even say this:
>
> "Rather than creating overly complex Action classes, it is generally a  
> good practice to move most of the persistence, and "business logic" to  
> a separate application layer. When an Action class becomes lengthy and  
> procedural, it may be a good time to refactor your application  
> architecture and move some of this logic to another conceptual layer;  
> otherwise, you may be left with an inflexible application which can  
> only be accessed in a web-application environment."
>
> http://jakarta.apache.org/struts/userGuide/ 
> building_controller.html#action_classes
>
> I doesn't seem like this logic belongs in the DAO either, because if  
> you  don't want that kind of logic mixed in with code to get the data  
> out of the database.  Does it belong in the business objects, maybe by  
> expanding the Widget object like this?
>
> public Widget {
>   public int getId();
>   public User getCreator();
>   public boolean canDelete(UserBO);
> }
>
> And then canDelete would in turn call a DAO to check that?  Or would a  
> separate layer be better, like this:
>
> public WidgetLogic {
>     public boolean canDeleteWidget(User, Widget);
> }
>
>
> Are there any best practices or sample applications that you know of  
> that have a good example of a business logic layer?
>
>
>
>
>
>
>
>
>
>
>
> ---------------------------------------------------------------------
> To unsubscribe, e-mail: user-unsubscribe@struts.apache.org
> For additional commands, e-mail: user-help@struts.apache.org
>


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


Re: Struts, Business Logic, DAOs

Posted by Sergiusz Jarczyk <se...@qresc.com>.
Hi
I'm not sure if this follows the 'best practices' (for me it do) and what
kind of RDBMS you're using, but the best place for such a logic is a
database itself. Using stored procedures, you can code such a checking and
validation on the table level, and avoid code overhead.

Sergiusz


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


Re: Struts, Business Logic, DAOs

Posted by Shyam A <st...@yahoo.com>.
I'm not sure about the best practice,but I would use
an application specific Controller
(Controller/Mediator pattern)class to perform the
logic. I use a controller class for all related
operations in use case(s) /subsystem.It controls all
interactions between the UI and business layers.
In my Action class, I would call the method in my
controller class, which in turn calls the DAO method.
eg.
in Action class

widgetController.deleteWidget(user,widget);

in WidgetController class,
//logic for checking user type and issuing delete...
......
widgetDAO.deleteWidget(widget);

HTH,
Shyam



--- Paul Barry <pa...@nyu.edu> wrote:
> I have a question about business logic.  The best
> way I can think to 
> explain this is with an example.  I know this is
> kind of long, but I am 
> trying to keep this as simple as possible while
> still being able to 
> illustrate the point.  Let's say I have Users and
> Widgets.  I would have 
> Business Objects for each one, something like this:
> 
> public User {
>    public int getId();
>    public boolean isAdmin();
> }
> 
> public Widget {
>    public int getId();
>    public User getCreator();
> }
> 
> Now assume I am using a DAO like this:
> 
> public WidgetDAO {
>    public void delete(int id);
> }
> 
> Assume the implementation of this DAO would delete a
> row from the widget 
> table in the database.  So using struts I would have
> an action with a 
> method like this:
> 
> execute(...) {
>      WidgetDAO.delete(widgetId);
> }
> 
> Assume the widgetId came from an ActionForm, the
> details are irrelevant. 
>   The point is this would all work fine, you could
> call the action with 
> a URL like /deleteWidget.do?widgetId=4 and it would
> delete widget 4. 
> Also, assume there is other logic already handling
> logging in the user 
> so there is a UserBO object in a session attribute,
> which is used to 
> populate the creator property of the Widget.
> 
> But now let's say I have 2 business rules:
> 
> 1.  users that are admins can delete any widget
> 2.  non-admin users can only delete widgets they
> created
> 
> So specifically from the objects above, you can
> delete a widget if 
> user.isAdmin() returns true or
> widget.getCreator().getId() == 
> user.getId().  The question is where should this
> kind of logic go?
> 
> You could get away with putting it in the action,
> but in a real world 
> application this type of logic would be much more
> complicated and 
> probably get re-used across different actions.  The
> Struts guidelines 
> even say this:
> 
> "Rather than creating overly complex Action classes,
> it is generally a 
> good practice to move most of the persistence, and
> "business logic" to a 
> separate application layer. When an Action class
> becomes lengthy and 
> procedural, it may be a good time to refactor your
> application 
> architecture and move some of this logic to another
> conceptual layer; 
> otherwise, you may be left with an inflexible
> application which can only 
> be accessed in a web-application environment."
> 
>
http://jakarta.apache.org/struts/userGuide/building_controller.html#action_classes
> 
> I doesn't seem like this logic belongs in the DAO
> either, because if you 
>   don't want that kind of logic mixed in with code
> to get the data out 
> of the database.  Does it belong in the business
> objects, maybe by 
> expanding the Widget object like this?
> 
> public Widget {
>    public int getId();
>    public User getCreator();
>    public boolean canDelete(UserBO);
> }
> 
> And then canDelete would in turn call a DAO to check
> that?  Or would a 
> separate layer be better, like this:
> 
> public WidgetLogic {
>      public boolean canDeleteWidget(User, Widget);
> }
> 
> 
> Are there any best practices or sample applications
> that you know of 
> that have a good example of a business logic layer?
> 
> 
> 
> 
> 
> 
> 
> 
> 
> 
> 
>
---------------------------------------------------------------------
> To unsubscribe, e-mail:
> user-unsubscribe@struts.apache.org
> For additional commands, e-mail:
> user-help@struts.apache.org
> 



	
		
__________________________________
Do you Yahoo!?
Yahoo! Tax Center - File online by April 15th
http://taxes.yahoo.com/filing.html

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


RE: Struts, Business Logic, DAOs

Posted by Robert Taylor <rt...@mulework.com>.
Take at look at:
http://www.corej2eepatterns.com/Patterns2ndEd/PatternRelationships.htm

More specifically the Application Service pattern
http://www.corej2eepatterns.com/Patterns2ndEd/ApplicationService.htm

BTW, its a great book!

robert

> -----Original Message-----
> From: Paul Barry [mailto:paul.barry@nyu.edu]
> Sent: Thursday, April 15, 2004 1:13 PM
> To: user@struts.apache.org
> Subject: Struts, Business Logic, DAOs
> 
> 
> I have a question about business logic.  The best way I can think to 
> explain this is with an example.  I know this is kind of long, but I am 
> trying to keep this as simple as possible while still being able to 
> illustrate the point.  Let's say I have Users and Widgets.  I would have 
> Business Objects for each one, something like this:
> 
> public User {
>    public int getId();
>    public boolean isAdmin();
> }
> 
> public Widget {
>    public int getId();
>    public User getCreator();
> }
> 
> Now assume I am using a DAO like this:
> 
> public WidgetDAO {
>    public void delete(int id);
> }
> 
> Assume the implementation of this DAO would delete a row from the widget 
> table in the database.  So using struts I would have an action with a 
> method like this:
> 
> execute(...) {
>      WidgetDAO.delete(widgetId);
> }
> 
> Assume the widgetId came from an ActionForm, the details are irrelevant. 
>   The point is this would all work fine, you could call the action with 
> a URL like /deleteWidget.do?widgetId=4 and it would delete widget 4. 
> Also, assume there is other logic already handling logging in the user 
> so there is a UserBO object in a session attribute, which is used to 
> populate the creator property of the Widget.
> 
> But now let's say I have 2 business rules:
> 
> 1.  users that are admins can delete any widget
> 2.  non-admin users can only delete widgets they created
> 
> So specifically from the objects above, you can delete a widget if 
> user.isAdmin() returns true or widget.getCreator().getId() == 
> user.getId().  The question is where should this kind of logic go?
> 
> You could get away with putting it in the action, but in a real world 
> application this type of logic would be much more complicated and 
> probably get re-used across different actions.  The Struts guidelines 
> even say this:
> 
> "Rather than creating overly complex Action classes, it is generally a 
> good practice to move most of the persistence, and "business logic" to a 
> separate application layer. When an Action class becomes lengthy and 
> procedural, it may be a good time to refactor your application 
> architecture and move some of this logic to another conceptual layer; 
> otherwise, you may be left with an inflexible application which can only 
> be accessed in a web-application environment."
> 
> http://jakarta.apache.org/struts/userGuide/building_controller.html#action_classes
> 
> I doesn't seem like this logic belongs in the DAO either, because if you 
>   don't want that kind of logic mixed in with code to get the data out 
> of the database.  Does it belong in the business objects, maybe by 
> expanding the Widget object like this?
> 
> public Widget {
>    public int getId();
>    public User getCreator();
>    public boolean canDelete(UserBO);
> }
> 
> And then canDelete would in turn call a DAO to check that?  Or would a 
> separate layer be better, like this:
> 
> public WidgetLogic {
>      public boolean canDeleteWidget(User, Widget);
> }
> 
> 
> Are there any best practices or sample applications that you know of 
> that have a good example of a business logic layer?
> 
> 
> 
> 
> 
> 
> 
> 
> 
> 
> 
> ---------------------------------------------------------------------
> To unsubscribe, e-mail: user-unsubscribe@struts.apache.org
> For additional commands, e-mail: user-help@struts.apache.org
> 

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