2012-03-13 9 views
0

私は、イベント、例外などに関して何が起こっているのかを表すために、Dayクラスの束をラップするCalendarクラスを持っています。当社のスケジュール関連アプリケーションのために。クラス内の関数の数を避ける(関数のサイズではない)

問題は、機能リストが詰まってクラスが使用されているため、クラスへのAPIが成長していることです。ほとんどのアルゴリズムは他のクラスに委譲されているので、関数自体は小さくなりますが、APIを単純にして、クラスの基本構造をユーザーに知らせないために、関数内に多くのものをラップしてしまいます。基本的には、他のクラスでメソッドを呼び出す関数の束です。

この問題を解決するには、(競合検出のような)主要な種類の使用ごとにCalendarクラスを拡張するしかありません。より具体的なコードの要求に

ここにある:

 
class Calendar 
{ 
    public $start_date; 
    public $end_date; 

    /** 
    * @var Hours_UnitDefault[] 
    */ 
    public $unit_defaults = array(); 

    /** 
    * @var Hours_HoursException[] 
    */ 
    public $exceptions = array(); 

    /** 
    * @var Event[] 
    */ 
    public $events = array(); 


    /** 
    * The underlining data structure of this class. 
    * In the form of ['date'] => CalendarDay obj 
    * Why hash table? 
    * -Convinience/Speed of storage retreaval and organization. 
    * @var CalendarDay[] 
    * 
    */ 
    public $calendarHashTable = array(); 

    public function __construct() 
    { 

    } 

    public function fetchAll(
     $start_date, 
     $end_date, 
     array $room_ids, 
     array $ignore_events = array(), 
     array $ignore_recurrences = array() 
    ) 
    { 
     $this->setDateRange($start_date, $end_date); 
     $unit_ids = $this->fetchUnitIDs($room_ids); 
     $this->fetchUnitDefaults($unit_ids); 
     $semester_ids = array_unique(array_from_key('semester_id', $this->unit_defaults)); 
     $this->fetchExceptions($unit_ids, $semester_ids); 
     $this->fetchEvents($room_ids, $ignore_events, $ignore_recurrences); 


    } 

    /** 
    * @param Event[] $pending_events 
    * checks collisions against each pending event and stores the conflicts 
    */ 
    public function checkPendingEventsForConflicts(array $pending_events) 
    { 
     $this->initHashTableByPendingEvents($pending_events); 
     $this->hashAllDbData(); 
     $this->selectCorrectUnitDefaults(); 
     $this->calculateCollisionsForPendingEvents($pending_events); 
    } 


    /** 
    * goes through each CalendarDay and makes sure the UnitDefault stored is the one it should use 
    */ 
    public function selectCorrectUnitDefaults() 
    { 
     foreach ($this->calendarHashTable as $key => $day) { 
      $day->selectCorrectUnitDefault(); 
     } 
    } 

    public function fetchUnitIDs($room_ids) 
    { 
     return array_unique(array_from_key('unit_id', RoomUnit::getRoomUnits(array('room_ids' => $room_ids)))); // Directory_)); 
    } 

    public function fetchUnitDefaults($unit_ids) 
    { 
     $this->unit_defaults = Hours_UnitDefault::getUnitDefaults(array('date_range' => array($this->start_date, $this->end_date), 'library_unit_ids' => $unit_ids)); 
    } 

    public function fetchExceptions($unit_ids, $semester_ids) 
    { 
     $this->exceptions = Hours_HoursException::getExceptions(
      array(
       'with_unit_defaults' => true, 
       'date_range' => (array(
        $this->start_date, 
        $this->end_date 
       )), 
       'semester_unit_id' => $semester_ids[0], 
       'library_unit_ids' => $unit_ids) 
     ); 
    } 

