承接 coff/state-machine-framework 相关项目开发

从需求分析到上线部署,全程专人跟进,保证项目质量与交付效率

邮箱:yvsm@zunyunkeji.com | QQ:316430983 | 微信:yvsm316

coff/state-machine-framework

Composer 安装命令:

composer require coff/state-machine-framework

包简介

State Machine Framework PHP component for designing state machines

README 文档

README

Maybe state machines are not what you usually do with PHP but when you do... just use this. This simple yet powerful framework will keep your state machines within their desired state transition cycles. You can also modify their behavior whilst running or just configure them dynamically and launch. You can define state transition conditions you want based upon anonymous functions or class methods. Fire events on each state transition with your favorite event dispatcher.

Installation

Easiest way is to use composer:

$ composer require coff/state-machine-framework

Alternatively just clone repository:

$ git clone https://github.com/coff/php-state-machine-framework.git

and then checkout specific tag:

$ git checkout tags/v0.3

Usage example

States' dictionary

For clarity each state machine should have its own state dictionary defined.

    
    /**
     * @method static DRAFT()
     * @method static SENT()
     * ... // this should make your IDE believe these methods exist
     *
     */
    class PetitionEnum extends StateEnum {
        const __default     = self::DRAFT,
              DRAFT         = 'draft',
              SENT          = 'sent',
              VOTED         = 'voted',
              ACCEPTED      = 'accepted',
              REJECTED      = 'rejected',
              CANCELED      = 'canceled';
              
              // States names should be defined lowercase without spaces and special characters due to 
              // automatically determined assertion method names when in use with DefaultCallbackAssertion
              // @todo replace DefaultCallbackAssertion behavior in this matter 
              
    }

Machine class

    class Petition extends Machine {
        
        protected $votesYes, $votesNo;
    
        public function init() {
            $this->setInitState(PetitionEnum::DRAFT());
            
            // defines machine's allowed behavior
            $this
                // prevents changing state upon assertion when AlwaysFalseAssertion is given
                ->allowTransition(PetitionEnum::DRAFT(), PetitionEnum::SENT(), new AlwaysFalseAssertion())
                ->allowTransition(PetitionEnum::DRAFT(), PetitionEnum::CANCELED(), new AlwaysFalseAssertion())
                
                // when no Assertion is given uses DefaultCallbackAssertion which calls assertXToY methods
                ->allowTransition(PetitionEnum::SENT(), PetitionEnum::VOTED())
                ->allowTransition(PetitionEnum::VOTED(), PetitionEnum::ACCEPTED())
                ->allowTransition(PetitionEnum::VOTED(), PetitionEnum::REJECTED())
                ;
            
        }
        
        public function send() 
        {
            // shall throw an exception if current state is not DRAFT because it wasn't allowed transition
            $this->setMachineState(PetitionEnum::SENT());
        }
        
        public function cancel() 
        {
            // shall throw an exception if current state is not DRAFT because it wasn't allowed transition
            $this->setMachineState(PetitionEnum::CANCELED());
        }

        
        public function setVotes($ya, $nay) 
        {
            $this->votesYes = $ya;
            $this->votesNo = $nay;
        }
        
        public function assertSentToVoted() 
        {
            // Method name used here is based upon DefaultCallbackAssertion. This can be changed though.
            return (null !== $this->votesYes && null !== $this->votesNo) ? true : false;
        }
        
        
        public function assertVotedToAccepted()
        {
            // condition for transition from state VOTED to ACCEPTED
            return $this->votesYes > $this->votesNo ? true : false;
        }
        
        public function assertVotedToRejected() 
        {
            // condition for transition from state VOTED to REJECTED
            return $this->votesYes <= $this->votesNo ? true : false;
        }
        
        public function onTransition(Transition $transition) 
        {
            // for purpose of this example we only echo this transition but you can easily dispatch an event from here 
            echo 'State changed from ' . $transition->getFromState() . ' to ' . $transition->getToState() . PHP_EOL;
        }
    }

Machine in-use

    $p = new Petition();
    $p->init();
    
    $p->run();
    // <nothing happens>
    
    $p->send();
    // State changed from draft to sent
    
    $p->run();
    // <nothing happens>
    
    $p->setVotes(5,1);
    
    $p->run();
    // State changed from sent to voted
    // State changed from voted to accepted
    

Transition object

Each transition object should have one or more assertion objects attached.

Remark: By default (when no assertion object is given as parameter) Machine::allowTransition() method attaches DefaultCallbackAssertion.

Assertion behaviors

AlwaysTrueAssertion

Results in automatic transition when machine is launched.

Be aware:

    $machine
        ->allowTransition(MachineEnum::ONE(), MachineEnum::TWO(), new AlwaysTrueAssertion)
        ->allowTransition(MachineEnum::TWO(), MachineEnum::ONE(), new AlwaysTrueAssertion)
        
    $machine->run();
    // this will result in endless loop of state changes

AlwaysFalseAssertion

Results in no transition when machine is launched. Use this kind of assertion when machine state is supposed to be changed upon setMachineState() method call only.

DefaultCallbackAssertion

Calls assertXToY method on machine object (or other object if specified) and makes transition decision upon its return.

CommonCallbackAssertion

Calls assertTransition method on machine object (or other object if specified) and makes transition decision upon its return.

CallbackAssertion

Calls user specified method to assert if state transition should proceed.

coff/state-machine-framework 适用场景与选型建议

coff/state-machine-framework 是一款 基于 PHP 开发的 Composer 扩展包,目前已累计 17 次下载、GitHub Stars 达 0, 最近一次更新时间为 2018 年 11 月 23 日, 在 PHP 生态内属于活跃度较高的组件。

我们在过去多个企业项目中使用过 coff/state-machine-framework 或与其功能相近的方案,如果你在选型或落地过程中遇到问题,例如 版本兼容、二次改造、私有化封装、与内部系统对接、生产 BUG 排查,欢迎联系我们协助评估。

围绕 coff/state-machine-framework 我们能提供哪些服务?
定制开发 / 二次开发

基于 coff/state-machine-framework 在你已有业务上做功能扩展、字段裁剪、UI 适配、与内部账号 / 权限 / 日志系统的深度对接。

BUG 修复 & 性能优化

线上偶发问题、内存泄漏、慢查询、并发异常等排查修复;针对高流量场景做缓存、队列、索引层面的调优。

项目外包 & 长期维护

承接完整的项目从需求 → 设计 → 开发 → 上线 → 长期运维;也可按月提供技术保姆服务。

yvsm@zunyunkeji.com QQ:316430983 微信:yvsm316 西安尊云信息科技 · 专注 PHP / Go / 分布式系统研发

统计信息

  • 总下载量: 17
  • 月度下载量: 0
  • 日度下载量: 0
  • 收藏数: 0
  • 点击次数: 10
  • 依赖项目数: 0
  • 推荐数: 0

GitHub 信息

  • Stars: 0
  • Watchers: 1
  • Forks: 0
  • 开发语言: PHP

其他信息

  • 授权协议: MIT
  • 更新时间: 2018-11-23