銀行員からのRailsエンジニア

銀行員からのRailsエンジニア

銀行員から転身したサービス作りが大好きなRailsエンジニアのブログです。個人で開発したサービスをいくつか運営しており、今も新しいサービスを開発しています。転職して日々感じていること、個人開発サービス運営のことなどを等身大で書いていきます。

当ブログではアフィリエイト広告を利用しています

リモートワークでのデスク環境の紹介

リモートワークが始まって3ヶ月目に入りました。

自宅のデスク環境をコツコツ改善してきた結果、ある程度完成したのでブログにまとめてみます。

色々とこだわった結果、会社の環境より快適になってしまいました(笑)

全体像

f:id:ysk_pro:20200509094913j:plain

ポイントはカービィの卓上扇風機と子パンダのぬいぐるみです!かわいい!

それ以外にもこだわった部分があるので1つずつ紹介していきます。

デスク

電動の昇降デスクを使っています。

元々「立って作業するとかつらそう」派だったのですが、職場の昇降デスクで立って作業をしてみたら、思いのほか集中できて良かったので家でも買っちゃいました。

午後は(眠いので)基本立つようにしています。

足つぼを刺激するスリッパと合わせるのがおすすめです。

メガ押しふみっぱ ピンク(グイグイインソール)

メガ押しふみっぱ ピンク(グイグイインソール)

  • 発売日: 2016/09/05
  • メディア: ヘルスケア&ケア用品
 

チェア

定番のアーロンチェアを使っています。

1年半前に新宿の大塚家具にチェアの下見のつもりで行ったのですが、気がついたときには買っちゃってました。それぐらい座り心地が良かったです。

もともとよく腰を痛めていた僕が、アーロンチェアを使い始めてから1度も腰が痛くなっていないのは割と快挙です。20万円くらいしましたが買って良かったです。

リモートワークになる前は、僕と同じくエンジニアである妻と1台を順番に使っていましたが、2人ともリモートワークとなったのでもう1台買い足しました。

アーロンチェアは3サイズあり、僕は身長172cmで中間のBサイズ、妻は身長158cmで一番小さいAサイズがちょうど良いです。

モニター

右から 24インチ、21インチ、13インチの3画面構成です。

2画面でも十分だと思っていましたが、3画面にしてみるともう2画面には戻れないくらい快適です。

真ん中のモニターはモニターアームで固定しており、モニターの下のスペースが空いてスッキリしています。

HP 9YF44AA#ABJ HP 21.5インチワイドIPSモニター P224

HP 9YF44AA#ABJ HP 21.5インチワイドIPSモニター P224

  • メディア: エレクトロニクス
 
Herman Miller Flo Single Monitor

Herman Miller Flo Single Monitor

  • メディア: Personal Computers
 

キーボード

僕が一番気に入っているポイントがこのキーボードです!

BAROCCOの分離型キーボードを使っています。

軸は、このキーボードの前のモデルで茶軸を使っていて音が気になったので、静音赤軸にしました。

両手を机に置いた自然な姿勢でタイピングできるのがとっても楽です。あまり肩こりに悩んだことがないのですが、このキーボードのおかげなんじゃないかなーと思っています。

しかもこのキーボード、光らせることもできます...!光らせ方もパターンを変えることができて、僕は押したキーがカラフルに光る設定にしています。

分離キーボードの間にトラックパッドとノートを置くと、いい感じに収まって使いやすいので便利です。

Apple Magic Trackpad 2 - スペースグレイ

Apple Magic Trackpad 2 - スペースグレイ

  • 発売日: 2018/05/16
  • メディア: Personal Computers
 

ケーブルの収納

デスクの裏のケーブル収納部分

机の裏にケーブルトレーを取り付けて、その上に延長コードを置いています。

また、机の裏に複数箇所にケーブルクリップをつけて、ケーブルをそこを通してなるべく机の裏を這わせるようにしています。

こうすることで、正面からはほとんどケーブルが見えなくなります。

元々延長コードを下に置いていたのですが、ケーブルトレーとケーブルクリップを使うことで見た目もよくなり掃除もしやすくなりました。

macに接続しているtype-cケーブルは、macを持ち運ぶ時のために机の横にマグネットでつけられるようにしています。

デスクの横にケーブルをマグネットでつけている画像

プラス Garage 配線ケーブルトレー 幅40cm レッド 434665

プラス Garage 配線ケーブルトレー 幅40cm レッド 434665

  • 発売日: 2020/02/10
  • メディア: オフィス用品
 

おまけ(ホームジム環境)

ジムを解約して、ホームジムを作りました!

