-1

I have a serious problem with application which i working on. It has a lot of procedural code and now it needs to refactoring now.. The problem: we have two different application in general, but they're use the same "module", concrete functions from this module. It looks like this: (pseudocode)

// general application
class App1 {
    DoSomething();
}

class App2 {
    DoSomething();
}

// "module":
a;
b;
c;

function DoSomething {
  if (App1) {
    // working with a, b here
  }

  if (App2) {
    // working with a, c here
  }
}

Note that "DoSomething" function gets "a", "b", "c" from outside. Also, this "DoSomething" may call another function inside itself, "DoSomething 2" for example..

This if statements aka "if App1 then, else if it App2 then.." scattered by the all the code, and it becomes the problem. Furthermore, count of this Application will may increase in the future (

What a better way to resolve this problem? Please, can you give an advice, what patterns/approaches may helps here?


UPDATE

This is real examples from the code, but all names was replaced with fake names:

situation one - "helpers.js"

import { isApp1 } from '../../..';
import { constTypes } from '../../../../someAnotherHelpers';
import { constSybtypes } from '../../someAnotherHelpersTwo';

const App1Constants = {
  [constTypes.a]: { .. },
  [constTypes.b]: {
    [constSybtypes.b.a]: 33,
  },
};

const App2Constants = {
  [constTypes.c]: 22,
};

const getConstants = isApp1()
  ? App1Constants
  : App2Constants;

situation two - "some react class"

import { isApp1 } ...;

class Test {
  const className = isApp1 ? 'object_app1' : 'object_app2';

  render() {
    <div className={className}>
      ...
    </div>
  }
}

situation three - "selector.js" (used everywhere..)

import { isApp1 } ...;
import { someAnotherSelector } from '.';
import { someAnotherSelector2 } from '../../../anotherSelectors';

export const someSelector = 
  isApp1()
    ? (state) => { 
      return someAnotherSelector(state.someReducer.variant1);
    }
    : (state) => { 
      return someAnotherSelector2(state.someReducer.variant2);
    }
};
  • Possible duplicate of Style for control flow with validation checks – gnat Aug 6 '18 at 9:49
  • 1
    @gnat thanks! i don't think so, because in that question peoples talking about if statements inside one single function. in my situation i need to decision as global architecture remading – 0x10 Aug 6 '18 at 10:06
  • 4
    The usual advice is to turn the functions into class methods and use dynamic dispatch so that each object automatically does the appropriate thing for its class. Is that possible in your language? – Kilian Foth Aug 6 '18 at 10:38
  • 1
    The example code here is a bit vague, it's hard to come up with a one-size-fits-all solution to this. One way to approach is to resolve the differences using inheritance. However, this is overkill and possibly counterproductive in other cases, so I'm apprehensive about suggesting it without further context. Can you give us more information: language used, scope of the application, scope of the issue, how many variations exist (app1/app2/... variations and a/b/c/... variations), a meaningful description of the purpose and differences between app1/app2/a/b/c/... ? – Flater Aug 6 '18 at 10:58
  • 1
    Why can't the apps call different methods? For example, App1 could call DoSomething and App2 could call DoSomethingElse. There is no need for the module to detect which app is the caller if the app is calling the appropriate method, and obviously the app knows which app it is so it knows which method to call. – John Wu Aug 6 '18 at 21:00
2

This is a classic case where you need to use some form of genericity (generic programming). Which sort of generic programming to select depends on the language you are using, and the details (which you abstracted too much to be useful).

But briefly, the obvious forms of genericy to use include:

  • inheritance/interfaces
  • macros / templates

Macros or templates are similar, and which is available to you depends on language choice. inheritance/interfaces is probably the most useful form of generic programming, and is available in most languages.

inheritance:

If your code is filled with things like

  if (typeof object) == A) {
    do this
  }
  else if (typeof object) == B) {
    do that.
  }

this is a classic opportunity for object orientation (interface/based programming).

Define an interface (details very language specific)

interface PutGoodNameHereForWhatSortsOfThingsTheseDo { virtual void Method (); // need GOOD NAME HERE TOO }

ObjectA, and ObjectB inherit (that maybe App1, and App2 in your example?) and provide the appropriate override of Method().

Then you write your code as:

object->Method(); // losing all the iffs and type checks

templates/macros:

Instead, if you have patterns in your code that repeat themselves, but have no obvious inheritance relationship like above, and IF your language supports templates (like java, or C++), you can try:

template<typename A, typename B> 
void DoSomething (A a, B b)
{
  if (a == 1) {
    print "hello";
  }
  if (b != a) {
     print "bye";
  }
}
int X;
double Y;
char Z;
DoSomething (X, Y);
DoSomething  (Y, Z);
...
  • Lewis, thank you. unfortunately, my language (it's a javascript) don't supports generics. It may possible in just Typescript, but we're don't use this stuff. your examples are logically right, but.. Let's pretend that we're in Java world. if you have a big code base with this App1 statements, and more-more business logic that's depends on this statements, can you painlessly translate all of this to generics? – 0x10 Aug 7 '18 at 8:45
  • So which case is right? In javascript, you can do inheritance - just not templates/macros. Note - as you say - you CAN do generics in typescript - typescriptlang.org/docs/handbook/generics.html @0x10 – Lewis Pringle Aug 7 '18 at 13:56
1

Sounds a good candidate for the template method pattern. Depending on the broader context, you could also consider the strategy pattern.

Here an example of how to implement the template method in javascript.

  • thank you for your answer! i read about "template method", and i 100% agree with this approach, but.. i have a dependencies inside this functions which used by Applications. this dependencies are different (not have some logic), links to different external places (another functions, heplers, consts variables, etc.). a bit later i will update my question by concrete examples (it's a javascirpt lang), and i invite you to read this) – 0x10 Aug 6 '18 at 12:26

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service, privacy policy and cookie policy

Not the answer you're looking for? Browse other questions tagged or ask your own question.