Serverless Framework でじゃんけんのLINEbotを作る(リファクタリング編)

#概要
[一つ前に投稿した記事](https://qiita.com/kouji0705/items/252b8790dfeb148a13c0)のリファクタリング編です。
じゃんけんの勝ち負けを判定するロジックが美しくなかったので、数学的に処理しました。

#アジェンダ
1. 問題の実装
2. 数学的処理
3. リファクタリング

#1. 問題の実装
```javascript:janken.jsの抜粋
/**
 * じゃんけんの勝ち負けを判定します。
 * @param {string} userHand - ユーザの出した手
 * @param {string} cpHand - コンピュータの出した手
 * @return {string} - message 判定結果
 */
//TODO ロジックが美しくない。数学的に処理する方法を後日の記事にする。
function hantei(userHand, cpHand){
  let message = ''

  if(userHand == 'グー'){
    if(cpHand == 'グー'){
      message = 'あいこです。(あなた：'+userHand + '、CP：'+ cpHand +')'
    }else if(cpHand == 'チョキ'){
      message = 'あなたの勝ちです。(あなた：'+userHand + '、CP：'+ cpHand +')'
    }else{
      message = 'あなたの負けです。(あなた：'+userHand + '、CP：'+ cpHand +')'
    }
  }else if(userHand == 'チョキ'){
    if(cpHand == 'チョキ'){
      message = 'あいこです。(あなた：'+userHand + '、CP：'+ cpHand +')'
    }else if(cpHand == 'パー'){
      message = 'あなたの勝ちです。(あなた：'+userHand + '、CP：'+ cpHand +')'
    }else{
      message = 'あなたの負けです。(あなた：'+userHand + '、CP：'+ cpHand +')'
    }
  }else{
    if(cpHand == 'パー'){
      message = 'あいこです。(あなた：'+userHand + '、CP：'+ cpHand +')'
    }else if(cpHand == 'グー'){
      message = 'あなたの勝ちです。(あなた：'+userHand + '、CP：'+ cpHand +')'
    }else{
      message = 'あなたの負けです。(あなた：'+userHand + '、CP：'+ cpHand +')'
    }
  }
  return message
}
```
うーむ、いかにも美しくないですよね。if文の中にif文があって、とても気持ち悪い。:confounded:
なので、数学的に処理してリファクタリングしましょう！！！

#2. 数学的処理
では数学的に処理しましょう。グーやパーなどのテキストデータだと処理しにくいので、数値に変換します。数値に変換した後は法則を見つけるだけです！！詳細は下記の画像の通りです。
![9F1F04C5-EED1-4A8B-94E6-6935CBFC2F26_1_105_c.jpeg](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/599049/15b8e153-bcc1-b7ef-2283-ac48357e2363.jpeg)
はい、画像の通り、判定方法は((自分-相手)+3)%3の結果を見れば判定できることがわかりましたね。では実装していきましょう。

#3.リファクタリング
```javascript:janken.js
'use strict';

// パッケージのインストール
const line = require('@line/bot-sdk');

// LINEアクセストークンの設定
const config = {
  channelAccessToken: 'アクセストークン',
  channelSecret: 'シークレットトークン',
};

// インスタンス化
const client = new line.Client(config);

exports.webhook = async (event, context) => {

  /* リクエストボディ*/
  const body = JSON.parse(event.body)
  /* Lineのevent情報*/
  const response = body.events[0]
  /* ユーザの出した手を取得*/
  const userHand = response.message.text
  /* コンピュータの出した手を取得 */
  const cpHand = getCpHand()

  let message = hantei(userHand, cpHand)
  /* メッセージ送信のために必要な情報 */
  const replyToken = response.replyToken
  console.log('replyToken:' + replyToken)
  const post = {
    type: 'text',
    text: message,
  }

  try {
    await client.replyMessage(replyToken, post)
  } catch (err) {
    console.log(err)
  }
};

/**
 * コンピュータの手を決定します。
 * @return {string} cpHand - コンピュータの手
 */
 function getCpHand(){
  /**ランダム数値を取得(範囲：0~2) */
  let num = Math.floor(Math.random() * 3)
  let cpHand = ''
  if(num ==0){
    cpHand = 'グー'
  }else if(num ==1){
    cpHand = 'チョキ'
  }else{
    cpHand = 'パー'
  }
  return cpHand
}

/**
 * じゃんけんの勝ち負けを判定します。
 * @param {string} userHand - ユーザの出した手
 * @param {string} cpHand - コンピュータの出した手
 * @return {string} - message 判定結果
 */
function hantei(userHand, cpHand){
  let message = ''
  /**ユーザの手を数値化する。(グー：0、チョキ：1、パー：2) */
  const userHandNum = transformHand(userHand)
  /**コンピュータの手を数値化する。(グー：0、チョキ：1、パー：2) */
  const cpHandNum = transformHand(cpHand)
  /**判定値を算出((自分の手 - 相手の手)+3)%3 */
  const hanteiNum = ((userHandNum - cpHandNum)+3)%3

  if(hanteiNum == 0){
    message = 'あいこです。(あなた：'+userHand + '、CP：'+ cpHand +')'
  }else if(hanteiNum == 1){
    message = 'あなたの負けです。(あなた：'+userHand + '、CP：'+ cpHand +')'
  }else{
    message = 'あなたの勝ちです。(あなた：'+userHand + '、CP：'+ cpHand +')'
  }
  return message
}
/**
 * じゃんけんの手を数値化します。
 * @param {string} userHand - ユーザの出した手
 * @return {num} - userHandNum ユーザの手の数値
 */
function transformHand(userHand){
  let userHandNum 
  if(userHand == 'グー'){
    userHandNum = 0
  } else if(userHand == 'チョキ'){
    userHandNum = 1
  }else{
    userHandNum = 2
  }
  return userHandNum
}
```