0

请帮我实现该任务的工厂设计模式。

我正在开发预定的消息发送 Web 应用程序。用户可以指定自己的预定发送计划,消息将在需要时发送。用户只能选择 3 种重复类型中的一种:每月、每周、每天。对于这 3 种重复类型算法是相似的:1)选择发送日期和时间(对于第一次交付) 2)根据重复类型选择“每 X 个月/周/天重复一次”中的选项 3)按类型指定结束(日期或按出现次数限制)

每周调度程序有点不同。它还有一个功能 - 重复的工作日(例如:每周一、周五重复)

class SchedulerFactory {
    public function create($type) {
        switch ($type) {
            case "monthly" :
                $Scheduler = new MonthlyScheduler();
        break;
            case "weekly" :
                $Scheduler = new WeeklyScheduler();
        break;
            case "daily":
                $Scheduler = new DailyScheduler();
        break;
            default:
                return null;
        }
    }
}

设置方法:

$SendScheduler->setSendDateAndTime("{$day}.{$month}.{$year}", time());

switch($end_by_type) {
 case 'by_date':
     $SendScheduler-     >setEndByDate("{$end_by_date_day}.{$end_by_date_month}.{$end_by_date_year}");
    break;
case 'by_occurences_limit':
    $SendScheduler->setOccurencesLimit($occurences_quantity);
    break;                  
}

$SendScheduler->addTaskOccuringEvery($RepeatEveryMonth);// repeat every X months/weeks/days depending on type

// only for weekly type
$SendScheduler->setWeekDayForRepeating($week_day); // repeat every Mon, Fri

我想使用工厂模式进行对象构造(它是最佳匹配吗?),并且不知道如何传递所有这些参数(不仅仅是$type,而是所有其他参数)来构造对象。

我应该创建将它们包装在单个数据对象中,并在 SchedulerFactory 类中创建方法“setOptions”并通过 getter 将此数据对象传递给“创建”构造方法吗?

也许在工厂类中创建这样的 setter 方法违反了工厂设计模式原则?我以前没有看到这样的例子,所以我现在有点困惑。

如果我走错了方向,请告诉我。您会为此任务推荐什么解决方案?

提前致谢

4

2 回答 2

4

我认为您误解了工厂模式。工厂应该只创建对象实例。至于传递更多参数,您可以这样做:

class Scheduler {
    public function factory($type, $paramsArr = array()) {
        switch ($type) {
            case 'monthly' : $className = 'MonthlyScheduler'; break;
            case 'weekly' : $className = 'WeeklyScheduler'; break;
            case 'daily' : $className = 'DailyScheduler'; break;
            default: return null;
        }
        $sched = new ReflectionClass($className);  
        return $sched->newInstanceArgs($paramsArr);  ;
    }
}

$paramsArr构造函数参数数组在哪里

因此:

$yourSched = Scheduler::factory('weekly',array('Monday'));

相当于:

$yourSched = new WeeklyScheduler('Monday');
于 2009-03-10T15:49:55.897 回答
1

您可以为调度选项创建一个包装器对象,并将其与类型一起传递给 SchedulerFactory.create() 方法。然后,在您的工厂方法中,您将创建调度程序对象并根据类型设置属性,因此所有内容都封装在调度程序工厂中。我想你也可以做一些乱七八糟的事情并使用 PHP 的变量方法参数而不是对象,但这会变得很难看。

我会避免创建 setOptions 方法,因为这需要一个 SchedulerFactory 实例,其中将选项作为对象传递允许工厂(和创建方法)保持静态。

要添加到 vartec 的帖子,因为从您的设计和使用工厂模式来看,调度程序子类属性仅在创建对象后才被读取,您可能希望通过仅在时间设置属性来使每个调度程序不可变创建对象(在构造函数中)。

于 2009-03-10T15:49:20.653 回答