ホームジムの写真

家にあることで必ず目に入り、毎日欠かさずやるようになって筋肉量は着実にアップしている気がします。

このダンベルは優れもので、ダイヤルを回すだけで重さが変えれて最高です。

おわりに

デスク環境整えるの楽しいですよね〜!

ちなみに最初に紹介したカービィの卓上扇風機はUFOキャッチャーでめっちゃ頑張って取った非売品です!と思ってたらAmazonに普通にありました... 

これからも継続的にデスク環境の改善をしていくつもりです。(今気になっているのは、4Kディスプレイ と zoom会議用のマイク と Bluetoothスピーカーです)

オススメのグッズなどあれば是非教えてください!

(追記)

デスクをリニューアルして記事を書いたので、ぜひ合わせてご覧ください。

ysk-pro.hatenablog.com

nullオブジェクトの導入【リファクタリング Rubyエディションまとめ4】

こんにちは。

最近 リファクタリング Rubyエディション を読みました。本書は、復刻版が最近発売された名著でリファクタリングの様々なパターンRubyのサンプルコードを使って解説しています。

本書の中でいいなと思ったパターンを1つずつブログにまとめています。

今回はその第4弾で「nullオブジェクトの導入」についてまとめました。
オリジナルの Ruby のサンプルコードを使って説明しています。

第3弾の「継承から委譲へ」のまとめはこちらです。
継承から委譲へ【リファクタリング Rubyエディションまとめ3】 - 銀行員からのRailsエンジニア

f:id:ysk_pro:20200508074431p:plain

「nullオブジェクトの導入」とは

サンプルコードを見ていく前に簡単に説明します。

概要

まず「nullオブジェクト」というのは、オブジェクトが nil だった場合の処理を集めたクラスから作られたオブジェクトを指します。

オブジェクトが nil だった場合に、代わりに null オブジェクトの同名のメソッドを呼び出すことで、メソッド呼び出しするだけで処理を分けることができ、オブジェクトの nil チェックが不要になります。

※ null と nil は同じで、一般的な名称が null、Ruby内での呼び方が nil というだけです。

どんな時に使えるか

オブジェクトが nil の場合は別の値を入れる処理を繰り返している場合に有効です。

メリット

nilチェックが不要になります。

ポリモーフィズムを利用することで、よりオブジェクト指向らしいコードになります。

ポリモーフィズムの本質は、オブジェクトにどのようなタイプ(型)なのかを尋ね、その答に基づいてなんらかのメソッドを呼び出すようなことをせずに、単純にメソッドを呼び出すことである。呼び出されたオブジェクトは、自分の型に基づいて適切な処理を行う。
リファクタリング Rubyエディションから抜粋)

サンプルコード

リファクタリング

サンプルコードを見ていきましょう。
まずはリファクタリング前のコードです。

class Gym
  attr_reader :name, :trainer

  def initialize(name, trainer=nil)
    @name = name
    @trainer = trainer
  end
end

class Trainer
  attr_reader :name, :muscle_quantity

  def initialize(name, muscle_quantity)
    @name = name
    @muscle_quantity = muscle_quantity
  end
end

muscle_trainer = Trainer.new('マッチョトレーナー', 100)
gold_gym = Gym.new('ゴールドジム', muscle_trainer)
joyfit = Gym.new('ジョイフィット')

# それぞれのジムのトレーナー情報を出したい
gyms = [gold_gym, joyfit]
gyms.each do |gym|
  puts "#{gym.name}: #{gym.trainer&.name || 'トレーナー不在'} / 筋肉量: #{gym.trainer&.muscle_quantity || 0}"
  # nilチェックが多くなってつらい
end

見ての通り、筋肉量100のマッチョなトレーナーがいるゴールドジムとトレーナーが不在のJOYFITがあって、それぞれのジムのトレーナー情報を出力するプログラムです。

ゴールドジムのトレーナーは本当にマッチョでした。

上記のプログラムを実行すると、結果は下記の通りとなります。

ゴールドジム: マッチョトレーナー / 筋肉量: 100
ジョイフィット: トレーナー不在 / 筋肉量: 0

トレーナー情報を出力する部分で、nil チェックが多くてつらくなっていますね。

リファクタリング

「nullオブジェクトの導入」を使ってリファクタリングすると次のようになります。

class Gym
  attr_reader :name, :trainer

  def initialize(name, trainer=nil)
    @name = name
    @trainer = trainer || NoTrainer.new # trainerがnilの時にnullオブジェクト生成 
  end
end

