Search code examples
phpsolid-principlessingle-responsibility-principle

Best way to populate an object with properties pulled from a database


I'm using PHP 5.4. I'm in the process of trying to make my application more SOLID. I'm currently going through my objects and making sure they follow SRP. I'm stuck on how to handle populating my object with properties, especially properties that "extend" the object's properties. Let me better explain.

I have a class called Flock (yes, a group of chickens--I'm in agriculture). It consists of several properties that are in the flocks table in the database: id, member_id, integrator_id, date_placed, date_picked_up, etc:

<?php
class Flock
{
    private $id;
    private $member_id;
    private $farm_id;
    private $integrator_id;
    private $comments;
    private $production_sq_ft;
    private $number_of_houses;
    private $avg_effective_age_of_houses;
    private $date_placed;
    private $date_picked_up;
    private $head_started;
    private $head_picked_up;
    private $pounds_picked_up;
    private $pounds_sold;
    private $base_rate;
    private $performance_rate;
    private $fuel_rate;
    private $other_rate;
    private $feed_pounds_consumed;

    public function __construct() {}

    //Then a bunch of getters and setters.
}

My goal is to use the same object for both creating and retrieving a flock. However, in my database, I have created several "master" views--views that join together all lookup tables and perform any basic calculations on the data that can be performed at the row level. In this example, in my master view for flocks, I have joined the integrators table with my flocks giving me an integrator_name column in my view. The same goes for the members and farms tables. I have also found the difference in days between date_placed and date_picked_up giving me a column called total_time_in_facility. In my current version of this application, all this data is simply stored in an array and accessed using magic methods (__get). So if I wanted to get the integrator name, I would simply use $flock->integrator_name. However, if I were to use my Flock class to populate a database, I would not pass the integrator name--I would simply pass the values I've listed above.

My question is--what is the best way to get this extended data about a flock? Should I use another class to handle this (like FlockDetails)? Should I not be using this master view at all? Instead of performing any calculations in my view, should I simply be performing those within the class itself? I was under the impression that I should only be using a single class to describe a flock. If I were to create a new flock, I would use this class. If I wanted to retrieve on, I would simply populate it using a factory. But if I populate it using a factory, what about the additional details contained in my master view? Can anyone help me clear this up? Thanks!


Solution

  • Well, I would probably have a class Flock which represents a single row in the table "flocks" and class FlockEx which extends the class Flock by adding the fields you get as a result of the calculation in db. So, when you want to update or add a new flock to the db you use Flock class and when you retrieve flock fields along with the calculated ones you use FlockEx. Makes sense?