Take the 2-minute tour ×
Programmers Stack Exchange is a question and answer site for professional programmers interested in conceptual questions about software development. It's 100% free, no registration required.

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?

share|improve this question
    
$timeSlotsForThatDay = array(); Why would you do that? –  Yannis Rizos Jan 5 '12 at 19:48

2 Answers 2

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.

share|improve this answer

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.

share|improve this answer

Your Answer

 
discard

By posting your answer, you agree to the privacy policy and terms of service.

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