Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Design pattern for multiples methods using same argument

I have this class on which I have a method and will return a map, using dozens of methods inside it using the same arguments.

My class has thousand of lines and it will increase even more.

I can create several classes and inside create methods, but I´m asking if there is a special design for this scenario

Actual Scenario:

public Map<String, Object> transformMapOnAnotherMap(Map<String, Object> firstMap) {

   Map<String, Object> lastMap = new HashMap<String, Object>(firstMap);

   lastMap = do1(firstMap, lastMap);

   lastMap = do2(firstMap, lastMap);

   lastMap = do3(firstMap, lastMap);

   lastMap = do4(firstMap, lastMap);

   //more 20 methods

   return lastMap;

}

Try without design:

public Map<String, Object> transformMapOnAnotherMap(Map<String, Object> firstMap) {

    Map<String, Object> lastMap = new HashMap<String, Object>(firstMap);

    Do1 do1 = new Do1();
    lastMap = do1.do1(firstMap, lastMap);

    Do2 do2 = new Do2();
    lastMap = do2.do2(firstMap, lastMap);

    // more 20 methods

    return lastMap;

}
like image 231
Goldbones Avatar asked Dec 17 '25 13:12

Goldbones


2 Answers

If do1, etc., are just implementation, not part of the public interface of your class, it would probably make sense to create a private class (perhaps even a nested one) with a constructor accepting the two maps which it retains as instance variables:

private static class Worker {
    Worker(Map firstMap, Map secondMap) {
        this.firstMap = firstMap;
        this.secondMap = secondMap;
    }
    void do1() {
        // ...update `this.lastMap` if appropriate...
    }
    void do2() {
        // ...update `this.lastMap` if appropriate...
    }
}

There I've made Worker static so it's a static nested class, not an inner class, but it could be an inner class instead (no static) if you need access to the internals of the surrounding class.

Then

public Map<String, Object> transformMapOnAnotherMap(Map<String, Object> firstMap) {
     Worker worker = new Worker(firstMap, new HashMap<String, Object>(firstMap));
     worker.do1();
     worker.do2();
     worker.do3();
     worker.do4();
     //more 20 methods
     return worker.lastMap;
}
like image 180
T.J. Crowder Avatar answered Dec 20 '25 13:12

T.J. Crowder


You can use interface and make every "do" an implementation of functional interface.

interface Do {
    Map<String, Object> apply(Map<String, Object> firstMap, Map<String, Object> lastMap);
}

Then you can initialize static dos:

static Do[] allDos = {
    (firstMap, lastMap) -> {
        // do0
    },
    (firstMap, lastMap) -> {
        // do1
    },
    // ...do2, do3, ...
};

If you need to invoke do0 -> do2 -> do4 for example:

public Map<String, Object> transformMapOnAnotherMap(Map<String, Object> firstMap) {
    Map<String, Object> lastMap = new HashMap<String, Object>(firstMap);
    int[] ids = { 0, 2, 4 };
    for (int id : ids)
        lastMap = allDos[id].apply(firstMap, lastMap);
    return lastMap;
}
like image 40
zhh Avatar answered Dec 20 '25 11:12

zhh



Donate For Us

If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!