Link to home
Start Free TrialLog in
Avatar of Jonah11
Jonah11

asked on

Design Question: Using Members To Share Data Between A Method and SubMethod?

Say we have a public method "method," which uses private "subMethod1" and private "subMethod2" in its calculation.  These subMethods serve no other purpose than to break down "method" into more readable, encapsulated sub-parts.  

We need each of these sub methods to operate on 2 or more primitive data types, which are local variables defined at the top of method.  We cannot pass them into the sub methods by reference, since java does not allow primitives to be passed by reference, and anyway passing an argument in to be altered is not a preferred design idiom.  

So our solution is to refactor, and change the local variables defined at the top of method to member variables, which can of course be read and written by both method and its sub-methods.  The problem (maybe it is a problem) is that now we have member variables that don't really exist to store object state, but only exist, effectively, during the execution of method.  Of course, in actuality they exist throughout the whole lifetime of the object, but they are only ever used during the execution of method, and they could vanish at other times without affecting the behavior of the object at all (keep in mind that method initializes the members to default values at the beginning of its method body).  

So something about that design feels wrong.  Is it?  If so, what is a better way to refactor?

Thanks,
Jonah
SOLUTION
Avatar of Valeri
Valeri
Flag of Bulgaria image

Link to home
membership
This solution is only available to members.
To access this solution, you must be a member of Experts Exchange.
Start Free Trial
So you can pass the primitive valiables to the subMethods "by reference". Just collect them into the Object (at the top of the Method) and pass the object to the subMethods.
Avatar of Jonah11
Jonah11

ASKER

Valeri,

This solution is not an option.  My method is used as part of a simulation (it will be run millions of times in a loop), and the creation of Objects as wrappers merely to pass the primitives back and forth will have too large of a performance hit.
Then create only one instance of such as Object, make it member variable of your Main Object and before calculations just reinitialize the variables in this Object which will be responsible for the calculations! And to make things more clear I think that will be good to move submethods to this Object, because they are used only for the calculations.
Avatar of Jonah11

ASKER

Are you suggesting I create an inner class to encapsulate the sub methods and the shared primitive data?  
Avatar of Jonah11

ASKER

Actually, it seems that you are not, so I don't see how your solution avoid the problem that mine does.  The member Object wrapping the primitives still serves no purpose other than sharing info between method and its sub-methods.  That is, the member object you propose is still not existing to save state for the main object, as you enthusiastically say it should: "Keep as a member variables only the variables that concerns the object state!"
Yes, something like that. But if you create it as a inner class whenever you instantiate the Main class, the inner class will be also instantiated. It shoud be static inner class. And it can be just different class and to be static in your MainClass in order to have only one instance of it.
Of course you have to be very careful with the static variables :-)
Also if your app is multithreading one you have to redesign using of this class. Then it shouldn't be static, but you have to have different instance of it per each one of the threads, because performance is very omportant.
Avatar of Jonah11

ASKER

I really don't see how creating a static inner class is answering the design problem I had in the OP, and the one that you shared when you said "Keep as a member variables only the variables that concerns the object state!"  Now we will just have a static inner class which exists merely to share information between methods of the parent class.  Why is that any better than having member variables for the same purpose?
Avatar of Jonah11

ASKER

Or would both method and its submethods (and the primitive data) all be static methods of the static inner class?  Then the public method of the parent class would just delegate to its static counterpart in the inner class?  I think that might work.....
>>My method is used as part of a simulation (it will be run millions of times in a loop), and the creation of Objects as wrappers merely to pass the primitives back and forth will have too large of a performance hit.
>>

can you try it really and then compare the performance hit? actually wrapping into an class is the nice follow of oops. what you think is the optimized code may not be optimized code for the compiler, the recommondation is write simple neat oops code and the compiler will optimize it for you!
- .. and the creation of Objects as wrappers merely to pass the primitives back and forth will have too large of a performance hit.

