在PHP中将数据对象传递给Factory

时间:2009-03-10 15:34:04

标签: php refactoring factory

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

我正在处理预定的消息发送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;
        }
    }
}

Setter方法:

$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

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

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

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

如果我走向绝对错误的方向,请告诉我。 你会为这项任务推荐什么解决方案?

先谢谢

2 个答案:

答案 0 :(得分:2)

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

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');

答案 1 :(得分:1)

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

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

要添加到vartec的帖子,因为它出现在您的设计和工厂模式的使用中,Scheduler子类属性仅在创建对象后读取,您可能希望通过仅允许设置属性使每个Scheduler不可变在创建对象时(在构造函数中)。