乐趣区

关于采编系统的设计与分析

一个采编系统,核心无非就是写作,审核,发布这些基本的流程。处理好这个部分,一个采编系统就该就差不多了。

写作,审核,发布。从编程的角度来看,它们其实是一个个的事件。审核是一个事件,发布是一个事件,取消发布是一个事件,推荐是一个事件。而这些是事件改变的是文章的状态。

首先就是一个文章类,简单化,一个 id 表示唯一标识,一个 status 标识文章状态。

class ArticleModel
{
    public $id;
    public $status;
}

其次,这个应该是事件驱动的,那么定义接口和抽象类

interface IArticleEvent{public function action(ArticleModel $articelModel);
}

abstract class ArticleEvent implements IArticleEvent{    
    // 保存
    const SaveArticle = 1;
    // 提交
    const SubmitArticle = 2;
    // 第一次审核
    const FirstReviewArticle = 4;
    // 第二次审核
    const SecondReviewArticle = 8;
    // 发布
    const PublishArticle = 16;
    // A 推荐
    const ARecommendArticle = 32;
    // B 推荐
    const BRecommendArticle = 64;

    public $event_name;
    public $created_at;
    public $created_by;

    public function __construct($event_name,$created_at,$created_by){
        $this->event_name = $event_name;
        $this->created_by = $created_at;
        $this->created_by = $created_by;
    }

    public abstract function action(ArticleModel $articelModel);
}

一般用状态最好用二级制 1,2,4,6,8… 表示。这个其一和 1,2,3,4 没有什么区别,其二就是它可以表示累加,1+2+4 = 7。
这里的流程是,保存状态 -> 提交状态 -> 第一次审核状态 -> 第二次审核状态 -> 发布状态 ->(A 推荐状态,B 推荐状态)。
这里 status 就可以很灵活,既可以是 1,2,4,8。也可以是状态相加,比如说 文章是 A 推荐状态 1+2+4+8+16+32 = 63。文章同时 A 推荐也是 B 推荐,就是 127。文章取消 A 推荐,就是 95,仅仅是发布状态就是 31。

最后就是实现各个事件了。这里就简单实现三个事件。提交,A 推荐和取消 A 推荐

class PublishArticleEvent extends ArticleEvent {public function action(ArticleModel $articelModel)
    {
        $status = $articelModel->status + ArticleEvent::PublishArticle;
        echo "提交文章成功 文章状态".$status;
    }
}

class ARecommendArticle extends ArticleEvent
{public function action(ArticleModel $articelModel)
    {
        $status = $articelModel->status + ArticleEvent::ARecommendArticle;
        echo "A 推荐 文章进入到 B 推荐(文章可以同时是提交状态和 A 推荐状态)". $status;
    }
}

class CancelARecommendArticle extends ArticleEvent
{public function action(ArticleModel $articelModel)
    {
        $status = $articelModel->status - ArticleEvent::ARecommendArticle;
        echo "取消 A 精选成功 文章返回到提交状态".$status;
    }
}

目前流程比较简单,就是简单的加,减法。也可以在这里去处理 sql 语句之类的。

这样是事件驱动,符合单一原则和开放 - 关闭原则。代码就会很灵活,扩展也会很方便,流程控制代码和事件代码分离。
比如说,在 Article 实现通用的日志记录方法 function log()。在特定的类下面,重写这个 log 方法。用于记录更加详细的日志信息。
再比如说,流程中加一个第三次审核,加一个事件 ThirdArticleReviewEvent, 将这个类加入到流程控制代码中。
取消 A 推荐这个事件,要求不仅取消 A 的推荐,同时也是取消 A 的发布。那么加一个新事件,或者只需要修改单一事件。
在上面的需求再改一下。A 部门可以同时取消推荐和发布,B 部门只能取消推荐。那么加一个新的事件。

这种基本可以做到他自狠来他自恶,我自一口真气足。

退出移动版