4 Replies Latest reply on Mar 29, 2007 3:30 PM by cingram

    Stop the violence! How should we be separating our beans?

      Our developers are getting ready to come to blows.

      How should we be separating our session beans? Is the preferred method for application design in seam to have 1 ejb for the Action Listener and another to contain the actual business methods, refer to ex 1? Or should we just combine the 2 beans in to 1 refer to ex 2.

      ex 1.

      @Stateful
      @Name("addressmanager")
      public class AddressManagerBean implements AddressManager {
      
       @In
       private Address address;
      
       //..some other business methods.
      
       public boolean allowAddressChange() {
       //perform some sort of rules check.
      
       return rulecheck.checkAddressRules();
       }
      }
      
      
      @Stateful
      @Name("addressmanageraction")
      public class AddressManagerActionBean implements AddressManagerAction {
      
       @In
       private Address address;
      
       @In
       private AddressManager addressManager;
      
       @In
       private FacesMessages facesMessages;
      
       //..some other business methods.
      
       public void checkifAllowAddressChange() {
       if ( ! addressManager.allowAddressChange()) {
       facesMessages.addToControl("FailedAddressChangeRuleCheck", "The addrress can not be changed.");
       }
       }
      }
      
      //The pages.xml or .jpdl.xml file would contain the navigation rules.
      


      ex 2.
      @Stateful
      @Name("addressmanager")
      public class AddressManagerBean implements AddressManager {
      
       @In
       private Address address;
      
       @In
       private FacesMessages facesMessages;
      
       //..some other business methods.
      
       public boolean checkifAllowAddressChange() {
      
       boolean allowAddressChange rulecheck.checkAddressRules(); //This could maybe be replaced by Drools
      
      
       if ( ! allowAddressChange()) {
       facesMessages.addToControl("FailedAddressChangeRuleCheck", "The addrress can not be changed.");
       }
      
       return allowAddressChange();
       }
      }
      
      // The pages.xml or .jpdl.xml file would contain the navigation rules.
      



        • 1. Re: Stop the violence! How should we be separating our beans
          gavin.king

          Ahem, there's no right or wrong way.

          Option 2 has the (big) advantage that it requires less code.

          Option 1 has the advantage that the business logic is not coupled to FacesMessages, which means that it would be reusable as a WS or whatever.

          So it really depends on asking yourself the question: "how likely is it that I'm going to need to use this functionality from something other than JSF in the next 6 months?"

          And, or course, that's often a very difficult problem to answer. However, if you don't have a great answer, notice that with modern refactoring tools, it is really not that difficult to get from 2 to 1 if and when you need to do it. In fact, its only arguable that there is less work to do 1 immediately rather than do 2 now and then refactor to get to 1 (if and when you need it).

          I strongly believe that it's usually much more important to get *working functionality now*, than it is to plan for stuff that might or might not happen in 6 months or a year or two years. Deliver useful stuff ASAP, secure ongoing funding for your project, and ongoing cooperation, trust and feedback from your users. Then in 6 months time when you really need it, you'll be able to do the refactorings you really need, with a lot less pressure, and a lot more knowledge.

          BTW, there is always Option 3:

          <rule if="#{addressmanager.addressChangeAllowed}">
           <redirect view-id="/addressChanged.xhtml">
           <message>The address was changed.</message>
           </redirect>
          </rule>
          <rule if="#{not addressmanager.addressChangeAllowed}">
           <render view-id="/changeAddress.xhtml">
           <message>The address can not be changed.</message>
           </render>
          </rule>


          But I understand that this is not to all tastes ;-)


          • 2. Re: Stop the violence! How should we be separating our beans
            gavin.king

            I suppose I need to let you add a message to a control from pages.xml....

            Well, that's easy to implement....

            • 3. Re: Stop the violence! How should we be separating our beans
              gavin.king

              OK, in CVS, you can now do:

              <rule if="#{addressmanager.addressChangeAllowed}">
               <redirect view-id="/addressChanged.xhtml">
               <message>The address was changed.</message>
               </redirect>
              </rule>
              <rule if="#{not addressmanager.addressChangeAllowed}">
               <render view-id="/changeAddress.xhtml">
               <message for="FailedAddressChangeRuleCheck">The address can not be changed.</message>
               </render>
              </rule>


              • 4. Re: Stop the violence! How should we be separating our beans

                Wow! Thanks for the answer Gavin. That is exactly what I have been trying to get across to the developers here. With your code update, you did remove the last argument making option 3 in my opinion the best one.


                Thanks!