我正在寻找一些关于整洁、可维护和可测试的方法来处理以下情况的建议,其中不同的参数组合必须由对象的方法以不同的方式解释:
# 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()的功能会有所不同。
我并不是在寻找实现日期处理的方法--我是在使用循环事件来说明问题的类型。相反,我正在寻找有关如何处理将不同可能的参数组合分派到适当方法的好方法的更通用信息。我使用的是Moose,所以欢迎使用Moose/OO模式。
上面的例子可以大致分为不同类型的事件:每日、每周、每月和每年。每种方法将以不同的方式处理剩余的参数,但最终结果将是相同类型的对象-一组可执行某些操作(获取开始和结束日期、确定交叉点等)的重复事件。
因此,get_set()可以实现一个分派表来处理所有可能的参数组合,为每个参数调用一个单独的方法-但这感觉很混乱。
我可以为不同的递归类型(Event::Recurrence::Daily、Event::Recurrence::Weekly等)创建一个CodeRef属性和单独的类,并在构造时为该属性分配适当的类,这类似于this question的公认答案-尽管我不确定如何实现它。
发布于 2011-08-21 06:58:13
对于每种重复发生的事件,您可能应该有单独的子类,例如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 ]);https://stackoverflow.com/questions/7133238
复制相似问题