class Trainer
  attr_reader :name, :muscle_quantity

  def initialize(name, muscle_quantity)
    @name = name
    @muscle_quantity = muscle_quantity
  end
end

class NoTrainer
  def name
    'トレーナー不在'
  end

  def muscle_quantity
    0
  end
end

muscle_trainer = Trainer.new('マッチョトレーナー', 100)
gold_gym = Gym.new('ゴールドジム', muscle_trainer)
joyfit = Gym.new('ジョイフィット')

# それぞれのジムのトレーナー情報を出したい
gyms = [gold_gym, joyfit]
gyms.each do |gym|
  puts "#{gym.name}: #{gym.trainer.name} / 筋肉量: #{gym.trainer.muscle_quantity}"
end

実行結果はリファクタリング前と同じになります。

Gymクラスのコンストラクタで、trainer が nil の場合に @trainer に null オブジェクト(NotTrainer.new)を入れることによって、nil チェックではなくシンプルなメソッド呼び出しで nil の場合の条件分岐が実現できていますね。

おわりに

ここまでお読みいただきありがとうございます。

Rubyのコードで nil チェックを行なっている箇所は多いと思うので、「nullオブジェクトの導入」というリファクタリングを覚えておくとリファクタリングの引き出しが増えますね。

リファクタリング Rubyエディションでは、もう少しリアルなサンプルケースを使って説明していてとても分かりやすかったので、ご興味ある方は是非ご覧ください。

次回はまた違うパターンをまとめていきます!

(追記)
第5弾として「タイプコードからポリモーフィズムへ」についてまとめました。
是非合わせてご覧ください。
ysk-pro.hatenablog.com

継承から委譲へ【リファクタリング Rubyエディションまとめ3】

こんにちは。

最近 リファクタリング Rubyエディション を読みました。本書は、復刻版が最近発売された名著でリファクタリングの様々なパターンRubyのサンプルコードを使って解説しています。

紹介されているリファクタリングのパターン数は膨大で全てをまとめるのは難しいので、いいなと思ったパターンを1つずつブログにまとめています。

今回はその第3弾で「継承から委譲へ」についてまとめます。
オリジナルの Ruby のサンプルコードを使いながら説明しています。

第2弾の「モジュールの抽出」のまとめはこちらです。
モジュールの抽出【リファクタリング Rubyエディションまとめ2】 - 銀行員からのRailsエンジニア

f:id:ysk_pro:20200505075342p:plain

「継承から委譲へ」とは

概要

継承を使っていた箇所を、継承の関係を解消して委譲を使うようにするリファクタリングです。

どんな時に使えるか

継承関係にあるものの、サブクラスがスーパークラスのインターフェースの一部しか使っていなかったり、スーパークラスのメソッドの多くがサブクラスにうまくかみ合っていない時に有効となります。

どのようにリファクタリングするか

サブクラスにスーパークラスのためのフィールドを作り、スーパークラスに処理を委譲するようにして、継承構造を解消します。

メリット

不要なメソッドを継承することがなくなり、予期せぬ副作用を防ぎつつコードの共通化を維持することができます。

サンプルコード

リファクタリング

サンプルコードを見ていきましょう。
こちらはリファクタリング前のコードです。

class Tasks < Array
  def finish(task)
    puts 'Well done!'
    delete(task)
  end

  def list
    each { |task| puts task }
  end
end

Array クラスを継承した Tasks クラスを作ってみました。

tasks = Tasks.new
tasks.push('clean room')
tasks.push('study ruby')

tasks.list
tasks.finish('clean room')
tasks.list

上記のように実行すると、下記の結果になります。

clean room
study ruby
Well done!
study ruby

Array クラスを継承してしていますが、Array クラスの一部のメソッド(push, delete, each)しか使っていませんね。

Tasks クラスに必要なメソッドのみを使えるよう、委譲を使ってリファクタリングしてみましょう。

リファクタリング

「継承から委譲へ」を使ってリファクタリングすると次のようになります。

require 'forwardable'

class Tasks
  extend Forwardable

  def_delegators :@tasks, :each, :delete, :push

  def initialize
    @tasks = [] # Array.new でも同じ
  end

  def finish(task)
    puts 'Well done!'
    delete(task)
  end

  def list
    each { |task| puts task }
  end
end

実行方法、結果はリファクタリング前と同じになります。

Tasks クラスは Array クラスを継承しなくてよくなり、Array クラスで初期化したインスタンス変数である @tasks に処理を委譲することで、Array クラスのメソッドを利用できています。

これで不要なメソッドの継承は防ぎつつ、利用したい Array クラスのメソッドを使えるようになりました

