PHPã®ã¹ãã¼ããã·ã³Finiteã触ã£ã¦ã¿ã[PHP][Finite][StateMachine]
ä»åã¯ã¹ãã¼ããã·ã³ãPHPã§æ±ããFiniteã¨ããã©ã¤ãã©ãªã触ã£ã¦ã¿ãã®ã§åå¿é²ã¨ãã¦ã
ã¹ãã¼ããã·ã³ã¨ã¯ã£ã¦ããã¨ããããFiniteã®ç°¡åãªä½¿ãæ¹ã¾ã§ã軽ãã¾ã¨ãã¦ã¿ããããªã¨æãã¾ãã
ã¹ãã¼ããã·ã³ã¨ã¯
ã¹ãã¼ããã·ã³ã¨ã¯ããããç°¡åã«è¨ãã¨ç¶æ é·ç§»ã管çãããã®ã§ãããç¶æ Aããããç¶æ Bã¸ã®é·ç§»ãå¯è½ãã©ãããå¤å®ãããå®éã«é·ç§»ãå®è¡ããããã¾ãã
ç´°ããã¨ããã¯ã¹ãã¼ããã·ã³ããªã¼ãããã³ãªã©ã§èª¿ã¹ãã¨åºã¦ããã®ã§èå³ãããã°mm
éå¼ã«èªããã»ã©ãããããã¦ãªãã®ã§ä»ã®ç解ã ã¨ä¸è¨ç¨åº¦ã®æãã§ãw
ã¢ããªã±ã¼ã·ã§ã³ã§ã¹ãã¼ããã·ã³ãç¨ããããã«ããã¨æ¬¡ã®ãããªã¡ãªãããããã¾ãã
- ã¹ãã¼ã¿ã¹ããã¤ãªãã¸ã§ã¯ãã®ç¶æ é·ç§»ã®å®ç¾©ãéãè¾¼ãã¦ããã
- å®ç¾©éãã«ããç¶æ é·ç§»ã§ããªããªãããããã¼ã確ç«ããã
- å®ç¾©ã«åããç¶æ é·ç§»ãè¡ããã¨ããéã«ã¯ä¾å¤çãèµ·ãããã¨ã§é©åã«å¦çã§ãã
ç¶æ é·ç§»ã¯å¾ã ã«ãã¦ç®¡çãè¤éã«ãªã£ã¦ããããã¯ãå ã®è²ã ãªç®æã§å¤å®ãé½åº¦é½åº¦è¡ãããã«ãªã£ãããé½åº¦é½åº¦è¡ãããã§ãã°ã®æ¸©åºã«ãªã£ãããç¶æ é·ç§»ã®ããã¼ãå¤ãã£ãæã«ã¯ä¸æã«å¤å®ãã¦ããé¨åãä¿®æ£ããªããã°ãªããªãã£ããã¨ãåä»ãªç®ã«åããã¨ãå¤ãã§ãã
ä¾ãã°ãããä½æ¥ãè¡ããã±ããã®ç¶æ é·ç§»ãèãã¦ã¿ã¾ãã
âãåæç¶æ ãâãçµäºç¶æ ã¨ãã¦ãã¾ãã
ãã£ã¨èãã¦ã¿ãã ãã§ããããªæãã«ç¶æ é·ç§»ãåºã¦ãããã«æãã¾ãã
ä»ã«ããã±ãããã¯ãã¼ãºç¶æ ã追å ããããã¯ãã¼ãºãããªãªã¼ãã³ããããã©ããªç¶æ ããã§ãå¼·å¶çã«çµäºç¶æ ã«æã£ã¦ãããå´ä¸ç¶æ ã追å ããããèãæ¹ã«ãã£ã¦ã¯è²ã ãªç¶æ é·ç§»ããã¼ãåºæ¥ä¸ããã¾ãã
ããã®ç¶æ ã ã£ããç¢å°ã ã£ãããããæãã«åãæ±ãããï¼ããããªã¨ãã«æ¯é使ã£ã¦ããããã®ãã¹ãã¼ããã·ã³ã§ãï¼
Finiteã¨ã¯
ä¸è¨ã§èª¬æããã¹ãã¼ããã·ã³ã®PHPå®è£ ã§ãã
Finite, A PHP5.3+ Finite State Machine | Finite
PHP5.3以ä¸ãªã使ããã®ã§å°å ¥ã®æ·å± ã¯ä½ãã¨æãã¾ãï¼
ã¤ã³ã¹ãã¼ã«
composerã§å ¥ãã¾ãï¼
stableã¨ãã¦ã¯1.0.3ãã¿ã°ä»ãããã¦ãã¾ãããç¾å¨éçºä¸ï¼ã®masterã¯1.1ã«ãªãããã§ãçµæ§ä»æ§ãå¤ãã£ã¦ãããããªã®ã§(StateMachineã®ã³ã³ã¹ãã©ã¯ã¿å¼æ°ãå¤ãã£ã¦ããã)ãä»åã¯dev-masterãæå®ãã¦ã¤ã³ã¹ãã¼ã«ãã¾ããã
"require": { "yohang/finite": "dev-master" }
使ãæ¹
å ¬å¼ã®ãµã³ãã«ã³ã¼ãã«åã£ã¦èª¬æãã¦ãããã¨æãã¾ãã
Finite/basic-graph.php at master · yohang/Finite · GitHub
<?php require_once __DIR__ . '/../vendor/autoload.php'; /** * Class Document * ç¶æ ãæã¤ãªãã¸ã§ã¯ãã®ãµã³ãã«ã¨ãã¦ããã¥ã¡ã³ãã使ããã¦ãã¾ãã * 管çãããç¶æ ãæã¤ãªãã¸ã§ã¯ãã¯Finite\StatefulInterfaceãimplementsãã¾ãã * * StatefulInterfaceã¯getFiniteState()ã¨setFiniteState()ãå®è£ ãããã¨ãè¦æ±ãã¦ããã®ã§ã * ç¶æ 管çãããããããã£ãsetãgetã§ãããããã¦ããã¦ããã¾ãã */ // Implement your document class class Document implements Finite\StatefulInterface { private $state; public function getFiniteState() { return $this->state; } public function setFiniteState($state) { $this->state = $state; } } // Configure your graph $document = new Document; /** * ããã¥ã¡ã³ãã¤ã³ã¹ã¿ã³ã¹ã渡ãã¦ã¹ãã¼ããã·ã³ã®ã¤ã³ã¹ã¿ã³ã¹ãä½æãã¾ãã * ãã®æ¸¡ãããã®ã«å¯¾ãã¦ã¹ãã¼ããã·ã³ã¯ç¶æ 管çãè¡ãã¾ãã */ $stateMachine = new Finite\StateMachine\StateMachine($document); /** * ãã¼ãã¼ãä½æãã¾ãã * ããã§ç¶æ é·ç§»ã®ã«ã¼ã«ã決ãã¦ããã¾ãã * ä¸è¨ã®ä¾ã ã¨ããã¥ã¡ã³ãã«å¯¾ãã¦ã®ã«ã¼ã«ãå®ãã¦ãã£ã¦ãã¾ãã * ãã¼ãã¼ã«ã¯ä»¥ä¸ã®æ å ±ãè¨å®ãããã¨ãã§ãã¾ãã * * class * * è¨å®ãããã¯ã©ã¹åãããã¾ãã * * states * * ç¶æ ã®è¨å®ããã¾ãã * * type * * åæç¶æ ãé常ç¶æ ãçµäºç¶æ ã®3ã¤ããé¸æãã¾ãã * * ããã©ã«ãã¯é常ç¶æ ã§ãã * * properties * * ç¶æ ã«æããããè¨å®æ å ±ãããã°ãé£æ³é åå½¢å¼ã§èªç±ã«æãããäºãã§ãã¾ãã * * transitions * * stateséã®é·ç§»ãè¨å®ãã¾ãã * * ã©ã®ç¶æ ããã©ã®ç¶æ ã«ã¯é·ç§»å¯è½ãã¨ããã®ãè¨è¿°ãã¾ãã * * * * "draft"ã¨ããstateã¯ãåæç¶æ ã§ãããåé¤å¯è½ãã¤ç·¨éå¯è½ãã¨ããè¨å®ã«ãªã£ã¦ãã¾ãã */ $loader = new Finite\Loader\ArrayLoader(array( 'class' => 'Document', 'states' => array( 'draft' => array( 'type' => Finite\State\StateInterface::TYPE_INITIAL, 'properties' => array('deletable' => true, 'editable' => true, 'comment' => 'ä¸æ¸ã'), ), 'proposed' => array( 'type' => Finite\State\StateInterface::TYPE_NORMAL, 'properties' => array('comment' => 'æåºæ¸'), ), 'accepted' => array( 'type' => Finite\State\StateInterface::TYPE_FINAL, 'properties' => array('printable' => true), ) ), 'transitions' => array( 'propose' => array('from' => array('draft'), 'to' => 'proposed'), 'accept' => array('from' => array('proposed'), 'to' => 'accepted'), 'reject' => array('from' => array('proposed'), 'to' => 'draft'), ), )); /** * ä¸è¨ã§ä½æãããã¼ãã¼ã§ãã¹ãã¼ããã·ã³ã«è¨å®ããã¼ããã¾ãã * ããã§ã¹ãã¼ããã·ã³ãã³ã³ã¹ãã©ã¯ã¿å¼æ°ã«ã¦åãåã£ãã¤ã³ã¹ã¿ã³ã¹ã«å¯¾ãã¦ã©ã®ããã«ç¶æ ã管çãã¦ãããã * ç解ãããã¨ãã§ããããã«ãªãã¾ãã */ $loader->load($stateMachine); /** * ã¹ãã¼ããã·ã³ã®åæåãè¡ãã¾ãã * ããã§ãã¼ãã¼ã®ã«ã¼ã«ã«å¾ã£ã¦ç¶æ ããã¤ã¤ã³ã¹ã¿ã³ã¹ã®åæåãè¡ãã¾ãã * åæã«ãã¹ãã¼ããã·ã³ããç¾æç¹ã§ã®ç¶æ ããç¥ãã¾ãã * ä¸è¨ã®ä¾ã ã¨åæåããã¨typeãINITIALã§ãã"draft"ãã»ããããããã¨ã«ãªãã¾ãã */ $stateMachine->initialize(); // Working with workflow // Current state var_dump($stateMachine->getCurrentState()->getName()); // åæç¶æ ãªã®ã§"draft"ãè¿ãã¾ãã /** string(5) "draft" */ var_dump($stateMachine->getCurrentState()->getProperties()); // åæç¶æ ã®ããããã£ãè¿ãã¾ãã /** array(2) { ["deletable"]=> bool(true) ["editable"]=> bool(true) ["comment"]=> string(9) "ä¸æ¸ã" } */ var_dump($stateMachine->getCurrentState()->has('deletable')); // draftã'deletable'ããããã£ãæã¤ããè¿ãã¾ããæã£ã¦ããã®ã§true /** * bool(true) */ var_dump($stateMachine->getCurrentState()->has('printable')); // draftã'printable'ããããã£ãæã¤ããè¿ãã¾ããæã£ã¦ããªãã®ã§false /** * bool(false) */ var_dump($stateMachine->getCurrentState()->get('comment')); // draftããã¤'comment'ããããã£ãè¿ãã¾ãã'ä¸æ¸ã'ãè¿ãã¾ã /** * string(9) "ä¸æ¸ã" */ var_dump($stateMachine->getCurrentState()->get('printable')); // draftããã¤'printable'ããããã£ãè¿ãã¾ããæã£ã¦ããªãå ´åã¯NULL /** * NULL */ // Available transitions var_dump($stateMachine->getCurrentState()->getTransitions()); // draftã®æã£ã¦ããtransitionsãè¿ãã¾ãã /** array(1) { [0]=> string(7) "propose" } */ var_dump($stateMachine->can('propose')); // 'propose'ãã©ã³ã¸ã·ã§ã³ãé©ç¨å¯è½ããå¤å®ãã¾ããdraftã¯proposeãã©ã³ã¸ã·ã§ã³ã®éå§ç¶æ ãªã®ã§true /** * bool(true) */ var_dump($stateMachine->can('accept')); // 'accept'ãã©ã³ã¸ã·ã§ã³ãé©ç¨å¯è½ããå¤å®ãã¾ããdraftã¯proposeãã©ã³ã¸ã·ã§ã³ã®éå§ç¶æ ã§ã¯ãªãã®ã§false /** * bool(false) */ // Apply transitions try { $stateMachine->apply('accept'); // é©ç¨å¯è½ã§ãªããã©ã³ã¸ã·ã§ã³ãé©ç¨ãããã¨ããã¨StateExceptionãæãããã¾ãã } catch (\Finite\Exception\StateException $e) { echo $e->getMessage(), "\n"; /** * The "accept" transition can not be applied to the "draft" state of object "Document" with graph "default". */ } // Applying a transition $stateMachine->apply('propose'); // é©ç¨ããã¨ç¶æ ãé·ç§»ãã¾ãã var_dump($stateMachine->getCurrentState()->getName()); // ç¶æ ãé·ç§»ããã®ã§draftããproposedã«å¤åãã¦ãã¾ãã /** * string(8) "proposed" */ var_dump($document->getFiniteState()); // ç¶æ ãé·ç§»ããã®ã§draftããproposedã«å¤åãã¦ãã¾ãã /** * string(8) "proposed" */ var_dump($stateMachine->getCurrentState()->getProperties()); // åå¾ã§ããããããã£ãproposedã®ãã®ã«å¤åãã¦ãã¾ãã /** array(1) { ["comment"]=> string(9) "æåºæ¸" } */
ãã®æ§ã«ãç¾å¨ã®ç¶æ ã®æ å ±ã管çãããã管ç対象ã®ç¶æ ãå¤æ´å¯è½ããå¤å®ãããã管ç対象ã®ç¶æ ãå¤æ´ããããã¨ãã£ããã¨ãä¸æãã©ãããã¦æããããã«ãªã£ã¦ãã¾ãã
便å©ã§ããï¼
ä»åã¯åºæ¬çãªåããæ¹ã«ã¤ãã¦ãã¥ã¼ããªã¢ã«ããã£ã¦ã¿ã¾ããã
ä»ã«ãç¶æ
é·ç§»ã®ç´åãç´å¾ã«ã³ã¼ã«ããã¯ãåã¾ãã¦ä»»æã®ã³ã¼ããå®è¡ããããã«è¨å®ãå ãããã¨ãå¯è½ã ã£ãããã¦ããªããªãèãããã¦ãããªãã¨æãã¾ããã
ãã¨ã¯ä»åã¯finiteState
ã¨ããããããã£ã«å¼·å¶ããã¦ãã¾ããããä»»æã®ããããè¤æ°åã®ç¶æ
ã管çãããã¨ãããã¨ãã§ãã¾ãã
ã¾ããDIã³ã³ãããç¨ãããã¨ãæ³å®ããã¦ãã¦ãã»ããããã²ãªå½¢ã¿ãããªã®ãç¨æããã¦ãã¾ãã PimpleãSymfony2ã®ãµã¼ãã¹ã³ã³ããã¸ã®ãã¡ã¯ããªã¼ã®è¿½å ç¨ã®ã¯ã©ã¹ãããã¾ããã
Finite/src/Finite/Factory at master · yohang/Finite · GitHub
ãã ãPimpleã¯1ç³»æ³å®ã®ãã®ã«è¦ããã®ã§ã2系対å¿ã«ãããï¼ã¨ããå ´åçãããã«ã¯ãªããã®ã§æ±ãããå ´åã¯ã ã¨AbstractFactoryãextendsãããFactoryInterfaceãimplementsããããã¦å¯¾å¿ãããã®ãèªä½ããæµãã«ãªãããã§ãã
ãã®è¾ºãã®å¿ç¨ç·¨ã«ã¤ãã¦ãæ¸ãæ©ä¼ããã£ããæ¸ããããªãã¨æãã¾ãï¼
ã¨ã«ããã¯ããã¯ã©ã¤ãã«ä½¿ãã¨ãã¦ãã¹ãã¼ããã·ã³ã¯ã¨ã¦ã便å©ã§æå ãã¢ããªã±ã¼ã·ã§ã³ãä½ããã¨ãã§ããããã«ãªãã¨æãã®ã§ããã²ä½¿ã£ã¦ãã£ã¦ã¿ã¦ãã ããï¼
ä»åã®ããã°ç¨ã«è§¦ã£ã¦ã¿ããªãã¸ããªã¯ä»¥ä¸ã«ãªãã¾ãã