You can create this object only once and invoke its setters each time you need to return the data.
to Jonah11@33585042 : Yes, exactly
to ksivananth : It's very interesting! But I think that the compiler will not avoid instantiating of new Object again and again... and this will slow down the application?!?!
Avatar of Jonah11

ASKER

can you try it really and then compare the performance hit? actually  wrapping into an class is the nice follow of oops. what you think is the  optimized code may not be optimized code for the compiler, the  recommondation is write simple neat oops code and the compiler will  optimize it for you!

ksivananth:

too bad reality is not this simple.  I've attached a very simple (and silly) example that demonstrates the performance.  In this simple example using the pass by reference method with a wrapping object increases execution time by more than 50%.  


package scratch;


public class TestSharedMembers {
    
    protected int m17Multiples;
    protected int m23Multiples;
    
    public int methodPrimitive(int i) {
        
        m17Multiples = 0;
        m23Multiples = 0;
        
        calc17Primitive(i);
        calc23Primitive(i);
        
        return m17Multiples + m23Multiples;
    }
    
    private void calc17Primitive(int i) {
        if (i % 17 == 0) 
            m17Multiples++;
    }
    private void calc23Primitive(int i) {
        if (i % 23 == 0) 
            m23Multiples++;
    }
    
    
    class IntWrapper {
        private int mInt;
        public IntWrapper(int i) {
            mInt = i;
        }
        public int getInt() {
            return mInt;
        }
        public void increment() {
            mInt++;
        }
    }
    public int methodObject(int i) {
        
        IntWrapper o17 = new IntWrapper(0);
        IntWrapper o23 = new IntWrapper(0);
        
        calc17Object(i, o17);
        calc23Object(i, o23);
        
        return o17.getInt() + o23.getInt();
    }
    
    private void calc17Object(int i, IntWrapper o) {
        if (i % 17 == 0) 
            o.increment();
    }
    private void calc23Object(int i, IntWrapper o) {
        if (i % 23 == 0) 
            o.increment();
    }
    
    
    public static void main(String[] args) {
        TestSharedMembers t = new TestSharedMembers();
        final int NUM_ITERS = 20000000;
        
        double start = System.currentTimeMillis();
        int total = 0;
        for (int i=0; i<NUM_ITERS; i++) {
            total += t.methodPrimitive(i);
        }
        double stop = System.currentTimeMillis();
        System.out.println(total);
        System.out.println(stop - start);
        
        start = System.currentTimeMillis();
        total = 0;
        for (int i=0; i<NUM_ITERS; i++) {
            total += t.methodObject(i);
        }
        stop = System.currentTimeMillis();
        System.out.println(total);
        System.out.println(stop - start);
        
    }
}

Open in new window

Avatar of Jonah11

ASKER

Valeri,

I have been thinking about your solution some more, and I don't think a static inner class will work.  The problem is that method and sub-methods in question would need access to non-static members of the parent class.  

An instance class might work, in which case we could create an inner class called "MethodHelper" or something like that, which would exist only to house the implementation of method.

What do you think of that?
>>
I have been thinking about your solution some more, and I don't think a static inner class will work.  The problem is that method and sub-methods in question would need access to non-static members of the parent class.
>>
Yes, you are right! I didn't consider that.
>> An instance class might work...
Yes, I think so. If you define your non-static members of the parent class as protected you can access them directly in your instance class.
But it will not work in multithreading environment. Is your app multithreading one?
Avatar of Jonah11

ASKER

No, it won't be multithreaded.
ASKER CERTIFIED SOLUTION
Link to home
membership
This solution is only available to members.
To access this solution, you must be a member of Experts Exchange.
Start Free Trial
Avatar of Jonah11

ASKER

ksivananth:

I understand the importance of good OO design -- that is why I made this post.  There is no need to make that case to me.   I just happened to be facing a conflict here between good design and good performance.  I do appreciate your input though -- I think I can use your ideas above to get both things.

I just need to experiment a bit more to make sure I don't have any further questions.

Thanks for your help.
This question has been classified as abandoned and is closed as part of the Cleanup Program. See the recommendation for more details.