    public function fetchEvents($room_ids, $ignore_events = array(), $ignore_recurrences = array()) 
    { 
     $this->events = Event::getEvents(array(
      'start_date_after' => $this->start_date, 
      'end_date_before' => $this->end_date . ' 23:59:59', 
      'room_ids' => $room_ids, 
      'event_status' => array('approved', 'blocked'), 
      'not_events' => $ignore_events, 
      'not_recurrences' => $ignore_recurrences)); 
    } 

    public function setDateRange($start_date, $end_date) 
    { 
     $this->start_date = date("Y-m-j", strtotime($start_date)); 
     $this->end_date = date("Y-m-j", strtotime($end_date)); 
    } 

    /** 
    * Gets an array of dates that are relevant to an event type to use as hash keys. 
    * @static 
    * @param EventInterface $event 
    * @return string[] dates 
    */ 
    public function getHashDateKeys(EventInterface $event) 
    { 

     return ConflictUtility::getDatesBetween2Dates($event->getStartDate(), $event->getEndDate()); 

    } 

    /** 
    * Hashes any event type(Event, Exception, UnitDefault) into the hash table. 
    * @param EventInterface $event 
    */ 
    public function hashEvent(EventInterface $event) 
    { 
     $keys = $this->getHashDateKeys($event); 

     foreach ($keys as $key) { 

      if (!$this->isHashKeySet($key)) { 
       continue; 
      } 

      $day = $this->getCalendarDayByKey($key); 
      $day->assignEvent($event); 
     } 

    } 

    public function splitEvent(EventInterface $event) 
    { 
     //we need to split multi-day spanning days into single days 

     $split_events = array(); 
     $dates = $this->getHashDateKeys($event); 
     $dates_count = count($dates); 

     if ($dates_count > 1) { 

      foreach ($dates as $date) { 
       array_push($split_events , clone $event); 
      } 

      for ($i = 0; $i setStartDate($dates[$i] . " " . date('g:i:s A', $split_events[$i]->getStartTimeStamp())); 
       $split_events[$i]->setEndDate($dates[$i] . " " . date('g:i:s A', $split_events[$i]->getEndTimeStamp())); 
      } 

     } else { array_push($split_events, $event); } 

     return $split_events; 

    } 

    /** 
    * Hashes events, exceptions and events into the hash table. 
    * Assumes the hash table was initialized. 
    */ 
    public function hashAllDbData() 
    { 

     //we need to split multi-day spanning exceptions into single days 
     foreach ($this->exceptions as $exception) { 

      $split_exceptions = $this->splitEvent($exception); 

      foreach($split_exceptions as $single_exception){ 
       $this->hashEvent($single_exception); 
      } 

     } 

     foreach ($this->events as $event) { 

      $split_events = $this->splitEvent($event); 
      foreach($split_events as $single_event){ 
       $this->hashEvent($single_event); 
      } 
     } 

     //splitting unit defaults into days (requires different approach then previous once) 
     foreach ($this->unit_defaults as $unit_default) { 
      $unit_default_semester_adapter = new Hours_UnitDefaultEventInterfaceAdopter($unit_default); 
      $unit_default_semester_adapter->treatAsSemester(); 
      $dates = $this->getHashDateKeys($unit_default_semester_adapter); 

      foreach ($dates as $date) { 
       $unit_default_adapter = new Hours_UnitDefaultEventInterfaceAdopter($unit_default); 
       $unit_default_adapter->treatAsEvent(); 
       $unit_default_adapter->setDate($date); 
       $this->hashEvent($unit_default_adapter); 
      } 
     } 
    } 


    /** 
    * @return CalendarDay 
    * @param string $key date 
    */ 
    public function getCalendarDayByKey($key) 
    { 
     return $this->calendarHashTable[$key]; 
    } 

    /** 
    * 
    * @param string $key date 
    * @return bool 
    */ 
    public function isHashKeySet($key) 
    { 
     if (isset($this->calendarHashTable[$key])) return true; 
     else      return false; 
    } 