委譲の部分は、Forwardable モジュールの def_delegators メソッドを使うことで実現しています。

おわりに

ここまでお読みいただきありがとうございます。

継承関係がいいのか、委譲を使った方がいいのかは難しく、コードの増加とともに変更したくなるケースもあると思うので、この方法は覚えておくと役立ちそうですね。

リファクタリング Rubyエディションでは、Hashクラスを継承しているサンプルコードで丁寧に解説されていてとても分かりやすかったので、ご興味ある方は是非ご覧ください。

次回はまた違うパターンをまとめていきます!

(追記)
第4弾として「nullオブジェクトの導入」についてまとめました。
是非合わせてご覧ください。
ysk-pro.hatenablog.com

モジュールの抽出【リファクタリング Rubyエディションまとめ2】

こんにちは!

最近 リファクタリング Rubyエディション を読み始めました。本書は、復刻版が最近発売された名著でリファクタリングの様々なパターンをRubyのサンプルコードと共に紹介しています。

紹介されているリファクタリングのパターンの数は膨大なので、いいなと思ったパターンを1つずつブログにまとめています。

今回はその第2弾で「モジュールの抽出」についてまとめます。

第1弾の「委譲の隠蔽」のまとめはこちらです。
委譲の隠蔽【リファクタリング Rubyエディションまとめ1】 - 銀行員からのRailsエンジニア

f:id:ysk_pro:20200502084917p:plain

リファクタリング前のコード

早速サンプルコードを見ていきましょう。
こちらはリファクタリング前のコードです。

ItemクラスとUserクラスで、インスタンスの保存の前にデフォルトの名前を設定しています。

class Item < ApplicationRecord
  #・・・
  before_save :set_default_name

  def set_default_name
    self.name = default_name
  end
  #・・・
end

class User < ApplicationRecord
  #・・・
  before_save :set_default_name

  def set_default_name
    self.name = default_name
  end
  #・・・
end

このコードの問題点は、言うまでもなくコードが重複している点です。

ただ、set_default_name というメソッドは、Itemクラス・Userクラスそれぞれのインスタンスを更新しているため、別のクラスに共通のメソッドを作ってそのクラスのインスタンスに処理を委譲するというやり方ではうまくいきません。

今回のような、通化したいコードがそれぞれのクラスでしか意味を持たないケースで「モジュールの抽出」は有効です。

モジュールの抽出を使ったリファクタリング

モジュールの抽出を使ったリファクタリング後のコードはこのようになります。
Itemクラス、Userクラスでは新しく作った SetDefaultNameモジュールをincludeしているだけでとてもシンプルですよね。

module SetDefaultName
  def self.included(klass) # ①
    klass.class_eval do # ②
      before_save :set_default_name
    end
  end

  def set_default_name
    self.name = default_name
  end
end

class Item < ApplicationRecord
  #・・・
  include SetDefaultName
  #・・・
end

class User < ApplicationRecord
  #・・・
  include SetDefaultName
  #・・・
end

includedメソッド は、モジュール(今回だとSetDefaultName)が include された時に、include をしたクラス(今回だと Item, User)を引数に実行されるメソッドです。

class_evalメソッド は、ブロックに記載したメソッドをレシーバ(このコードだと klass)内に定義してくれるメソッドです。

つまり self.included メソッドでは、SetDefaultName モジュールが include されるタイミングで、include したクラスに before_save :set_default_name を定義しているのです。

「モジュールの抽出」という名前は、単に共通の処理をモジュールにして抽出していることを表しており、シンプルで覚えやすいですね。

おわりに

ここまでお読みいただきありがとうございます。

includedメソッドを使ってモジュールが include されたタイミングでメソッドを定義する方法は、知っておかないとこの方法を使っているコードを読むのが難しいので、覚えておいて損はないと思います。

このブログのサンプルコードは、全く同じではないもののリファクタリング Rubyエディションのサンプルコードを参考にさせていただきました。本書の中では、さらに丁寧に解説されていてとても分かりやすいので、ご興味ある方は是非ご覧ください。

次回はまた違うパターンをまとめていきます!

(追記)
第3弾として「継承から委譲へ」についてまとめました。
是非合わせてご覧ください。
ysk-pro.hatenablog.com

委譲の隠蔽【リファクタリング Rubyエディションまとめ1】

こんにちは。ゆうすけです。

先日ついに Rubyによるデザインパターン を読み終えた(!)ので、次は リファクタリング Rubyエディション を読み始めました。

リファクタリング Rubyエディションは、復刻版が最近発売された名著でリファクタリングの様々なパターンをRubyのサンプルコードと共に紹介していく形式です。

