PHP 7 의 전략 모델 실천

실천 배경
회사 의 업무 변경 으로 인해 회원 시스템 에 대해 기능 적 인 새로운 기능 을 해 야 한다. 예전 의 회원 시스템 업그레이드 와 관련 된 업무 고려 가 주도면밀 하지 않 아서 코드 논리 도 완선 되 지 않 은 것 을 감안 하여 예전 에 회원 시스템 과 관련 된 코드 를 다시 미 루어 야 한다. 이런 업무 장면 이 이전에 배 운 전략 모델 과 비슷 하 다 는 것 을 고려 하여 실천 을 하기 로 결정 했다.
업무 설명
1 회원 레벨: 일반 회원, 황금 회원, 백금 회원, 다이아몬드 회원, 블 루 다이아몬드 회원 2 레벨 제한
디 테 일 구현
  • 먼저 회원 의 업그레이드 전략 이 다 르 기 때문에 앞으로 도 비교적 큰 변화 가 있 을 것 이다. 그러나 두 가지 행 위 를 추상 화 할 수 있다. 회원 이 업그레이드 조건, 업그레이드 논 리 를 가지 고 있 는 지 추상 화 할 수 있 기 때문에 하나의 인터페이스
  • 를 추상 화 할 수 있다.
    namespace app\api\service\vip;
    
    interface IVipUpStrategyBase
    {
        public function up();
    
        public function checkLevel();
    }
    
  • 인터페이스 가 있 으 면 실현 류 가 있어 야 하지만 공용 논리 가 있 을 수 있 음 을 고려 하여 중간 에 Base 류 를 추가 하여 인 스 턴 스 속성
  • 을 탑재 해 야 한다.
    namespace app\api\service\vip;
    
    /**
     * @property VipUpParams $vipUpParams
     */
    class VipUpStrategyBase implements IVipUpStrategyBase
    {
        protected $vipUpParams = null;
    
        /**
         * @var bool        
         */
        protected $isHaveSession = false;
    
        public function checkLevel()
        {
        	//             
            return true;
        }
    
        public function up()
        {
    		//               
        }
    	
    	// VipUpParams               
        public function setVipUpParams(VipUpParams $params)
        {
            $this->vipUpParams = $params;
        }
    }
    

    저의 VipUpParams 예 시 를 드 리 겠 습 니 다.
    class VipUpParams
    {
        //      
        protected $originLevel;
    
        //           
        protected $upLevel;
    
        protected $userInfo;
    
    
        /**
         * @return mixed
         */
        public function getOriginLevel()
        {
            return $this->originLevel;
        }
    
        /**
         * @param mixed $originLevel
         */
        public function setOriginLevel($originLevel)
        {
            $this->originLevel = $originLevel;
        }
    
        /**
         * @return mixed
         */
        public function getUpLevel()
        {
            return $this->upLevel;
        }
    
        /**
         * @param mixed $upLevel
         */
        public function setUpLevel($upLevel)
        {
            $this->upLevel = $upLevel;
        }
    
        /**
         * @return mixed
         */
        public function getUserInfo()
        {
            return $this->userInfo;
        }
    
        /**
         * @param mixed $userInfo
         */
        public function setUserInfo($userInfo)
        {
            $this->userInfo = $userInfo;
        }
    }
    
  • 다음은 전략 류
  • namespace app\api\service\vip\strategyImpl;
    class RegularToPlatinum extends VipUpStrategyBase
    {
        public function up()
        {
            $this->checkLevel();
        }
    }
    

    N 여러 가지 전략 이 있 을 수 있 습 니 다.
    namespace app\api\service\vip\strategyImpl;
    class RegularToGold extends VipUpStrategyBase
    {
        public function up()
        {
            $this->checkLevel();
        }
    }
    
    namespace app\api\service\vip\strategyImpl;
    class RegularToDiamond extends VipUpStrategyBase
    {
        public function up()
        {
            $this->checkLevel();
        }
    }
    

    등등
  • 여러 가지 전략 류 가 있 습 니 다. 그 다음 에 사용자 에 따라 스케줄 링 전략 류 를 입력 해 야 합 니 다. 제 가 있 는 사용자 의 입력 은 두 개 밖 에 없 기 때문에 저 는 Map 류
  • 를 만 들 었 습 니 다.
    namespace app\api\service\vip;
    use app\api\service\vip\enum\VipUpStrategyEnum;
    
    class VipUpStrategyMap
    {
        protected static $map = [
            VipUpStrategyEnum::RegularToPlatinum => 'app\\api\\service\\vip\\strategyImpl\\RegularToPlatinum',
        ];
    
        public static function getMap() {
            return self::$map;
        }
    }
    
    namespace app\api\service\vip\enum;
    class VipUpStrategyEnum
    {
        /**
         *       
         */
        //            
        const RegularToGold = '1-2';
    
        //            
        const RegularToPlatinum = '1-3';
    
        //            
        const RegularToDiamond = '1-4';
    
        //           
        const RegularToBlueDiamond = '1-5';
    
    
        /**
         *         
         */
        //            
        const GoldToPlatinum = '2-3';
    
        //            
        const GoldToDiamond = '2-4';
    
        //              
        const GoldToBlueDiamond = '1-5';
    
    
        /**
         *         
         */
        //            
        const PlatinumToDiamond = '3-4';
    
        //              
        const PlatinumToBlueDiamond = '3-5';
    
        /**
         *         
         */
        //              
        const DiamondToBlueDiamond = '3-5';
    }
    

    물론 가장 중요 한 스케줄 러 dispatcher 는 반사 적 으로 스케줄 링 을 실현 한다
    namespace app\api\service\vip;
    use app\api\service\vip\exceptions\StrategyNotFound;
    
    class VipUpDispatcher
    {
        protected $vipUpParams = null;
    
        public function __construct(VipUpParams $vipUpParams)
        {
            $this->vipUpParams = $vipUpParams;
        }
    
        public function dispatch() {
            $levelStrategy = $this->vipUpParams->getOriginLevel().'-'.$this->vipUpParams->getUpLevel();
            $map = VipUpStrategyMap::getMap();
            if(!isset($map[$levelStrategy]) || empty($map[$levelStrategy])) {
                throw new StrategyNotFound();
            }
            $strategyClass = new \ReflectionClass($map[$levelStrategy]);
            $strategyInstance = $strategyClass->newInstance();
            $strategyInstance->setVipUpParams($this->vipUpParams);
            return $strategyInstance->up();
        }
    }
    
  • 마지막 클 라 이언 트 호출
  • namespace app\api\service\vip;
    use app\api\service\vip\exceptions\StrategyNotFound;
    class Test extends \PHPUnit_Framework_TestCase{
    	public function testMain() {
            $userInfo = \think\Db::name("user")->where('id', '311')->find();
            $originLevel = $userInfo['level'];
            $upLevel = 13;
            $vipUpParams = new VipUpParams();
            $vipUpParams->setOriginLevel($originLevel);
            $vipUpParams->setUpLevel($upLevel);
            $vipUpParams->setUserInfo($userInfo);
            $vipUpDispatcher = new VipUpDispatcher($vipUpParams);
            try {
                $res = $vipUpDispatcher->dispatch();
            } catch (StrategyNotFound $e) {
                $this->error($e->getMessage(), null, $e->getCode());
            }
            $this->success('', $res);
        }
    }
    

    좋은 웹페이지 즐겨찾기