I need to perform a complicated calculation. In my case it seemed most natural to create a Calculator class (abstracted using a strategy pattern).
To perform the calculation the class needs to accept about 20 inputs, some of which are optional, some of which could change in the future etc. Once the Calculate() method is called, about 20 different variables need to be outputted.
There are a number of ways this can be achieved.
- Inputs passed in as parameters to a calculate method
- Inputs passed in through properties of the Calculator
- Inputs wrapped up into their own class, then passed to Calculate() method.
- Outputs returned by Calculate(), wrapped up in a class
- Outputs populated into a parameter passed to the Calculate() method
- Outputs retrieved from public properties of the Calculator, after Calculate() has been called
There are pros and cons to all these methods. How would you do it?
UPDATE: Thanks for the feedback.
The purpose of this calculator is to generate a quote. The inputs are things such as the customer’s address, interest rates, target profit, additional fees, product id etc The output includes the quote, the actual profit, more fees etc.
I have gone ahead and created ICalculateInput and ICalculateOutput interfaces and their concrete classes, and the system works very well now. The Calculator class also inherits from an ICalculator interface (as the calculations involved differ enormously depending on the company the product is sourced from).
Most people suggest using a ‘Parameter Class’, and a ‘Result Class’. I agree with this approach, but it seems to me that your parameters fall into several categories. Perhaps you could create a parameter class for the required parameters, and a separate parameter class for the optional parameters or groups of optional parameters. This way, you could create different methods depending on what kind of calculation you require;
This will make your API easier to use. If you don’t want to create classes for the different groups, you could also use Maps, but this will require more validation code in the calculation engine. Normally I would prefer parameter classes, but would have to know more about your particular problem to be decisive.
I would not store the calculation result in the calculation engine itself, because of thread safety and object reusability. It’s much easier to maintain code that is stateless.