7

I have a use case where I display variables in a PDF file. But to get there is not simple, but I could do something like this:

/*
 * takes product model number, retrieves, processes, formats values
 * returns $variables, ready to plug-in to view with no further processing
 */
$variables = $this->repository->getVariables($model);

/*
 * View runs PDF Library code and displays variables and their values in a table
 */
$this->sendToView($variables);

Way 1 - Have Repository Do all the work to transform variables

inside getVariables I would do these:

  1. read raw data from database tables (stored expressions)
  2. run data through expression engine (it evaluates the expressions)
  3. format resulting numeric data (i.e. round to 2 decimal points)
  4. add denominations (i.e. mm or inches)
  5. adorn data (put engineering tolerances, or extra wording around variables)
  6. re-group data for consumption by the PDF API engine (the view)

All the work will be done in getVariables and sendToView will then directly plug the variables as PDF API directs, no transformation needed

Way 2 - Use repository to get raw data only

Opposite extreme is have getVariables do #1 only and have separate classes do their own things .. I could end up with

$expressions = $this->repository->getVariables($model);
$solveExpressions = $this->expressionEngine->process($expressions);
$formattedVars = $this->formatter->format($solvedExpressions);
$denominatedData = $this->denom->addMarkers($formattedVars);
$adornedData = $this->adorner->adorn($denominatedData);
$viewReadyData = $this->viewPreparer->prep($adornedData);
$this->sendToView($viewReadyData);

Or I could mix and match the above and stuff the methods into various classes..

My question

How much of the data transformation, formatting, regrouping, polishing, preparation, etc goes into the repository layer?

(That will help me determine what of the data manipulation will need to be done outside of repository layer, and maybe even what of the data manipulation is to be done in the view layer - i.e. simple regrouping of data for easier way to plug into a table)

P.S. What am I trying to do (data manipulation)

Without focusing on code, in the context of the question, what I am doing is this -- starting with expressions stored in database:

a = 5
b = a + 3

Then I end up with solved expressions:

a = 5
b = 8

Then I do a series or formatting and adorning like so:

8 => 8.00 => 8.00mm => 8.00mm +/-0.01

where during the above is stays in a form similar to

array(
    'a' => '5.00mm +/-0.01',
    'b' => '8.00mm +/-0.01'
);

For the view I transform that into

array(
    0 => array(
        'description' => 'a',
        'value' => '5.00mm +/-0.01'
    ),
    1 => array(
        'description' => 'b',
        'value' => '8.00mm +/-0.01'
    )
);

And I wish to write the above into modern OOP code.

Dennis
  • 8,267
  • 6
  • 38
  • 70

1 Answers1

3

Based on your comments, I would highly recommend you to not get fooled by so called best practices and other wizardry. Primarily you should choose a way to implement your solution in a way that helps:

  • your stakeholders/boss to reach business goal using your solution - the code in place.
  • you and your team to be able to fastly respond to the arisen problem/task, in a way that everyone understands

You also write about anemia and business object. Please prove me wrong but I fail to percieve any behaviour or business logic in the set of method calls. They just seem to doing a series of data transformation, without any validation or so. I have a gut feeling that it's used for some sort of reporting, but the true intention is not really clear.

The only useful thing I could help you with is, to examine your code, capture the technical areas and split them up to modules those have explicit boundaries. The Separation of concerns design principle can help here drawing the boundaries:

  • Repository: held responsible for reading and writing the data in your data store
  • Expression engine: evaluating the data
  • Formatter: formatting and adorning
  • Output to viewing: convert/represent the above to a given output form

Each of these modules should be responsible for their own set of concerns. Create classes with respective methods that does what are respectively responsible for and nothing more. Whenever you encapsulate these concerns into set of modules you are also increasing cohesion and may even help the testability of your code.

kayess
  • 241