前言
我最近一直写了很多活动都需要做任务发奖励。但每次都有很多类似的任务以及奖励。于是乎就想有没有什么方法把任务抽象,只需要写一遍代码就可以了。经过了一番参考觉得以下方法可行
任务
/**
* 任务接口
*
* @author suntianxiang <suntianxiang@kding.com>
*/
interface TaskInterface
{
/**
* 获取目标
*
* @param array $params
* @return TargetInterface[]
*/
public function getTargets();
/**
* 获取进度
*
* @return string 1/10
*/
public function getProgress();
}
这是任务接口
getTargets()方法获取所有目标,再根据目标判断任务是否完成,目标里对应这不同的逻辑,如连续登录,点赞这些
目标
interface TargetInterface
{
/**
*
* @param mixed $user 用户信息
* @return bool
*/
public function checkCondition($user);
}
这是目标接口
通过横向实现此接口完成各种不同的目标,如 LoginTarget,LikeTarget...
例子
/**
* 连续登录目标
*/
class ConsecutiveLoginTarget implements TargetInterface
{
/**
* @var int $days 连续登录天数
*/
private $days;
public function __construct($days)
{
$this->days = $days;
}
public function checkCondition($user)
{
return count($user['consecutive_login_times']) >= $this->days;
}
}
class ActivityTask implements TaskInterface
{
public function getTargets()
{
// 实际中这可能是从库中解析出来的
return [
new ConsecutiveLoginTarget()
];
}
public function getProgress()
{
return '0/1';
}
}
任务配置表
任务配置表sql
CREATE TABLE `tb_task_configs` (
`id` int(11) NOT NULL AUTO_INCREMENT COMMENT '任务id',
`name` varchar(30) NOT NULL COMMENT '任务名称',
`type` tinyint(1) NOT NULL COMMENT '任务类型 1 一次性任务 2 每日任务',
`targets` varchar(255) NOT NULL COMMENT '任务目标 string "|" 分割不同目标 ":"后接构造参数 ","分割参数 如 LoginTarget:1|OrderTarget:1,2',
`status` tinyint(1) NOT NULL DEFAULT '1' COMMENT '1 启用 0 禁用',
`is_del` tinyint(1) NOT NULL DEFAULT '0' COMMENT '0 未删 1 已删',
`create_time` int(11) NOT NULL DEFAULT '0',
`update_time` int(11) NOT NULL,
PRIMARY KEY (`id`)
) ENGINE=InnoDB DEFAULT CHARSET=utf8mb4 COMMENT='任务配置表';
结语
通过合理的抽象能减少很多重复的代码.像还有 任务奖励,前置任务这些笔者并没有实现,读者可以根据自己需要扩展。
**粗体** _斜体_ [链接](http://example.com) `代码` - 列表 > 引用
。你还可以使用@
来通知其他用户。