🔖

LINEのメッセージオブジェクトを整理したお話

2020/09/22に公開

今回は新たな機能を実装したお話ではなく、リファクタリングしてちょっとプログラムをきれいにしました.
前回まで機能追加でソースの整理が追いついて無かったので,これからの開発を楽にするためにもしました.

主なリファクタリング内容

大きく変えたのはメッセージオブジェクト周りです.
メッセージオブジェクトとは、送信するメッセージの内容を表すJSONオブジェクトです(公式リファレンス).

今までのソース

送信する度にメッセージオブジェクトを作っては送信してました.
具体的には↓のように実装されてました.

            # メッセージオブジェクトの生成
            message = {
              type: 'text',
              text: sending_message
            }
            # 実際に送信
            client.reply_message(event['replyToken'], message)
            
            # メッセージオブジェクトの生成
            message = {
              type: 'location',
              title: place_name,
              address: address,
              latitude: lat,
              longitude: lng
            }
            # 実際に送信
            client.push_message(accepting_user_id, message)

これだと,何か送信する度に最低4行はメッセージオブジェクト生成のために使うことになり,コードが冗長になります(リファクタリング前は生成するだけで110行25行くらい使ってました).

これからのソース

なので,今後はメッセージオブジェクトを管理するクラスを専用に作って,そこで実際の生成をするようにしました.

下準備

今まで,メッセージオブジェクトはハッシュで設定していたので,まずはクラスをハッシュにしてくれるモジュールを作成します.
ついでに,ログ出力することを視野に入れて,Jsonも生成できるようにします.

messageObject.rb
module MessageObject
  def to_json()
    JSON.generate(self.to_hash)
  end

  def to_hash()
    hash = {}
    self.instance_variables.each do |t|
      key_name = t.to_s.gsub(/@/, '')
      hash[key_name] = self.send(key_name)
    end

    hash
  end
end

クラスの作成

そして,上をprependしたクラスを作成します.

text.rb
require 'json'
require './public/ruby/line_dto/message_object'

class Text
  prepend MessageObject
  attr_reader :type
  attr_accessor :text

  def initialize(text)
    @type = 'text'
    @text = text
  end
end
location.rb
require 'json'
require './public/ruby/line_dto/message_object'

class Location
  prepend MessageObject
  attr_reader :type
  attr_accessor :title, :address, :latitude, :longitude

  def initialize(title, address, lat, lng)
    @type = 'location'
    @title = title
    @address = address
    @latitude = lat
    @longitude = lng
  end
end

インスタンス生成時に引数を設定することで,送信する内容をセットする様にしています.
今のところ,一度インスタンスを生成したら,それを使いまわすイメージにしているので,@type以外はいつでも値をセットできる様になっています.

結果

作ったクラスを利用する様に,今までのソースにある部分を↓の様に修正しました.

            # メッセージオブジェクトの生成
            message = Text.new(sending_message)
            # 実際に送信
            client.reply_message(event['replyToken'], message.to_hash)

            # メッセージオブジェクトの生成
            location = Location.new(place_name, address, lat, lng)
            # 実際に送信
            client.push_message(accepting_user_id, location.to_hash)

とってもスッキリしました.

Discussion