2

I have two business classes: TimesheetDay and TimeSlot. One TimesheetDay can have one or more TimeSlots.

The TimesheetDay and TimeSlot classes will be dependent on an object that implements a corresponding TimesheetDayData and TimeSlotData interface. That way, I can write data classes to map the objects to a MySQL database, but if I use another way to store the data in the future, I can inject objects from a different dataclass.

These objects will not create other objects, and I refuse to use the "new" keyword in them. I want them to be testable in complete isolation.

For example, I instantiate a TimesheetDay object like this (in a container):

$mTimesheetDayData = new TimesheetDayMysqlData($databaseHost, $timesheetDayId);
$mTimesheetDay = new TimesheetDay($mTimesheetDayData);

TimeSlot objects will be constructed the same way:

$mTimeSlotData = new TimeSlotMySqlData($databaseHost, $timeSlotId);
$mTimeSlot = new TimeSlot($mTimeSlotData);

My problem lies in getting TimeSlot objects that the TimesheetDay contains. I can't have the TimesheetDay class creating objects. Otherwise, I might write a method that returns an array of TimeSlot objects, something like:

$timeSlotsForThatDay = array();
$timeSlotsForThatDay = $mTimesheetDay->getTimeSlots();

But, that would require the method getTimeSlots() to create objects.

How would you handle this?

1
  • $timeSlotsForThatDay = array(); Why would you do that?
    – yannis
    Commented Jan 5, 2012 at 19:48

2 Answers 2

1

I recommend to create one more class - TimesheetDataMapper, it would map mysql data and objects. As I understand, you intend to make TimesheetDay and TimeSlot as POPO (Plain Old Php Object). That is a good intention :)

So what you have to do is inject TimeSlotMySqlData into TimesheetDataMapper, there have a method getTimesheetDay($someCriteriaOrId); which would get the data from mysql based on criteria, create new object TimesheetDay, select time slot data & inject it into TimesheetDay.

class TimesheetDataMapper {
    protected function _getTimeSlotData($someCriteriaOrId)
    {
         $timeSlotsForReturn = array();

         $someTimeSlotListFromDb; 
         foreach ($someTimeSlotListFromDb as $timeSlotData) {
             $timeSlotsForReturn[] = new TimeSlot($timeSlotData);
         } 

         return $timeSlotsForReturn;
    }
    public function getTimesheetDay($someCriteriaOrId) 
    {
        $timeSlotData = $this->_getTimeSlotData($someCriteriaOrId);
        $timesheetDay = new TimesheetDay($timeSlotData);

        return $timesheetDay;
    }
}

You could also have some setters/getters on TimesheetDay / TimeSlot.

0

The TimesheetDay object should query the database for data to construct its list of TimeSlots, either when it is constructed, or the first time getTimeSlots is called.

Your Answer

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

Not the answer you're looking for? Browse other questions tagged or ask your own question.