-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);
    }
};
0x10
  • 7

2 Answers2

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 Pringle
  • 2,975
  • 1
  • 11
  • 15
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.

Christophe
  • 81,699