1

I need your help how to implement it nice and well. It's quite a simple problem. I can solve it but I need help on how to do that better.

My class has logic working using three parameters. It gets them from another class. The problem is:

  1. the first parameter is enum (it's required)

  2. the second parameter is another enum (it's optional - there is possibility that this parameter doesn't exist)

  3. the third parameter is vector of other enums (it's optional - there is possibility that this parameter doesn't exist).

How to handle these parameters to my class?

Any ideas?

I'd like to get these parameters in one method, e.g. updateParameters(...).

Maybe I should have overloaded methods for every possibility, but it's not nice I guess. I can't get some container with parameters because I have different types.

3
  • is there a reasonable default for the optional parameters? Jan 27, 2014 at 13:43
  • With optional enum parameter there is a problem. I can't use any of value. Every value means something so I can't use one of them. With vector I can use empty vector (I can interpreted it as vector doesn't exist) Jan 27, 2014 at 13:51
  • So... I think I can have two overladed methods. updateParameters(enum1 requiredParam, vec<enum2> v = vector<enum2>()) and updateParameters(enum1 requiredParam, vec<enum2> OptionalVec, enum3 OptionalParam)... I'm not sure if it is ok... :/ Jan 27, 2014 at 13:57

2 Answers 2

3

There are three sensible solutions here:

  1. You could pass them as parameters to your constructor, the first parameter being the required parameter, or..
  2. You could create getters and setters to provide these parameters afterwards, or..
  3. You could pass a map containing property values.

Passing to constructor

Passing to the constructor indicates that while optional, they must be made known immediately upon construction of the instance. If this is not your case, I would avoid it entirely since A) you may not immediately have that information upon initialization and B) you want to convey a class's usage as best as possible and thus there's no point to limit when it is not necessary.

Using getters and setters

For me at least, using getters and setters tells me that you're using an optional parameter. As such, I don't feel obliged to provide some value just to ensure that one is provided. This is best if these values are truly optional, however, and a parameter's default will work fine as is. If you think the caller would be better off setting it to something (despite being optional), then you should probably stick with passing to constructor.

Please note that you should only be prepared to use getters and setters if you're willing to allow changes at any point of an instance's usage. By this I mean that should you set parameters using a setter, call execute, then change that parameter later and call execute a second time, it should work as expected, using whatever value it is currently set to. If you cannot guarantee this, you should not use getters and setters (use passing to constructor method above).

Also, for what concerns your vector of enums, consider the possibility of adding a "add" method which takes a single enum value or a vector and adds it to its internal enum vector. This is also comfortable if you have one value so you don't have to create a vector simply to add new values.

Property map

A property map is a good idea if you see yourself having to serialize these values to a database or on a file somewhere. It is also handy if you think the properties passed may vary significantly. I generally prefer to avoid this method, however I tend to use it when I'm dealing with properties that my class doesn't have to be familiar with but are still important to subclasses. An example of this is if I were to instantiate a database connection and I don't need to know all the properties which may pertain to that particular connection.

Conclusion

I hope this gives you a start. Generally speaking, I try to use getters and setters for all optional parameters if I can. Anything which must be necessary immediately upon creation of a new instance (default or otherwise) absolutely has to be in the constructor.

You can also mix and match these techniques. The impression I give to the caller at that point would be a mix as well. In other words, if I put parameters in constructor and also provide setters and getters, the message I want to pass is "These parameters should be known immediately as they don't have suitable defaults, however you can later change them." If I use property map with getters and setters, the message I want to pass is "Some of these parameters are static and optional, while others are dynamic and may contain more information than this class can deal with."

Edit: I'm not sure what you mean by updateParameters. If all these parameters will potentially change from one moment to the next, then you should consider creating an entirely new instance each time. If only some parameters may change, then you can use getters and setters and change whichever parameters are different with respect to before.

3

As a rule of thumb when creating an enumeration, some value is left for NONE (usually 0). In cases similar to yours this value is passed in to indicate that no other value suites. Adding such value to your enums will solve the problem with optional parameters.

In case of vectors of enums, you can always pass in an empty vector.

I wouldn't consider overloading methods for different cases unless this cases require completely different handling. Even in that case you could consider a public method with all parameters and then create private methods for handling specific cases based on optional parameters.

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge that you have read and understand our privacy policy and code of conduct.

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