7 Replies Latest reply on Aug 18, 2008 3:23 PM by Peter Johnson

    SLSB basic design question

    Ivan B Novice

      Hi,

      There is an SLSB.
      It has a facade method.
      Which calls private methods of the same SLSB.

      How can I pass parameters to those private methods? Via method declaration?
      Or can I use private fields? Like that:

      public class SLSB {
      
      int v1;
      
      void facade(int var) {
       v1 = var;
       call_internal();
      }
      
      void call_internal() {
       use(v1);
      }
      }
      


      Which way is preferred?
      Thanks,



        • 1. Re: SLSB basic design question
          Peter Johnson Master

          Always pass values as method parameters - do not use fields. With an SLSB multiple threads can be using it simultaneously and if you use a field you will get "interesting" results.

          • 2. Re: SLSB basic design question
            Ivan B Novice

             

            "PeterJ" wrote:
            With an SLSB multiple threads can be using it simultaneously


            Huh???
            What about SLSB pools then? I was sure that a thread takes SLSB instance from the POOL, executes it and returns it back for later use. Never two threads execute on the same SLSB instance.

            • 3. Re: SLSB basic design question
              Andrew Rubinger Master

              Peter is right, though for the wrong reason. :)

              SLSBs *do* have state, as the instance is returned to the Pool after use. Therefore invocation-specific data should not be kept in instance members of a SLSB. For SFSB this is acceptable (and good practice) because it's guaranteed that every subsequent invocation upon a given proxy will invoke upon the same SFSB instance.

              However, EJBs are Thread-safe - no two invocations will use the same instance concurrently (by spec anyway):

              "EJB 3.0 Core Specification 4.7.11" wrote:
              The container must ensure that only one thread can be executing an instance at any time.


              S,
              ALR

              • 4. Re: SLSB basic design question
                Ivan B Novice

                 

                "ALRubinger" wrote:
                SLSBs *do* have state, as the instance is returned to the Pool after use. Therefore invocation-specific data should not be kept in instance members of a SLSB.


                Thanks, Andrew. This makes good sense. However, if I only run one single facade method, and previous old state doesn't bug me (all variables are re-initialized before used), can such "temporal" use of fields be justified?

                Imagine I have a chain of methods inside a SLSB.
                a calls b, b calls c, c calls d, etc.

                Facade method receives a parameter. I need to use that parameter down the chain of execution. Should I put that parameter in each method declaration? Ouch ... Doesn't look very appealing, don't you think?




                • 5. Re: SLSB basic design question
                  Andrew Rubinger Master

                   

                  "vanyatka" wrote:
                  ...if I only run one single facade method, and previous old state doesn't bug me (all variables are re-initialized before used), can such "temporal" use of fields be justified?


                  Sure, but you've set up a maintenance "gotcha" that is pretty easy to violate and will be difficult to debug. Also, you'll be less likely to see the inconsistencies exhibited in development, meaning it's likely that Peter's "weird stuff" will happen in Production. So as a general rule, I'd avoid this paradigm unless you can say:

                  1) There's no cleaner way
                  2) Document the hell out of it to make sure the instance var is cleansed upon each invocation

                  "vanyatka" wrote:
                  Imagine I have a chain of methods inside a SLSB.
                  a calls b, b calls c, c calls d, etc.

                  Facade method receives a parameter. I need to use that parameter down the chain of execution. Should I put that parameter in each method declaration? Ouch ... Doesn't look very appealing, don't you think


                  No, cluttered APIs are not pretty, though this approach *is* pretty foolproof.

                  You can also look into:

                  1) Store that parameter in a ThreadLocal
                  2) Each method looks to the ThreadLocal for the value
                  3) Apply an interceptor to, after invocation, clear the value of the ThreadLocal (as the Thread will also be returned to a pool).

                  S,
                  ALR



                  • 6. Re: SLSB basic design question
                    Ivan B Novice


                    Thanks for sharing your insights on this issue!

                    "ALRubinger" wrote:
                    Sure, but you've set up a maintenance "gotcha" that is pretty easy to violate and will be difficult to debug. Also, you'll be less likely to see the inconsistencies exhibited in development, meaning it's likely that Peter's "weird stuff" will happen in Production. So as a general rule, I'd avoid this paradigm


                    Agreed. I don't like it either. That's why I brought it up )


                    unless you can say:
                    1) There's no cleaner way


                    Before asking this question I thought of two, you introduced the third, and now I don't like any of them )


                    2) Document the hell out of it to make sure the instance var is cleansed upon each invocation


                    Good point.


                    No, cluttered APIs are not pretty, though this approach *is* pretty foolproof.

                    Ugly or fragile? That is the question.



                    You can also look into:
                    1) Store that parameter in a ThreadLocal
                    2) Each method looks to the ThreadLocal for the value
                    3) Apply an interceptor to, after invocation, clear the value of the ThreadLocal (as the Thread will also be returned to a pool).


                    Looks kinda the same as our discussed approach, only you have to clean a single variable. To make sure that variables are "clean" I can devote a special init() method for that, and call it each time inside my business methods.


                    • 7. Re: SLSB basic design question
                      Peter Johnson Master

                      Of course an alternate approach is to go back to what was done with EJB 2.x to support unittestability - place all of the methods into another object, and make the SLSB a mere facade for that object. Then each SLSB method would look like:

                      void doSomething(int var) {
                      new RealObject(var).doSomething()
                      }

                      Unfortunately, this approach generates unneeded garbage.

                      Personally, I vote for passing the values along from method to method. Less chance of unintentional bugs later on.

                      And besides, by adding fields (whose values change) to an SLSB you are in effect adding state to what should be a stateless object. And as Andrew pointed out, you will be bit by this during maintenance (most likely several months/years down the line when someone inadvertently assumes that the field actually hold real state, and not pseudo-state).

                      And besides, IDEs are pretty good about helping you manage method signatures. For example, say you wanted to add a second parameter to your facade method, and you dutifully add the parameter to the call_internal method invocation - Eclipse will flag the method call and provide suggested changes, including adding the parameter to the call_internal method.