    /** 
    * Inits a hash table key. 
    * @param string $key date 
    */ 
    public function initHashKey($key) 
    { 
     $calendar_day = new CalendarDay(); 
     $calendar_day->setDate($key); 
     $this->calendarHashTable[$key] = $calendar_day; 
    } 

    /** 
    * Sets up hash table based on a date range 
    * @param string $date_start 
    * @param string $date_end 
    */ 
    public function initHashTableByDateRange($date_start, $date_end) 
    { 
     $keys = ConflictUtility::getDatesBetween2Dates($date_start, $date_end); 

     foreach ($keys as $key) { 
      $this->initHashKey($key); 
     } 
    } 

    /** 
    * Sets up hash table based on array of dates 
    * @param string[] $dates 
    */ 
    public function initHashTableByDateArray(array $dates = array()) 
    { 
     foreach ($dates as $key) { 
      $this->initHashKey($key); 
     } 
    } 

    /** 
    * Sets up hash table based on pending events. 
    * @param Event[] $pending_events 
    */ 
    public function initHashTableByPendingEvents(array $pending_events = array()) 
    { 
     foreach ($pending_events as $pending_event) { 
      $key = self::getHashDateKey($pending_event); 
      $this->initHashKey($key); 
      $calendar_day = $this->getCalendarDayByKey($key); 
      $calendar_day->assignPendingEvent($pending_event); 
     } 
    } 

    /** 
    * @param Event[] $modify_pending_events 
    * @param Event[] $skip_pending_events 
    * 
    * deletes pending events that are skipped from the calendar 
    * substitutes pendings events that are modified from the calendar 
    */ 
    public function modifyPendingEvents(array $modify_pending_events, array $skip_pending_events) 
    { 

     //replace old one with new one 
     foreach ($modify_pending_events as $modify_pending_event) { 
      $key = $this->getHashDateKey($modify_pending_event); 
      $day = $this->getCalendarDayByKey($key); 
      $day->emptyPendingEvent(); 
      $day->assignPendingEvent($modify_pending_event); 
     } 

     //delete pending events that were skipped 
     foreach ($skip_pending_events as $skip_pending_event) { 
      $key = $this->getHashDateKey($skip_pending_event); 
      $day = $this->getCalendarDayByKey($key); 
      $day->emptyPendingEvent(); 
     } 
    } 


    /** 
    * @param EventInterface $event 
    * @return string date 
    */ 
    public function getHashDateKey(EventInterface $event) 
    { 
     $keys = self::getHashDateKeys($event); 
     $key = $keys[0]; 
     return $key; 
    } 

    /** 
    * For each pending event, checks even there are collisions in the appropriate date key. 
    * Behind the scenes it populates the conlficts EventContainer. 
    * @param Event[] $pending_events 
    */ 
    public function calculateCollisionsForPendingEvents(array $pending_events) 
    { 
     foreach ($pending_events as $pending_event) { 
      $key = self::getHashDateKey($pending_event); 
      $day = $this->getCalendarDayByKey($key); 
      $day->calculateCollisions(); 
     } 
    } 

    /** 
    * Removes date keys without conflicts. 
    * Returns a hash table with dates that have conflicts. 
    * @return array HashTable 
    */ 
    public function getConflictingDays() 
    { 

     $conflicting_days = array(); 
     foreach ($this->calendarHashTable as $date => $day) { 
      if ($day->hasConflicts()) { 
       array_push($conflicting_days, $day); 
      } 
     } 

     return $conflicting_days; 
    } 

    public function getConflictFreeDays() 
    { 
     $conflict_free_days = array(); 
     foreach ($this->calendarHashTable as $date => $day) { 
      if (!$day->hasConflicts()) { 
       array_push($conflict_free_days, $day); 
      } 
     } 
     return $conflict_free_days; 
    } 