パターンの数は膨大なので、いいなと思ったパターンを1つずつブログにまとめていこうと思います。

今回はその第一弾で「委譲の隠蔽」についてまとめます。

問題のあるコード

例えば、こんなコードがあったとします。

class Article
  attr_accessor :blog
end

class Blog
  attr_reader :writer

  def initialize(writer)
    @writer = writer
  end
end

前提として、ブログ(Blog)の中にたくさんの記事(Article)があり、同じブログに属している記事の作者は同じとします。

ある記事の作者(writer)が知りたい場合は、下記の実行コードの「article1.blog.writer」のように呼び出す必要があります。

article1 = Article.new
blog1 = Blog.new('ブロガーくん')
article1.blog = blog1

puts article1.blog.writer # -> ブロガーくん

このコードだと、呼び出す側が「作者の管理はブログが行なっている」という知識を持っている必要があります。(言い換えると、article1.blog.writer という呼び出し方を知っている必要があるということ)

知識が必要だということは、呼び出す側からブログクラスへの依存が生じており、ブログクラスに変更があった際には呼び出す側にも影響が生じてしまいます。辛いですね。。

委譲の隠蔽を使ったリファクタリング

これを、記事クラスに簡単な委譲メソッド(writer メソッド)を作って改善します。

class Article
  attr_accessor :blog

  def writer
    blog.writer
  end
end

class Blog
  attr_reader :writer

  def initialize(writer)
    @writer = writer
  end
end

こうすることによって、下記実行コードのように「article1.writer」と呼び出せるようになり(ブログクラスへの処理の委譲を記事クラスが隠蔽している!)、「作者の管理はブログが行なっている」という知識を呼び出す側が持つ必要がなくなります。(言い換えると、article1.writer と呼び出せばいいことだけを知っていればよいということ)

先ほどの問題点をクリアしていますね!

article1 = Article.new
blog1 = Blog.new('ブロガーくん')
article1.blog = blog1

puts article1.writer # -> ブロガーくん

図で表すとこのようなイメージです。
矢印の向いた先に依存していることを示しています。

依存関係を表した図

図から分かるように、呼び出し側からブログクラスへの依存がなくなり、ブログクラスの変更の影響を呼び出し側が受けなくなりました。これは嬉しいですね。

「委譲の隠蔽」とは、元々は記事クラスが作者を取得するための処理をブログクラスに委譲していたところを、記事クラスの writer メソッドに隠蔽した(呼び出す側から分からなくした)という意味です。

Forwardableモジュールを使うと

やっていることは同じなのですが、Ruby標準ライブラリに含まれている Forwardable モジュールを使うことで以下のように書くこともできます。

require 'forwardable'

class Article
  extend Forwardable

  def_delegator :blog, :writer

  attr_accessor :blog
end

class Blog
  attr_reader :writer

  def initialize(writer)
    @writer = writer
  end
end

def_delegator は、2つ目の引数のメソッド(この場合は writer)を1つ目の引数のオブジェクト(この場合は blog)へ委譲します。

よりスッキリしていい感じですね。

おわりに

ここまでお読みいただきありがとうございます。

サンプルコードと依存関係の図は リファクタリング Rubyエディションを参考にさせていただきました。本書の中では、Person クラスと Department(部門)クラスの関係を例に説明しています。

「委譲の隠蔽」使えそうですね。

次回はまた違うパターンをまとめていきます!

(追記)
第2弾として「モジュールの抽出」についてまとめました。
是非合わせてご覧ください。
ysk-pro.hatenablog.com

Rubyによるデザインパターンのまとめ【各パターンをオリジナルのコードで説明】

こんにちは。

「綺麗なコードを書く」って難しくないですか?僕は結構悩んでます。

そんな「コードの品質向上」という僕の課題に対し、マネージャーからデザインパターンを勉強してみては」とアドバイスをいただき、「Rubyによるデザインパターン」で紹介されているデザインパターンを毎週1つずつアウトプットしはじめました。

やりはじめてから5ヶ月経ち、 Rubyによるデザインパターン で紹介されている16パターン全てをアウトプットし終えたので、まとめておこうと思います。

ほとんどの記事の中でオリジナルのコードを使って説明しているので、気になるデザインパターンがあれば見てみてください。文章での説明よりもコードを見た方がわかりやすいと思います。

f:id:ysk_pro:20200321134222p:plain

 

デザインパターンの概要

Template Method パターン

基底クラスに骨格となる抽象的な処理を書き、サブクラスに具体的な処理を定義するパターンです。

