0

In a BI project we have multiple reporter functionalities. So, we have defined some classes to implement this feature. This classes needs many attributes to chain and build complex queries to generate reports. Any other classes should set specific values for these attributes, to get reports from this class. Values of these attributes are Non-Dynamic. I don't use the database to store them. Below codes are the current model i am using:

Report generator (Main class):

class Report

    {
        private $indicator;
        private $ratio;
        private $divider;
        private $criteria;
        private $plantation;
        private $reporter;

        public function reporter($reporter)
        {
            $this->reporter = (new Reporters())->get($reporter);
            return $this;
        }

        public function plantation($plantationId)
        {
            $this->plantation = $plantationId;
            return $this;
        }

        public function ratio($ratio)
        {
            $this->ratio = (new Ratios())->get($ratio);
            return $this;
        }

        public function divider($divider)
        {
            $this->divider = (new Dividers())->get($divider);
            return $this;
        }

        public function criteria($criteria)
        {
            $this->criteria = $criteria;
            return $this;
        }

        public function get()
        {
            return $this->mocker();
        }

    }

Dividers Class:

class Dividers
{
    public $dividers = [
        'sum' => [
            'name' => 'مجموع',
            'alias' => 'sum',
        ],
        'plantations' => [
            'name' => 'مجموعه انتخابی',
            'alias' => 'plantations',
            'model' => Plantation::class
        ],
        'operation_types' => [
            'name' => 'نوع عملیات',
            'alias' => 'operation_type',
            'model' => OperationType::class
        ],
        'planting_years' => [
            'name' => 'سال زراعی',
            'alias' => 'planting_years',
            'model' => Planting_year::class
        ],
        'crops' => [
            'name' => 'انواع گیاهان',
            'alias' => 'crops',
            'model' => Crop::class
        ],
    ];

    public function get($divider)
    {
        if(!array_key_exists($divider, $this->dividers)){
            return false;
        }
        return $this->dividers[$divider];
    }
}

Ratio Class:

class Ratios
{
    public $ratios = [
        'SUM' => 'انباشته',
        'KILOGRAM' => 'کیلوگرم',
        'HECTARE' => 'هکتار',
        'RIALPERKILO' => 'ریال به کیلوگرم',
        'MILIONRIALPERTON' => 'میلیون ریال بر تن',

    ];

    public function get($ratio)
    {
        if(!array_key_exists($ratio, $this->ratios)){
            return false;
        }
        return $this->ratios[$ratio];
    }
}

So for using report generator i will use this method:

$report = (new Report())
    ->plantation(352)
    ->divider('sum')
    ->reporter('NetProfit', ['operation_type'=> 364])
    ->criteria([['criteriaType'=> 'human_resources', 'value'=> '256'],['criteriaType'=> 'human_resources', 'value'=> '326']])
    ->ratio('sum')
    ->indicator(324, 523, 632)
    ->get();

My question is: what is the best pattern to store this data objects to reduce human mistakes?

1
  • It seems like you're trying to incorporate translations for string. A much better approach would be using key/value pairs in a flat file and then loading your strings as accessible constants. Commented Mar 18, 2019 at 20:37

2 Answers 2

1

This is more of an opinion based answer, so I'll suggest what I do when I am using static values.

Declare class members as static and protected for variables.

Like in your question class Ratios { } is a static class

class Ratios{ 
    protected static $ratios = [...];
    public static function get($ratio)
    {
        if(!array_key_exists($ratio, self::$ratios)){
            return false;
        }
        return self::$ratios[$ratio];
    }
}
//Access the Ratios class with.
$val = Ratios::get($ratio);

This ensures that

  1. the values won't change throughout the lifecycle of your request
  2. Adds a layer of security.
  3. Also maintains the source, i.e. no change will occur if you don't change the code.
  4. Doesn't create a new Instance(new Ratios()) for getting static values and you have that memory edge.

Do the same with the class Dividers { }.

Sign up to request clarification or add additional context in comments.

Comments

1

I don't know if this is the best practice, but i would make a separate directory called "constants" or "config" or something that seems intuitive to you, and add there files named like Class_Property.php that return the value of that property

For example, in you Ratios class:

   class Ratios
{
    public $ratios = require('config/Ratios_ratios.php');

    public function get($ratio)
    {
        if(!array_key_exists($ratio, $this->ratios)){
            return false;
        }
        return $this->ratios[$ratio];
    }
}

And in config/Ratios_ratios.php:

<?php

        return [
            'SUM' => 'انباشته',
            'KILOGRAM' => 'کیلوگرم',
            'HECTARE' => 'هکتار',
            'RIALPERKILO' => 'ریال به کیلوگرم',
            'MILIONRIALPERTON' => 'میلیون ریال بر تن',

        ];

    ?>

Depending on how critical that data is, opt for require/require_once/include. This is done mainly to keep your class more skinny, separating the constants

Comments

Your Answer

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

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.