7

Hi Stackoverflow community,

I am working on some code where a list of optional criterias criterias is submitted to my dao. Method signature contains the list of +/- 10 parameters, which I really don't like and want to reformat. Plus I would like to avoid having to refactor all method signatures from different layers just because I add/remove a criteria

List searchParams(String name, Long countryCode, ...){
...
}

would become

List searchParams(HashMap<String,Object> map) {
    BeanUtils.populate(this,map);
    ...
}

I am a bit worried that this happen to because kind of a bad practice, because I give up control of what is passed in the map to give me that flexibility ? So my question is if I am on the right path proceeding that way?

Jako
  • 944
  • 14
  • 33

4 Answers4

14

When I encounter situations like this, I tend to create a Params class, and pass that around. The benefits are that:

  • unlike when using a Map, you can have meaningful getters/settings, proper validation etc;
  • it's type-safe and self-describing (meaning it's easy to find out the available parameters and their types).
  • you can add new parameters without having to refactor any intermediate layers.
NPE
  • 486,780
  • 108
  • 951
  • 1,012
2

You could define a new class to hold/handle your set of parameters, so you get a bit more control than a HashMap would give you. Annoying to write, or at least tedious, but seems like a better balance between flexibility & control.

Scott Hunter
  • 48,888
  • 12
  • 60
  • 101
2

You could look at your parameters and see if you can wrap them as a logical group into an object. For example a name an a country code could be a person object

public Person {
    private String name;
    private String countryCode;
}

Then you will just be passing this object down and can use getters to get the data out which should be easier to read and maintain than needing to know all the keys for the HashMap on multiple layers.

n00begon
  • 3,503
  • 3
  • 29
  • 42
2

The only case where using a map is appropriate is when you are designing a factory, and you need to pass different kinds of parameters to different classes being created. In all other cases, a solution with a specialized parameter info class would be preferred.

For an example of where passing a map is appropriate, look at the DriverManager.getConnection method: this method needs to pass parameters to constructors of driver-specific implementations of the Connection being created, so it wraps a map into Properties, and lets the user pass it through to the driver-specific connection. Note that DriverManager does not have another solution that would be future-proof.

I would strongly discourage using a map in all other cases: the added flexibility shifts error detection from compile-time to run-time, which has a strong potential of multiplying your headache beyond belief.

Sergey Kalinichenko
  • 714,442
  • 84
  • 1,110
  • 1,523