アルゴリズムに多様性を持たせたい場合に便利なパターンで、不変となる部分は基底クラスに書き、変わる部分はサブクラスのメソッドに定義します。

Javaなどでサポートされている抽象メソッドや抽象クラスはRubyではサポートされていないので、呼び出した時に例外を投げるようにして擬似的に抽象メソッドを実装します。

最近ハマっている筋トレネタのサンプルコードで説明しています → 【Rubyによるデザインパターンまとめ1】テンプレートメソッド / Template Method - 銀行員からのRailsエンジニア

 

Strategyパターン

アルゴリズムの変化する部分をクラスに閉じ込めて、アルゴリズムを実行する際はそのクラスに処理を委譲するパターンです。

アルゴリズムに多様性を持たせたい場合に利用するのはTemplateメソッドパターンと同じですが、Strategyパターンは継承を使わずに実現することができます。(Templateメソッドパターンは継承を使っており、継承にはサブクラスがスーパークラスに依存してしまうというデメリットがあります)

Strategyパターンの「Strategy(戦略)」は、アルゴリズムのことです。Strategyパターンという名前は、変化するアルゴリズム(=Strategy)を、クラスに閉じ込めてそのアルゴリズムを使うオブジェクトに引き渡すことからこの名が付けられたそうです。

僕の好きなスポーツネタのサンプルコードで説明しています →【Rubyによるデザインパターンまとめ2】ストラテジーパターン - 銀行員からのRailsエンジニア

 

Observerパターン

あるオブジェクトの状態が変化した時に、そのオブジェクトが変化したことを知る必要があるオブジェクトに通知をすデザインパターンです。

Rubyによるデザインパターン では次のように説明されていました。

GoFは「何らかのオブジェクトが変化した」というニュースの発信者と消費者の間に綺麗なインターフェイスを作るアイデアを、Observerパターンと呼んでいます。

GoFとは、ギャング オブ フォーの略でデザインパターンを広めた「オブジェクト指向における再利用のためのデザインパターン」の4人の著者のことです)

変化したという通知を受け取るオブジェクトのことを「Observer」(観察者)と呼ぶことから、Observerパターンと名付けられました。

ECサイトの通知を題材にしたサンプルコードで説明しています →【Rubyによるデザインパターンまとめ3】オブザーバーパターン - 銀行員からのRailsエンジニア

 

Compositeパターン

あるものと、それが集まってできたものを同じように扱うことができるデザインパターンです。

例えば、会社は人が集まって課ができており、課が集まって部ができており、部が集まって会社ができています。人が会社から給料を受け取っているのと同じように、人の集まりである課や部も会社から給料を受け取っていると考えることができ、人・課・部が受け取っている給料を共通のインターフェースで扱うことができるイメージです。

Rubyによるデザインパターン のこちらの説明はわかりやすかったです。

GoF「全体が部分のように振る舞う」という状況を表すデザインパターンを、Compositeパターンと呼んでいます。Compositeパターンは、階層構造やツリー構造のオブジェクトを作りたいとき、そしてそのツリーを利用するコードが1つの単純なオブジェクトを扱っているのか、それともごちゃごちゃした枝全体を扱っているのかを考えさせたくないときに利用できます。

親となるオブジェクトのメソッドを呼び出すことで、子オブジェクトの同じメソッドを再帰的に呼び出すケースでよく使われます。会社の例だと、部の給料を求めるメソッドを呼び出すことで、課・人の給料を求めるメソッドを呼び出し、それを集計して値を返すイメージです。

Composite(コンポジット)とは、「複合的」という意味の単語です。

最近ハマっているゴルフネタのサンプルコードで説明しています →【Rubyによるデザインパターンまとめ4】Compositeパターン - 銀行員からのRailsエンジニア

 

Iteratorパターン

一言で言うと、オブジェクトの集まりがあった時に、そのオブジェクト1つずつに順番にアクセスする方法を提供するデザインパターンです。

GoFは、以下のように説明しています。

集約オブジェクトがもとにある内部表現を公開せずに、その要素に順にアクセスする方法を提供する

配列で与えられたデザインパターンを1つずつ出力するというシンプルなサンプルコードで説明しています → 【Rubyによるデザインパターンまとめ5】イテレータパターン - 銀行員からのRailsエンジニア

 

Commandパターン

処理の内容をオブジェクトに閉じ込めて、実行する際はそのオブジェクトのメソッドを呼び出すパターンです。

処理の内容が書いたオブジェクトのことを、命令という意味の「コマンド」と呼んでいます。