    /** 
    * @return Event[] 
    * returns all of the pending events that are stored on the calendar 
    */ 
    public function getPendingEvents() 
    { 
     $pending_events = array(); 
     foreach ($this->calendarHashTable as $date => $day) { 
      if (!$day->isEmptyPendingEvent()) { 
       array_push($pending_events, $day->getPendingEvent()); 
      } 
     } 

     return $pending_events; 
    } 
} 

ここでの考え方は...一つだけにまたがるすべての再発などのようにするため、すべてが[日付] => CalendarDay にハッシュされていることです日。それらが何日も続く場合、それらは、それが広がる毎日に分解されます。

 
class CalendarDay 
{ 
    /** 
    * @var EventContainer 
    */ 
    public $schedule; 

    /** 
    * @var EventContainer 
    */ 
    public $conflicts; 

    public $pending_event; 

    public $date; 

    public function __construct() 
    { 
     $this->conflicts = new EventContainer(); 
     $this->schedule = new EventContainer(); 
     $this->pending_event = new EventContainer(); 
    } 

    /** 
    * Checks whether there are any conflicts in the conflicts container. 
    * Only relevant if a check for conflicts was performed and conflicts populated. 
    * @return bool 
    */ 
    public function hasConflicts() 
    { 
     if ($this->conflicts->isEmpty()) 
      return false; 
     else 
      return true; 
    } 

    /** 
    * Figures out if there are collisions between each event type and 
    * the pending event. In case there is a conflict it appends it to the 
    * EventContainer conlflicts. 
    */ 
    public function calculateCollisions() 
    { 
     //if there is no pending events, do nothing. 
     if ($this->pending_event->isEmptyEvents()) return; 

     $pending_event = $this->pending_event->getEvent(); 

     if (!$this->schedule->isEmptyEvents()) { 
      foreach ($this->schedule->getEvents() as $event) { 
       if ($event->hasConflict($pending_event)) { 
        $this->conflicts->assignEvent($event); 
       } 
      } 
     } 

     if (!$this->schedule->isEmptyUnitDefault()) { 
      $default_hours = $this->schedule->getUnitDefault(); 
      if ($default_hours->hasConflict($pending_event)) { 
       $this->conflicts->assignEvent($default_hours); 
      } 
     } 

     if (!$this->schedule->isEmptyException()) { 
      $exception = $this->schedule->getException(); 
      if ($exception->hasConflict($pending_event)) { 
       $this->conflicts->assignEvent($exception); 
      } 
     } 
    } 

    /** 
    * Assigns event the to EventContainer schedule 
    * @param EventInterface $event 
    */ 
    public function assignEvent(EventInterface $event) 
    { 
     $this->schedule->assignEvent($event); 
    } 

    public function assignPendingEvent(EventInterface $event) 
    { 
     $this->pending_event->assignEvent($event); 
    } 


