2011-08-20 84 views
1

我在尋找的整潔,維護和測試的方式來處理諸如以下,其中不同的參數組合必須以不同的方式由該對象的方法來解釋的情況下建議:對象的構造/方法重載

# Every 2 days. 
$event = Event::Recurrence->new(recurs => 'daily', interval => 2); 

# 1st and 2nd day of every 3rd week. 
$event = Event::Recurrence->new(recurs => 'weekly', days => [1, 2], interval => 3); 

# 1st and 2nd day of every 4th month. 
$event = Event::Recurrence->new(recurs => 'monthly', days => [1, 2], interval => 4); 

# 1st and 2nd day of the 2nd and 3rd week of every month. 
$event = Event::Recurrence->new(recurs => 'monthly', days => [1, 2], weeks => [2, 3], interval => 1); 

# 1st and 2nd day of the 2nd and 3rd week of every year. 
$event = Event::Recurrence->new(recurs => 'yearly', days => [1, 2], weeks => [2, 3], interval => 1); 

# 1st and 2nd day of the 2nd and 3rd week of the 3rd and 4th months of every 5th year. 
$event = Event::Recurrence->new(recurs => 'yearly', days => [1, 2], weeks => [2, 3], months => [3, 4], interval => 5); 

# Do something with the event object. 
$set = $event->get_set(); 

get_set()將根據構造參數的不同而起作用。

我不是在尋找方法來實現日期處理 - 我使用循環事件來說明問題的類型。相反,我正在尋找更好的方法來處理將不同的可能的參數組合分配到合適的方法的更一般的信息。我使用駝鹿,所以駝鹿/ OO模式是受歡迎的。

上述示例可以大致分爲不同類型的事件:每日,每週,每月和每年。每個將以不同的方式處理剩餘的參數,但最終結果將是相同類型的對象 - 一組可以執行某些操作(獲取開始和結束日期,確定交叉點等)的循環事件。

get_set()因此可以實現一個調度表來處理所有可能的參數組合,爲每個參數調用一個單獨的方法 - 但是感覺混亂。

我可以用單獨的類針對不同復發類型一起創建一個CodeRef屬性(Event::Recurrence::DailyEvent::Recurrence::Weekly,等等),並指定相應的類,在施工時間屬性,類似於接受的答案this question - 雖然我不確定我會如何實現這一點。

+0

爲什麼要的方法做不同不同組參數的東西?你有沒有嘗試過一個系統,可以做循環事件,而不必關心他們的時期?在採用這種思維方式太古怪之前,我會尋找一個更簡單的解決方案。 –

+0

@brian d foy:我在使用[DateTime :: Event :: Recurrence](http://search.cpan.org/~fglock/DateTime-Event-Recurrence-0.16/lib/DateTime/Event/Recurrence.pm) ,但它不能按照我喜歡的方式處理一些重複。相反,我使用[DateTime :: Set-> from_recurrence](http://search.cpan.org/~fglock/DateTime-Set-0.31/lib/DateTime/Set.pm)來創建循環事件。我想遵循類似於DateTime :: Event :: Recurrence的模式,其中'days','weeks'具有不同的含義,具體取決於是否存在其他參數。例如,'days'可以表示星期幾或一個月中的某一天。 – Martin

回答

0

您可能應該爲每種重複事件分別設置不同的子類。 DailyRecurringEvent類,WeeklyRecurringEvent類,MonthlyRecurringEvent類等。

(注意:每日和每週經常性事件可以實施爲「每隔n天經常性事件」的實例,即對於日常事件n = 1和n =每週活動7次。)

而不是在您的事件對象上調用->get_set,我會將對象本身視爲「事件集」。現在的問題是:你想在你的設置上支持哪些操作,以及你需要哪些其他輔助類。

一個示例:假設您希望支持從某個特定日期之後的事件集合獲取下一個發生的事件的操作。將此操作稱爲「next_event_after」。針對上述每個類(即每日,每週,每月,每年)實施這項工作非常簡單。

現在你說你希望能夠接受事件集合的交集。一個名爲「EventSetIntersection」的新類表示一組事件集合的交集。操作「next_event_after」的一個路口可能實現這樣的:

package EventSetIntersection; 

use Moose; 
has event_sets => (
    is => 'rw', 
    isa => 'Array[EventSets]', 
); 
sub next_event_after { 
    my ($self, $date) = @_; 
    return min { $_->next_event_after($date) } @{ $self->event_sets }; 
} 

回想一下,你原來的班是EventSets,這樣你就可以直接創建交集:

my $weekely_event = WeeklyEvent->new(...); 
my $yearly_event = YearlyEvent->new(...); 
my $intersection = EventSetIntersection->new(event_sets => [ $weekly, $yearly ]); 
+0

這與我選擇實現的方法類似,但我最終設法將代碼分解到這樣的程度,以至於不需要單獨的類。相反,我有一個'Event :: Recurrence'類,它有'每日','每週','每月'和'年度'的方法。事實證明,這並不像我想的那樣混亂 - 事實上,它非常整潔:-) – Martin