Command

7/16/2021 OOPPatternBehavioral pattern

# Description

Command is behavioral design pattern that converts requests or simple operations into objects.

  • Chuyển request thành object

# Example

Xử lí lưu post với các trạng thái yêu cầu là draft, no approval, pusblish,..

  1. Class xử lí business logic cho post:

    class PostReceiver
    {
    	public function draft() 
    	{
    		// do something
    	}
        
        public function noApproval() 
    	{
    		// do something
    	}
        
        public function publish() 
    	{
    		// do something
    	}
    }
    
    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    13
    14
    15
    16
    17
  2. Command:

    interface Command
    {
    	public function excute();
    }
    
    1
    2
    3
    4
  3. Concreate command: class implement command define thực thi của Receiver tương ứng với case request.

    class DraftCommand implements Command
    {
        protected PostReceiver $receiver;
    
        public function __construct(PostReceiver $receiver)
        {
            $this->receiver = $receiver;
        }
    
        public function execute()
        {
            $this->receiver->saveDraft();
        }
    }
    
    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    13
    14
    class NoApprovalCommand implements Command
    {
        protected PostReceiver $receiver;
    
        public function __construct(PostReceiver $receiver)
        {
            $this->receiver = $receiver;
        }
    
        public function execute()
        {
            $this->receiver->saveNoApproval();
        }
    }
    
    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    13
    14
    class PublishCommand implements Command
    {
        protected PostReceiver $receiver;
    
        public function __construct(PostReceiver $receiver)
        {
            $this->receiver = $receiver;
        }
    
        public function execute()
        {
            $this->receiver->savePublish();
        }
    }
    
    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    13
    14
  4. Invoker: Liên kết với command, gửi request đến command.

    class Invoker
    {
        private Command $command;
    
        public function setCommand(Command $cmd)
        {
            $this->command = $cmd;
        }
    
        public function run()
        {
            $this->command->execute();
        }
    }
    
    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    13
    14
  5. Usage:

    $invoker = new Invoker();
    $postReceiver = new PostReceiver();
    
    $invoker->setCommand(new DraftCommand($postReceiver));
    $invoker->run();
    
    1
    2
    3
    4
    5

→ Dễ dàng thêm các command mới mà vẫn tuân thủ Open/Closed Principle . → Dễ thực hiện unit testing.