Commandパターン

 

どうも。
最近、蒙古タンメンにハマりすぎて困っています。
麻婆麺が辛すぎて病みつきになります。

 

 

Commandパターン
を見ていきます。

Commandパターンの定義

リクエスト(命令)をオブジェクトとしてカプセル化し、
その結果、他のオブジェクトを異なるリクエスト、キュー
またはログリクエストなどでパラメータ化でき、
アンドゥ可能な操作もサポートする。
= リクエストをオブジェクトでカプセル化する。
= クライアントはいろんなリクエストを持つことができる。(→使える)

 

クラス図

縦長。。。

 

・Command
…全てのコマンド(オブジェクト)のためのインターフェースを定義する。

 

・ConcreteCommand
…Receiverとaction()の結びつきを(execute()に)定義する。
Invokerがexecute()することで
ConcreteCommandへリクエストを行い、
ConcreteCommandがReceiverの
1つ以上のaction()を呼び出すことでそれを実行する。

 

・Invoker
…コマンド(オブジェクト)を保持し、
ある時点でのコマンドのexecute()を呼び出すことで
コマンド(オブジェクト)にリクエストを実行するよう依頼する。
様々なコマンド(オブジェクト)をパラメタ化して保持できるが、
具体的なコマンド(オブジェクト)の内容は知らない。
(Commandインターフェースを実装している何かだと知っている程度)

 

・Receiver
…制御されるもの(制御対象)

・Client

 

具体的に…

この章でのは
「複数の電化製品のon/offを制御できるリモコン」
でした。

 

PHPで書いたみたコード

 

・Command
…制御したい命令を定義するインターフェース

・LightOnCommand / LightOffCommand [ConcreteCommand]
…具体的に制御対象であるライトの
制御(点けたり消したりする)方法がここにある

・RemoteControl [Invoker]
…制御対象(Receiver)をsetCommandで設定したり、
実際に制御するコントローラー
複数の制御対象をセットできる。

・Light [Receiver]
…制御対象となるライト

・RemoteLoader [Client]

 

いいところ

Invoker(RemoteControl)自体が
制御するReceiver(Light)を知っている場合、
Receiverが増えるたびに、if文で追記する形になってしまう。

RemoteControl.php

  if($receiver == 'Light') {
   $receiver.on();

  } else if($receiver == 'Door') {

   $receiver.open();

- }
+ //制御対象「Sprinkler」の追加
+ } else if($receiver == 'Sprinkler') {
+
+  $receiver.waterOn();
+
+ }

 


↓ Commandパターンを使うと…

 

Invoker(RemoteControl)は
具体的なコマンドオブジェクトの内容を知らずして
(インターフェスは知ってる)、
コマンドオブジェクトに具体的な処理(制御)を依頼できるので、
Invoker(RemoteControl)とReceiver(Light)を分離することができる。
= 各々の役割分担ができる。

RemoteControl.php
※Receiver(LightやDoorなど)について全く出てこない。

use HFD\Command\Command\Command;
use HFD\Command\Command\NoCommand;

class RemoteControl
{
    /**
     * @var Command[]
     */
    public $onCommands;

    /**
     * @var Command[]
     */
    public $offCommands;


    public function __construct(int $commandCnt)
    {
        for ($i = 0; $i < $commandCnt; $i++) { $this->onCommands[] = new NoCommand();
            $this->offCommands[] = new NoCommand();
        }
    }

    public function setCommand(int $slotNum, Command $onCommand, Command $offCommand): void
    {
        $this->onCommands[$slotNum] = $onCommand;
        $this->offCommands[$slotNum] = $offCommand;
    }

    public function onButtonWasPushed(int $slotNum): void
    {
        $this->onCommands[$slotNum]->execute();
        $this->undoCommand = $this->onCommands[$slotNum];
    }

    public function offButtonWasPushed(int $slotNum): void
    {
        $this->offCommands[$slotNum]->execute();
        $this->undoCommand = $this->offCommands[$slotNum];
    }
}

 
制御対象が増える可能性がある時の
拡張性を考えた時に良さそうなパターンですね!
 

 

 

 

 

slackコマンドを作ってみた!

どうも、今週は#Webナイト宮崎でLTしてきました!
そのLTの内容を書きます!

にしても、connpassのプロフィールにLTする人の一覧がありますが、
自分のアイコン画像(Facebookの)が高校の時の写真なので
そろそろ変えないとですね

 

本題に入ります!

今回は、heroku(+SendGrid) +  PHP + slack
でslackコマンドを作ってみました。
ソースはこちら→[kin29/slack_command]

 

こんなslackコマンド

slackの投稿エリアにて、

/(設定したcommand) [メール件名]|[メール内容]

と入力し、エンターを押すと、

1. herokuサーバにキックされる。
2. herokuのadd-onであるSendGridから、メールを送信する。
送信先:WordPressメール投稿機能(プラグインPostie)で設定されたメールアドレス
2′. WordPress(ブログ)に記事が下書きの状態で投稿される。
3.メール送信結果を、slackに投稿する、

 

使ったもの

– Slack

– heroku
今回はPHP 7.2.12を使用しました。

– SendGrid…メール機能が使えるherokuのadd-onです。
freeプランがあり、最大12,000通/月送信することができます。
※herokuはデフォルトでメール機能が使えません。

 

作った理由

私はブログを週1は更新する!という目標があります。
そこで、ブログ(kin29.info)のネタを
忘れないうちに、サクッと貯めておきたかったので作りました。

slackで技術的なお話をしてる時や、
レビューの返しなどをもらった時に
「これ使える!」ってネタが思くので、
その時に使いどきかなって思います!

 

作り方

ソースはこちら→[kin29/slack_command]

 

1.heroku経由でSendGridを導入する。

  • herokuダッシュボードよりCreate new appを押下し、
    プロジェクトを作成します。
    プロジェクト名がサブドメインになります。
    イメージ:https://[プロジェクト名].herokuapp.com/
  • herokuダッシュボード > Resources > Add-onsにて、
    「SendGrid」を検索し導入する。
    Starter – Free(送信通数上限12,000通/月)を選択し、
    Provisionを選択。
  • SendGridダッシュボード > 左ナビのSettings > API Keys より
    「Create API Key」を押下する。
    ※API Keyはコピーしておく。

 

2.slack app を新規作成する。

https://api.slack.com/apps より、Create New Appを押下する。

  1. AppName と 導入するSlack Workspaceを選択する。
    ※Verification Tokenをコピーしておく。
  2. Slash Commands の設定
    – Command :設定したいslack コマンド
    – Request URL :commandが投稿された時に実行されるURL
  3. Install Appより、「Install App to Workspace」を押下する。
    → Incoming Webhookが設定されます。
    メール送信結果を投稿するslackチャンネルを選択し、
    投稿をAuthorize(許可)する。
    ※Webhook URL をコピーしておく。

 

3.heroku でデプロイ

  1. コードを書く → [kin29/slack_command]
  2. herokuダッシュボード > Setting > Config Varsより
    環境変数を設定する。
  3. herokuダッシュボード > Deploy よりデプロイする。
    Heroku Git(Githubでもできます。)
    $ git push heroku master  //これでデプロイされます。
  4.  

    4.Postie(WordPressプラグイン)を導入し、メール投稿設定をする

    Postieは、WordPressのプラグインです。
    これにより、メール投稿を使って
    Wordpressに記事を投稿することができます。

    参考:http://nb-style.info/?p=3072

     

    !!完成!!

     

    最後に

    もっともっとslackコマンドつくって、
    作業時短化や自動化していきたいです!