これにより複数のコマンドをキューに入れて順に実行するようにしたり、処理の取り消しなどをシンプルに実装できるようになります。

当時していた勉強内容ネタのサンプルコードで説明しています →【Rubyによるデザインパターンまとめ6】コマンドパターン - 銀行員からのRailsエンジニア

 

Adapterパターン

必要なインターフェースと既存のオブジェクトのインターフェースの違いを吸収するデザインパターンです。

以下の「アダプタ」という言葉の説明そのままの役割です。

アダプタとは、異なる複数の機器に接続する際に用いられる中間装置の総称である。(IT用語辞典バイナリ より)

RailsActiveRecord の中でアダプターパターンが使われている箇所があったので、その箇所をコードリーディングしながら説明しています → 【Rubyによるデザインパターンまとめ7】アダプターパターン - 銀行員からのRailsエンジニア

 

Proxyパターン

本来呼び出したいオブジェクトとの間にオブジェクトを挟むことで、様々な処理を差し込むことができる デザインパターンです。

言い換えると、本来呼び出したいオブジェクトを別のオブジェクト経由で呼び出し、別のオブジェクトに様々な処理を追加することができます。

インターフェースは、本来呼び出したいオブジェクトと同じにします。

よく使用されるケースとしては、アクセス制御 や 生成コストのかかるオブジェクトのインスタンス化遅延 などがあり、これらをプロキシ(挟んだオブジェクト)側で実装することで、関心事を分離することができます。(アクセス制御などが本来呼び出したいオブジェクトの関心事ではない場合に、それをプロキシ側に切り出すことができます)

プロキシ(Proxy)は「代理」という意味であり、中継サーバである「プロキシサーバ」と同じイメージです。

商品の購入、商品へのコメントができるサンプルコードで説明しています → 【Rubyによるデザインパターンまとめ8】プロキシパターン - 銀行員からのRailsエンジニア

 

Decoratorパターン

既存のオブジェクトに、機能を簡単に追加するためのパターンです。

層状に機能を積み重ねることができ、状況ごとに必要な機能のみを持つオブジェクトを作ることができます。

Decorator という単語は「装飾者」という意味で、元のオブジェクトに必要な機能を装飾するイメージです。

様々な方法で通知を行うサンプルコードで説明しています → 【Rubyによるデザインパターンまとめ9】デコレータパターン - 銀行員からのRailsエンジニア

 

Singletonパターン

ただ1つのインスタンスしか持てないクラスを作り、その1つのインスタンスへのアクセスをグローバルに提供するパターンです。

Singletonという単語は、トランプの一枚札(唯一存在するカード)という意味で、インスタンスが1つしか存在しないことを表しています。

ジムでダンベルの貸し借りを管理するサンプルコードで説明しています → 【Rubyによるデザインパターンまとめ10】シングルトンパターン - 銀行員からのRailsエンジニア

 

Factory Methodパターン

オブジェクトの生成をファクトリメソッドに任せることで、クラス名を指定せずにオブジェクトを生成することができるデザインパターンです。

コードの責務を分割して、保守しやすいコードになることがメリットです。

ファクトリ(Factory)とは「工場」という意味で、ファクトリメソッド = オブジェクトを生産するメソッドというイメージです。

Hashで与えられるデータを指定した形式で出力するサンプルコードで説明しています →【Rubyによるデザインパターンまとめ11】ファクトリメソッドパターン - 銀行員からのRailsエンジニア

 

Buildパターン

オブジェクトを作るのに大量のコードを書かなければ行けない場合などに、オブジェクトの生成のためのコードを別のクラス(ビルダクラス)に分離するパターンです。

つまり、オブジェクトの生成手順(コード上ではコンストラクタ)を外出しします。複雑なオブジェクトの生成手順を分離することで、構造がシンプルになり、再利用性も高めることができます

ユーザーオブジェクトを作るサンプルコードで説明しています → 【Rubyによるデザインパターンまとめ12】ビルダパターン - 銀行員からのRailsエンジニア

 

Interpreterパターン

クラスで表現した文法規則で構文を解析し、その結果得られた手順に基づいて処理を実行するパターンです。

Interpreter」は「通訳」という意味です。

文字列をプラスマイナスできるサンプルコードで説明しています → 【Rubyによるデザインパターンまとめ13】インタプリタパターン - 銀行員からのRailsエンジニア

 

DSLドメイン特化言語

ある特定の問題を解決するために専用の言語を定義するパターンです。

Railsでは、Validations・ActiveRecord・Rake・RSpecなど幅広く使われています。

