Search code examples
javascriptfunctional-programmingreusability

How to make a function's code more reusable


I want to make my functions more reusable, but I don't know how(and ask for your guidance).

Say I have something like that:

function One() {
  // code...
  // lot's of code...
  const doSomething = magic.sayWhat(); // or anything else
  // other code...
  // lot's of other code...
  return something;
}

function Two() {
  // code...
  // lot's of code...
  const doSomething = magic.sayWho(); // Here is a change. This change can be a bit more than that, but it's a fraction compared to all the rest of the code in function. It's the same as in function `One` except this piece of code.
  // other code...
  // lot's of other code...
  return something;
}

Can I make maybe somehow another, sort of a parent function that will include the general, common code and somehow wrap the changeable code? And yes, I know I can pass some params into the function and based on that make something with the if else, but I don't like this approach in this case. Any ideas?

Update:

Did my best to provide a mimic of what I'm actually doing:

function myLameAssFunction(someArg1, someArg2) {
  let gettingSomethingFromService1 = callService1(someArg1);
  let gettingSomethingFromService2 = callService2(someArg1);

  // code, code, code...

  unextractableFunction(() => {
    let somethingFromExternalLibrary = magicLibrary.do.magic();
  
    const doSomething = async () => {
      try {
        const someData = await magicLibrary.sayWhat(someArg2, gettingSomethingFromService1, somethingFromExternalLibrary);
        gettingSomethingFromService2(someData);
      } catch(err) {
        // whatever
      }
    }
  });

  // code, code, code...
  
  return gettingSomethingFromService2;
}

The only part that needed to change is the way I call/receive someData


Solution

  • Fundamentally, you can parameterize the function so you pass in something that does the bit that differs, or you can abstract the first and second bits into functions that you reuse.

    Parameterizing:

    function unified(operation) {
        // code...
        // lots of code...
        const doSomething = operation(); // ***
        // other code...
        // lots of other code...
        return something;
    }
    
    function One() {
        return unified(() => magic.sayWhat());
    }
    
    function Two() {
        return unified(() => magic.sayWho());
    }
    

    Aabstracting:

    function theFirstBit() {
        // code...
        // lots of code...
    }
    
    function theSecondBit() {
        // other code...
        // lots of other code...
    }
    
    function One() {
        theFirstBit();
        const doSomething = magic.sayWhat();
        theSecondBit();
        return something; // This might have come from one of the bits above
    }
    
    function Two() {
        theFirstBit();
        const doSomething = magic.sayWho();
        theSecondBit();
        return something; // This might have come from one of the bits above
    }
    

    Re your edit:

    The only part that needed to change is the way I call/receive someData

    That's a use case for parameterizing:

    function myLameAssFunction(someArg1, someArg2, getSomeData) {
    // *** −−−−−−−−−−−−−−−−−−−−−−−−−−−−−−−−−−−−−−−−^
      let gettingSomethingFromService1 = callService1(someArg1);
      let gettingSomethingFromService2 = callService2(someArg1);
    
      // code, code, code...
    
      unextractableFunction(() => {
        let somethingFromExternalLibrary = magicLibrary.do.magic();
      
        const doSomething = async () => {
          try {
            const someData = await getSomeData();
    // *** −−−−−−−−−−−−−−−−−−−−−−−−^
            gettingSomethingFromService2(someData);
          } catch(err) {
            // whatever
          }
        }
      });
    
      // code, code, code...
      
      return gettingSomethingFromService2;
    }