    /** 
    * Basic idea behind the algorithm: 
    * ******************************** 
    * Open Period(START) 
    *   |open -> between opening and first event 
    *  Closed Period(START) 
    *  Closed Period(END) 
    *   |open -> between events 
    *  Closed Period(START) 
    *  Closed Period(END) 
    *   |open -> between closing and last event 
    * Open Period(END) 
    * ******************************** 
    * 
    * @return TimePeriod[] 
    * returns empty array if closed 
    */ 
    public function getAvailableHours() //todo:make sure data is valid before this algorithm happens 
    { 
     $available_hours = array(); 

     $open_hours = $this->getOpenTimePeriod(); 

     //means its closed this day (cases: closed all day exception, closed on that day in unit default) 
     if ($open_hours->isEmpty()) return $available_hours; //which is an empty array 

     $closed_time_periods = $this->getClosedTimePeriods($open_hours); 
     $events_size = count($closed_time_periods); 

     $hours_start = $open_hours->getStartTimeStamp(); 
     $hours_end = $open_hours->getEndTimeStamp(); 

     //if events are empty, the available hours are the open hours 
     if (empty($closed_time_periods)) { 
      $available = new TimePeriod(); 
      $available->setStartTimeStamp($hours_start); 
      $available->setEndTimeStamp($hours_end); 
      array_push($available_hours, $available); 
      return $available_hours; 
     } else { 
      //takes care of available hours between opening hour and first event 
      $first_event = $closed_time_periods[0]; 

      $first_available = new TimePeriod(); 
      $first_available->setStartTimeStamp($hours_start); 
      $first_available->setEndTimeStamp($first_event->getStartTimeStamp()); 

      array_push($available_hours, $first_available); 

      //takes care of available hours in between events if more then one 
      if ($events_size > 1) { 
       for ($i = 0; $i setStartTimeStamp($event->getEndTimeStamp()); 
        $available->setEndTimeStamp($next_event->getStartTimeStamp()); 

        array_push($available_hours, $available); 
       } 
      } 

      //takes care of available hours between closing hour and last event 
      $last_event = $closed_time_periods[$events_size - 1]; 

      $last_available = new TimePeriod(); 
      $last_available->setStartTimeStamp($last_event->getEndTimeStamp()); 
      $last_available->setEndTimeStamp($hours_end); 

      array_push($available_hours, $last_available); 
     } 

     //filter out available hours less then 30m //todo: ask slava if its 30m 
     foreach ($available_hours as $i => $available) { 
      $minutes = ($available->getEndTimeStamp() - $available->getStartTimeStamp())/60; 
      if ($minutes schedule->isEmptyUnitDefault()) { 
      $unit_default = $this->schedule->getUnitDefault(); 
      $open_hours->setStartTimeStamp($unit_default->getStartTimeStamp()); 
      $open_hours->setEndTimeStamp($unit_default->getEndTimeStamp()); 
      $open_hours->setSource($unit_default); 
     } 

     //if there is an exception for open hours, replace default hours 
     else if (!$this->schedule->isEmptyException()) { 
      $exception = $this->schedule->getException(); 
      if ($exception->is_open) { 
       $open_hours->setStartTimeStamp($exception->getStartTimeStamp()); 
       $open_hours->setEndTimeStamp($exception->getEndTimeStamp()); 
       $open_hours->setSource($exception); 
      } 
     } 

     return $open_hours; 
    } 

    /** 
    * @param TimePeriod $open_hours 
    * @return TimePeriod[] 
    */ 
    public function getClosedTimePeriods(TimePeriod $open_hours) 
    { 
     $closed_hours = array(); 

     //first take care of events and treat them as closed time periods 
     $events = $this->schedule->getEvents(); 
     foreach ($events as $event) { 
      $closed_period = new TimePeriod(); 
      //add 10 minutes before and after for events //todo:: possibly account for events that go right after each other to avoid 20m gap instead of 10m 
      $padding = 0; 
      if ($event->event_status != 'blocked') { $padding = 10 * 60; } 

      $closed_period->setSource($event); 

      //don't need the date 
      $closed_period->setStartTimeStamp($event->getStartTimeStamp() - $padding); 
      $closed_period->setEndTimeStamp($event->getEndTimeStamp() + $padding); 

      array_push($closed_hours, $closed_period); 
     } 

     //take care of closed exception if any and treat it as closed time period 
     if (!$this->schedule->isEmptyException()) { 

      $exception = $this->schedule->getException(); 
      if (!$exception->is_open) { 

       $closed_period = new TimePeriod(); 
       $closed_period->setSource($exception); 

       $closed_period_start = $exception->getStartTimeStamp(); 
       $closed_period_end = $exception->getEndTimeStamp(); 

       //open hours generally don't have date as part of time stamp so we need to add it for future comparisons with exception 
       $open_period_start = $open_hours->getStartTimeStamp(); 
       $open_period_end = $open_hours->getEndTimeStamp(); 

       //now we need to take care of cases when closed exception starts before or after opening hours. 
       //why? to simplify further algorithms so that all closed time period fall within open time period. 

       //if closed exception starts before open -> trunkate 
       if ($closed_period_start $open_period_end) { 
        $closed_period_end = $open_period_end; 
       } 

       $closed_period->setStartTimeStamp($closed_period_start); 
       $closed_period->setEndTimeStamp($closed_period_end); 

       array_push($closed_hours, $closed_period); 
      } 

      if (!function_exists('cmp')) { 
       function cmp($a, $b) 
       { 
        if ($a->getStartTimeStamp() == $b->getStartTimeStamp()) { 
         return 0; 
        } 
        return ($a->getStartTimeStamp() getStartTimeStamp()) ? -1 : 1; 
       } 
      } 

      usort($closed_hours, 'cmp'); 
     } 

     return $closed_hours; 
    } 

    public function selectCorrectUnitDefault() 
    { 

     if (!$this->schedule->isEmptyException()) { 
      $exception = $this->schedule->getException(); 

      if ($exception->is_open) { //if we have exception for open hours, get rid of defaults 
       $this->schedule->emptyUnitDefaults(); 
       return; 
      } 

      if (!$exception->is_open) { //check for closed exception that last all day //todo:: think about how to do this in available_periods section 
       if ($exception->getStartTimeStamp('only_time') == strtotime('12:00:00 AM') && $exception->getEndTimeStamp('only_time') == strtotime('11:59:00 PM')) { 
        $this->schedule->emptyUnitDefaults(); 
        return; 
       } 
      } 

     } 

     $unit_defaults = $this->schedule->getUnitDefaults(); 
     //discard library hours if there are multiple unit defaults b/c we are going to use a different one. 
     if (count($unit_defaults) > 1) { 
      foreach ($unit_defaults as $i => $unit_default) { 
       if ($unit_default->getName() == 'Library') unset($unit_defaults[$i]); 
      } 
      $unit_defaults = array_values($unit_defaults); 

      //take the more restrictive unit default 
      $last_unit_default = $unit_defaults[0]; 
      foreach ($unit_defaults as $unit_default) { 
       if ($unit_default->getStartTimeStamp() > $last_unit_default->getStartTimeStamp()) $last_unit_default = $unit_default; 
      } 

      $unit_defaults[0] = $last_unit_default; 

     } 

     $unit_default = $unit_defaults[0]; //take whatever remains as unit default 

     $this->schedule->emptyUnitDefaults(); 
     $this->schedule->assignEvent($unit_default); 
    } 

    /** 
    * Sets date to correspond to hash table date key for convinience 
    * @param string $date 
    */ 
    public function setDate($date) 
    { 
     $this->date = $date; 
     $this->schedule->setDate($date); 
     $this->conflicts->setDate($date); 
     $this->pending_event->setDate($date); 
    } 

    public function getDate($format = "Y-m-d") 
    { 
     return date($format, strtotime($this->date)); 
    } 

    public function getAllConflicts() 
    { 
     return $this->conflicts->getAllEvents(); 
    } 

    public function getConflictCount() 
    { 
     return count($this->getAllConflicts()); 
    } 

    public function emptyPendingEvent() 
    { 
     $this->pending_event->emptyEvents(); 
    } 

    public function emptyConflicts() 
    { 
     $this->conflicts->emptyAll(); 
    } 

    public function isEmptyPendingEvent() 
    { 
     return $this->pending_event->isEmptyEvents(); 
    } 

    public function getPendingEvent() 
    { 
     return $this->pending_event->getEvent(); 
    } 

} 

コンテナCalendarDayはストレージに使用します。

 
class EventContainer { 