Railsのコードで実際に使われている箇所を題材に説明しています → 【Rubyによるデザインパターンまとめ14】DSL(ドメイン特化言語) - 銀行員からのRailsエンジニア

 

メタプログラミング

必要なコードを全て書いておくのではなく、実行時にプログラムに基づいて作り出します。

「attr_reader」と同じ機能をメタプログラミングで実装しながら説明しています → 【Rubyによるデザインパターンまとめ15】メタプログラミング - 銀行員からのRailsエンジニア

 

Convention over Configuration

日本語訳すると「設定より規約」で、規約に従うことで不必要な設定のコードを書く必要がなくなります

頭文字を取って「CoC」と略されます。

例えば、Rails の ActiveRecord では、users というテーブルは、 models ディレクトリにある user.rb というファイルにある User クラスで処理されます。さらに、users テーブルの name というカラムは、user オブジェクトの name フィールドに自動的に割り当てられます。
このように、規約に従うことでコードの記述量を減らすことでき、また誰が見ても分かりやすいコードになります。

Railsのscaffoldに似た機能を実装しながら説明しています → 【Rubyによるデザインパターンまとめ16】Convention over Configuration - 銀行員からのRailsエンジニア

 

デザインパターンをまとめてきた感想 

選択肢をいくつか持っていることによって状況に一番合った実装を選べる確率が上がるのかなあ、と思いました。自分の実装の幅を広げてくれるのでデザインパターンを知っているといいですね。学んで正解でした。

なんてことを、「あるコードを何種類かの方法でリファクタリングする」という内容の記事を書きながら思ったので、良ければ合わせて読んでみてください。

ストラテジーパターンを使ったリファクタリング例【Ruby】 - 銀行員からのRailsエンジニア

 

学んで終わりだと全く意味はないので、これから実務でのプロダクションコードにガンガンデザインパターンを入れていこうと思いますー!(先日も初めて1つ入れました!)

 

1冊で多くのことを学べたこの本は本当に良書だと思うので、Rubyをやっていてデザインパターンを学んでみたい方はぜひ読んでみてくださいー!(現在は新品を売っていなくて中古が高騰しちゃってるのがちょっとつらいですが..)

Rubyによるデザインパターン

Rubyによるデザインパターン

 

【Rubyによるデザインパターンまとめ16】Convention over Configuration

コードの品質向上のため、Rubyデザインパターンを解説した名著である Rubyによるデザインパターン で紹介されているデザインパターンを1つずつまとめており、今回が第16弾で最終回です!

前回の記事(メタプログラミングのまとめ)はこちらです。
【Rubyによるデザインパターンまとめ15】メタプログラミング - 銀行員からのRailsエンジニア

今回は Convention over Configuration についてまとめました。

f:id:ysk_pro:20200320150238p:plain

Convention over Configuration とは

日本語訳すると「設定より規約」で、規約に従うことで不必要な設定のコードを書く必要がなくなります

頭文字を取って「CoC」と略されます。

例えば、RailsActiveRecord では、users というテーブルは、 models ディレクトリにある user.rb というファイルにある User クラスで処理されます。さらに、users テーブルの name というカラムは、user オブジェクトの name フィールドに自動的に割り当てられます。
このように、規約に従うことでコードの記述量を減らすことでき、また誰が見ても分かりやすいコードになります。

コード

Rails はモデル・コントローラなどを自動で作成してくれる scaffold という機能があり、これも規約に従うことでコードの記述量を減らしてくれる CoC の一つです。

scaffold に似た、簡単な機能を作ってみましょう。

original_scaffold.rb ファイルを作成します。

name = ARGV[0]
class_name = name.capitalize + 'Controller'
file_name = name + '_controller.rb'

content = <<-"EOS"
class #{class_name}
  def hello
    puts 'Hello!'
  end
end
EOS

File.open(file_name, 'w') do |f|
  f.write(content)
end

このように「coc」を引数に渡して実行します。

ruby original_scaffold.rb coc

すると、「coc_controller.rb」が作成されました!

class CocController
  def hello
    puts 'Hello!'
  end
end

おわりに

ここまで読んでいただきありがとうございます。

Rubyによるデザインパターン の中では、様々の例を使って説明されていて分かりやすかったので、ご興味ある方は是非合わせてご覧ください。

Rubyによるデザインパターン

Rubyによるデザインパターン

これで、16回に渡ったデザインパターンまとめブログが終わりました!

実務でどんどん使っていこうと思います!

(追記)
デザインパターンをまとめた記事を書いたので、是非合わせてご覧ください。
ysk-pro.hatenablog.com