-1

This is more of a design question. How do I make a function perform different tasks depending on where is it being called from. For example

public doSomething(int a, int b) {
a=a+b; //line 1
b=a+b; //line 2
}

Now how do I make either line 1 or line 2 to execute depending of where the function doSomething is being called from. I would prefer not to pass any extra variables to the function, as this function is being used in a lot of places and it would mess up my existing code

Machavity
  • 30,841
  • 27
  • 92
  • 100
BrownTownCoder
  • 1,312
  • 5
  • 19
  • 25
  • "where the function doSomething is being called from" you mean class?? – Rod_Algonquin Jul 30 '14 at 04:03
  • yeah its a public function and is being called from two different functions of the same class. – BrownTownCoder Jul 30 '14 at 04:04
  • 3
    This is more of a design answer: change your design. You might think your proposal will be an easy fix, but it promises to become a maintenance nightmare very soon. [XY Problem](http://meta.stackexchange.com/questions/66377/what-is-the-xy-problem). If you really, *really* need it, [this answer](http://stackoverflow.com/a/421338/240443) describes what you need to do - but it is slow and I can't tell you enough how much I recommend against doing it. – Amadan Jul 30 '14 at 04:05

4 Answers4

2

You can't really make your method behave according to the context without

  1. Pass a parameter with context information to the method.
  2. Have the Class containing the method have a context object with the necessary information.
  3. Get the caller context information from somewhere like a cache etc.
Thihara
  • 7,031
  • 2
  • 29
  • 56
2

Generally, a function should do one thing and do it well.

It's conceivable that the one thing should be one of a selection but only if there's a lot of commonality.

The best way to do that is exactly the way you seem reticent to use, you pass more information on what to do.

Perhaps the problem we should be solving is your reticence or the proposed design :-)


If there is commonality and you're not willing to change the API because of the effect on current callers, there is another way.

Provide a new function to the new specification and change the old function to call it. For example, say you have a function to find the sum of two numbers:

def sum (a, b):
    return a + b

Now you want a new function that will either give you the sum or the difference and you don't want to change the current callers:

def sumOrDiff (type, a, b):
    if type == 'sum':
        return a + b
    return abs (a - b)

def sum (a, b):
    return sumOrDiff ('sum', a, b);

That way, you have the common code in one place (and I'd hope it's more complex than that) but without changing the calls already using it.

This is a well-worn method for making changes while keeping code simple, and not breaking backward compatibility.

Now that's a contrived example. In reality, I'd still provide a separate function for sum and difference. Your actual use case will hopefully make more sense.

paxdiablo
  • 854,327
  • 234
  • 1,573
  • 1,953
  • haha actually my boss doesn't like when I do that, i.e. passing a boolean value which tells the function what to do. – BrownTownCoder Jul 30 '14 at 04:08
  • And another reason is that that function is being used my numerous other modules, which I am not developing. So it will be headache for those programmers. I guess I will have to create a second function. – BrownTownCoder Jul 30 '14 at 04:10
  • @Ritwick, for once the boss may be right :-) Only do the boolean thing if the two actions have a lot in common. Otherwise, create a separate function. – paxdiablo Jul 30 '14 at 04:10
  • They do have a lot in common, everything but 1 line actually. The main issue is other developers are using that function too, and it will create ambiguity with them – BrownTownCoder Jul 30 '14 at 04:13
1

You could use this.

StackTraceElement[] stackTrace = Thread.currentThread().getStackTrace(); 


 for(StackTraceElement st : stackTrace){ // check st for further processing}

This will give you the stack trace. Depending upon the depth of your function call. You can check and have your condition accordingly.

Note: this has performance issue. I would recommend changing your design or use a boolean parameter in your function which decides the further flow.

Hope this solves your query.

Paras Mittal
  • 1,159
  • 8
  • 18
0

If I understand your question - one approach might be adding a field like count to your class,

private int count = 0;
public doSomething(int a, int b) {
  if (count == 0) {
    a=a+b; //line 1
  } else {
    b=a+b; //line 2
  }
  count++;
}

Obviously this only works directly when called line 1 then line 2. However, you could add something like

public void reset() {
  count = 0;
}

Of course this is just gluing context into your class - and it's probably easier to add a 3rd parameter overloaded method for "line 2" -

public void doSomething(int a, int b) {
  doSomething(a, b, 0);
}

public void doSomething(int a, int b, int c) {
  if (c == 0) {
    a=a+b; //line 1
  } else {
    b=a+b; //line 2
  }
}

And then you only have to change line 2 methods.

Elliott Frisch
  • 198,278
  • 20
  • 158
  • 249