    /** 
    * @var Hours_UnitDefaultInterfaceAdopter[] 
    */ 
    private $unit_defaults = array(); 

    /** 
    * @var Hours_HoursException 
    */ 
    private $exception; 

    /** 
    * @var Event[] 
    */ 
    private $events = array(); 

    /** 
    * Assigns event type to the appropriate variable by checking its class. 
    * UnitDefault are saved as UnitDefaultEventInterfaceAdopter for code reuse. 
    * @param EventInterface|Hours_UnitDefaultEventInterfaceAdopter|Hours_HoursException|Event $event 
    */ 
    public function assignEvent(EventInterface $event) { 
//  echo "assigning: ".get_class($event) . "
"; switch (get_class($event)) { case 'Event': array_push($this->events, $event); break; case 'Hours_HoursException': $this->exception = $event; break; case 'Hours_UnitDefaultEventInterfaceAdopter': array_push($this->unit_defaults, $event); break; default: die('Invalid class type argument supplied to the DaySchedule->assign() function'); } } /** * Checks whether all of the event types arrays are empty. * @return bool */ public function isEmpty(){ if (empty($this->unit_defaults) && empty($this->exception) && empty($this->events)) return true; else return false; } /** * * @return bool */ public function isEmptyException(){ return empty($this->exception); } /** * * @return bool */ public function isEmptyEvents(){ return empty($this->events); } /** * * @return bool */ public function isEmptyUnitDefault(){ return empty($this->unit_defaults); } /** * @return Hours_HoursException */ public function getException(){ return $this->exception; } /* * @return Hours_UnitDefaultInterfaceAdopter */ public function getUnitDefault(){ return $this->unit_defaults[0]; } /* * @return Hours_UnitDefaultInterfaceAdopter[] */ public function getUnitDefaults(){ return $this->unit_defaults; } /* * @return Event[] */ public function getEvents(){ return $this->events; } public function getEvent(){ return $this->events[0]; } public function setDate($date){ $this->date = $date; } public function getAllEvents(){ $events = array(); if(!$this->isEmptyEvents()){ $events = $this->events; } if(!$this->isEmptyException()){ array_push($events, $this->exception); } if(!$this->isEmptyUnitDefault()){ array_push($events, $this->getUnitDefault()); } return $events; } public function emptyEvents(){ $this->events = array(); } public function emptyUnitDefaults(){ $this->unit_defaults = array(); } public function emptyException(){ $this->exception = null; } public function emptyAll(){ $this->emptyEvents(); $this->emptyException(); $this->emptyUnitDefaults(); } }

どこでも使用されているインターフェイス。

 
interface EventInterface 
{ 
    public function getStartTimeStamp(); 
    public function getEndTimeStamp(); 
    public function getStartDate(); 
    public function getEndDate(); 
    public function hasConflict(EventInterface $pending_event); 
    public function getName(); 
    public function getDetails(); 
} 

は、今の問題は、保留中のイベントを格納するためにCalendarDayで構成さseprate EventContainerオブジェクトを持つために私を必要とする...など、すべての競合検出である等... 機能が成長するにつれ、私は自分自身がそれにあまりにも多くのものを追加すること見つけます。

批評をお待ちしています。

私はここに学びます。誰でもここに読んで時間がかかりました:早めにありがとう!

+0

サブクラス化は、拡張するのではなくオプションである可能性があります。 –

答えて

0

免責事項:私は実際にはPHPの経験はゼロです(現在)。

私が間違っていると私を修正しますが、カレンダークラスは時間間隔をCalendarDaysに分割し、次に各CalendarDay内でイベントを別々に処理して、カレンダーで結果を再結合します。この場合、his advice aboveに従ってください。時間間隔を日に分割し、毎日別々にイベントを処理するこの中間ステップを持つべきではありません。代わりに、複数の日に渡ってより一般的な方法でそれらを処理し、明示的に別々のオブジェクトに分割しないで暗黙的に日にマップする数学を実行する必要があります。

+0

コードを追加しました。ありがとうxD – Eugene

+0

私の編集を参照..... –

関連する問題