mardi 28 novembre 2017

Design pattern for a calculation that has to output a report in Ruby

I have a class that does calculations. Most of the times it is used in the code to output a single value:

Use: value = Calculator.new(1234).output

This is an example of the class definition:

class Calculator

  def initialize(parameter_1)
    @parameter_1 = parameter_1
  end

  def output 
    op_1_result = operation_1(@parameter_1)
    op_2_result = operation_2(op_1_result)

    operation_3(op_2_result)
  end

  def operation_1(param)
  ...

end

But sometimes the user has to print a report of the calculation, showing many of the variables from inside the calculations.

The first solution I implemented was to pass a parameter at initialization telling the class that it should save some internal variables for the report, like this:

class Calculator

  attr_reader :report

  def initialize(parameter_1, reporting=false)
    @parameter_1 = parameter_1
    @reporting = reporting
    @report = {}
  end

  def output 
    op_1_result = operation_1(@parameter_1)
    @report[:op_1_result] = op_1_result if @reporting

    op_2_result = operation_2(op_1_result)
    @report[:op_2_result] = op_2_result if @reporting

    operation_3(op_2_result)
  end

  def operation_1(param)
  ...

end

Then, when I want to get those intermediate variables, I would:

calculator = Calculator.new(1234, true) # reporting activated
report = calculator.report

report[:op_1_result] # one of the intermediate variables of the calculation

Does this break the single responsibility principle, as the class is now calculating the value and reporting at the same time?

Is there a better way to do this, a design pattern where I could have a fast calculation of the output result where it is needed and show the report where needed without all those ifs?

Any light on this and comments will be really appreciated!

Aucun commentaire:

Enregistrer un commentaire