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

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

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

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

【Rubyによるデザインパターンまとめ11】ファクトリメソッドパターン

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

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

言葉での説明よりもコードを見た方が分かりやすいので、サンプルコードでの説明をメインにしています。

今回は ファクトリメソッド(Factory Method)パターン についてまとめました。

f:id:ysk_pro:20200209075739p:plain

ファクトリメソッドパターンとは

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

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

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

文章の説明よりも実際のコードを見た方が分かりやすので、以下のサンプルコードをご覧ください。

サンプルコード

Hashで与えられるデータを指定した形式(json または csv)で出力するプログラムを考えてみましょう。
まずはファクトリメソッドパターンを使わずに実装してみます。

require 'json'

class Report
  def self.generate(data, type)
    case type
    when 'json'
      data.to_json
    when 'csv'
      data.keys.join(',') + "\n" + data.values.join(',')
    end
  end
end

次のように実行すると

data = {age: 28, hobby: 'golf'}
puts Report.generate(data, 'json')
puts '---'
puts Report.generate(data, 'csv')

実行結果はこのようになります。

{"age":28,"hobby":"golf"}
---
age,hobby
28,golf

このコードの問題点は、Reportクラスが 以下の2つの責務を持ってしまっている点です。

  • 対応する形式(jsoncsv)の定義
  • それぞれの形式に変換するロジック

複数の責務を持ってしまっていることは、有名なSOLID原則の「S」Single Responsibility Principle:単一責任の原則 に反しますね。

このサンプルコードでは対応する形式の種類が少なく、変換のロジックもシンプルなため問題が無いように感じますが、形式の種類が増えたりロジックが複雑になると、可読性が低く保守しづらいコードになってしまいます。

これをファクトリメソッドパターンを使って書き換えてみましょう。

class Formatter
  def self.type(type) # これがファクトリメソッド!
    case type
    when 'json'
      JsonFormatter.new
    when 'csv'
      CsvFormatter.new
    end
  end
end

class JsonFormatter
  def format(data)
    data.to_json
  end
end

class CsvFormatter
  def format(data)
    data.keys.join(',') + "\n" + data.values.join(',')
  end
end

class Report
  def self.generate(data, type)
    Formatter.type(type).format(data)
  end
end

実行方法、結果は先ほどと同じです。

先ほど課題であった、Reportクラスが持ってしまっていた2つの責務を以下のように分けることができました。

  • 対応する形式の定義 → Formatterクラス
  • 変換ロジック → JsonFormatter/CsvFormatterクラス

対応する形式を増やす場合や、変換ロジックに修正が入った場合には、FormatterクラスやJsonFormatter/CsvFormatterクラスを修正すればよく、Reportクラスの修正は不要になりました。

Reportクラスの責務はレポートを出力することであり、レポート出力に関係ない変換ロジックなどの修正でReportクラスを変更しなくてよくなり、保守性が上がっていると思います。

またこれはGoFの原則の1つ「変わるものを変わらないものから分離する」にも則っています。

今回のサンプルコードは、こちらのサイトを参考にさせていただきました。英語ですがとても分かりやすくて勉強になりました。
Ruby - Factory Method pattern - Ruby Blog

おわりに

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

これまでのブログと形式を変えて、デザインパターンを使っていないコードとその問題点を提示してから、デザインパターンでその問題点を解決していく」という形式で書いてみました。
個人的にはこの方が分かりやすい気がしているので、次回からもこの形で書いていこうと思います。

Rubyによるデザインパターン の中でも、ファクトリメソッドを使っていないコードをファクトリメソッドを使って改善してく流れの説明が分かりやすかったので、ご興味ある方は是非合わせてご覧ください。

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

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

次回は、ビルダ(Builder)パターンをまとめます。

来週も頑張ります!

(追記)
ビルダパターンについてまとめました!
是非合わせてご覧ください。
ysk-pro.hatenablog.com

AtCoderで緑色になりました!【やってきたことまとめ】

こんにちは。先週末についに AtCoder緑色 になりましたーーー!!始めた頃から緑色を最初の目標にしていたのでめっちゃ嬉しいです!!

2019/9にAtCoderを始めて、5ヶ月かかりました...!

緑色になってテンションの高いうちに、ここまでやってきたことなどをまとめてみます。 

f:id:ysk_pro:20200121214811p:plain

そもそもAtCoderとは?

AtCoderのホームページにある説明です。

AtCoderは、世界最高峰の競技プログラミングサイトです。
リアルタイムのオンラインコンテストで競い合うことや、
3,000以上の過去問にいつでもチャレンジすることができます。

AtCoderトップページより引用)

競技プログラミングの定義ってなんだろと思って、ウィキペディアで調べてみました。

競技プログラミングでは、参加者全員に同一の課題が出題され、より早く与えられた要求を満足するプログラムを正確に記述することを競う。

ウィキペディア/競技プログラミングより引用)

与えられたお題をクリアするプログラムを誰が最初に書けるか、みたいな感じです。

実際の問題を見たほうが雰囲気が分かると思うので引用します。

直近(2020/1/19)に行われた AtCoder Beginner Contest 152(初心者向けのコンテスト)の一番簡単な問題(A問題)です。

<問題文>
高橋君は、プログラミングコンテスト AXC001 に参加しており、問題 A にコードを提出しました。
この問題にはN個のテストケースがあり、すべてのテストケースに正解した場合のみ提出は AC となります。
高橋君の提出は、N個のテストケースのうち M個のテストケースに正解しました。
高橋君の提出が AC となるか判定してください。

<制約>
1 ≤ N ≤ 100
0 ≤ M ≤ N
入力はすべて整数である。

<入力>
入力は以下の形式で標準入力から与えられる。

N M

<出力>
高橋君の提出が AC となる場合は Yes, そうでない場合は No と出力せよ。

書いたプログラムで入力を受け取って、正しい出力を返せれば正解となります。

様々な言語で回答することができ、僕が Ruby で書いたコードはこちらです。

  1. n, m = gets.chomp.split.map(&:to_i)
  2. if n == m
  3.  puts 'Yes'
  4. else
  5.  puts 'No'
  6. end

すごい簡単ですよね。

コンテストでは、こんな感じの問題が複数出題されて、早くたくさん解いた順にランキングがつけられます。

 

一見複雑な問題を考察して、シンプルなアルゴリズムに落とし込んで解けたときは最高に気持ちいいです...!

 

緑色ってどのくらいのレベルなの?

AtCoderでは、オンラインで行われるコンテストに出場すると、結果に応じてレーティングがつき、レーティングによって色が変わります。

上から順に「赤・橙・黄・青・水・緑・茶・灰」となっており、緑は下から3番目です。

AtCoderの社長(競技プログラミングがとても強い方でもあります)のブログでは緑色のレベル感について次のような説明がされていました。

緑色になれれば、競技プログラミングに熱心に取り組んでいる人」と考えて問題ないでしょう。要求レベルも決して低くなく、出場回数が足りないとマイナス補正がかかるため、運だけで到達することはまず出来ないラインです。他社アルゴリズム力判定サービスだと、上位1%の最高ランクが付く実力です。(あくまで「アルゴリズム力部分だけであることに注意してください)

 

AtCoderをはじめたきっかけ

元々学生時代は数学が好きだったこともあり(相関があるのか不明ですが)、競技プログラミングというものに興味がありました。

時間ができたときに、試しに少しやってみよーと思ってやってみたら一瞬でハマっていました

みんなでやるとより楽しいので、今では会社内外で布教活動もしています(このブログもその一環かな)。

 

やってきたこと

前置きが長くなってしまいましたがここからが本題です。

コンテストへの出場

AtCoderでは、ほぼ毎週末(土曜 or 日曜の 21:00 からが多い)に初心者向けのコンテストが行われており、予定が無い日は極力参加しています。

コンテスト後にAtCoderの中の方がYoutubeで解説をしてくださるのですが、解法のみではなく考え方から教えてくださり、とっても分かりやすいので自分が解けなかった問題の解説は必ず見ています。

また、コンテスト後は全員の提出したコードが見れるので、同じ言語で提出されたコードを見て「こんな書き方あるのか〜」と参考にしています。

今まで参加してきたコンテストの結果はこんな感じです。14回のコンテストに出てきました。

f:id:ysk_pro:20200120215545p:plain

パフォーマンスというのが、そのコンテスト1回でのレーティングのようなものらしいです。

少しは成長しているようなしていないような。

レーティング推移も載せておきます。

f:id:ysk_pro:20200121214943p:plain

 

AtCoderの過去問

AtCoder Problems という神サービスを使って、過去問を毎日やっています。

自分が過去問の何割くらいを解いたのかであったり、何日連続で問題に取り組めているかを見れるのでモチベーションの維持にも役立ちます。

f:id:ysk_pro:20200120213900p:plain

赤枠で囲ったのですが、現在37日連続で問題に取り組めています。いい感じ。

f:id:ysk_pro:20200120213913p:plain

GitHubのように草も生やせます。楽しい。

 

蟻本

競技プログラミング界では超有名な プログラミングコンテストチャレンジブック(通称 蟻本)にも取り組みました。

難しくて初級編までしか読めておらず、初級編の理解も怪しいので、定期的に読み返そうと思っています。

 

モチベーションの維持

仲間を見つける

会社でAtCoderを一緒に始める仲間を見つけることができたので、slackでatcoderチャンネルを作って毎日ワイワイ盛り上がっています。

同時期に始めたので、レーティングを競い合ったりできて楽しいです。

会社外でも、個人開発のコミュニティ「運営者ギルド」のslackで最近ワイワイやり始めました。

 

おわりに

AtCoderめっちゃ楽しいです!

敷居も低いです!

ご興味ある方は是非一度チャレンジしてみてください!

 

次は水色目指して頑張ります。

【読書まとめ25】スクラムブートキャンプ(SCRUM BOOT CAMP THE BOOK)

勤めている会社で、スクラムで開発を進めているプロジェクトに初めて入ることになったので、先輩におすすめいただいた スクラムブートキャンプ(SCRUM BOOT CAMP THE BOOK) を読みました。

この本の紹介に書いてある「はじめて『スクラム』をやることになったら読む本」という言葉通り、マンガをはさんだストーリー仕立ての説明はとても分かりやすかったです。

後から見返せるように、ポイントをまとめてみました。このブログを読むだけでもスクラムの雰囲気は分かると思います。

f:id:ysk_pro:20200115221028p:plain

 

ソフトウェアをつくる上で大事なこと

  • できたものを使って利用者が便利になる等の成果をあげること。何かを作ることは目的ではなく、あくまで手段である。当初作ろうと思っていたものよりも良いアイデアが出れば、目的を達成するためにそれを受け入れながら、作るものを変えていく。そうすることで成果を最大化できる
  • このような考え方で、成果を最大化するために考案された開発の進め方がアジャイル開発である

アジャイル開発とは

  • 次のような開発の進め方をアジャイル開発と言う
    • 関係者は目的の達成のためにお互いに協力し合いながら進める 
    • 利用者の反応関係者からのフィードバック継続的に得ながら、計画を調整する 
    • 一度にまとめてではなく、少しずつ作る。そして実際にできあがったものが求めているものと合っているかを頻繁に確認する
  • あらかじめおおよその全体像を明らかにしたうえで、どのくらいの期間と人数で仕事をするかを決めて、その範囲の中で大事な要求から順にプロダクトを作っていく

スクラムとは

  • 目的を達成できるプロダクトをつくるために、常に進む方向を調整しながら全員が一丸となって行うべき作業、会議、成果物を定めたものスクラムと言う

スクラムの進め方

  • スクラムではプロダクトオーナー(後述)が要求を並べ替えて、開発チームがスプリント単位でプロダクトをつくっていく
  • 「プロダクトバックログ(プロダクトへの要求を抽出して順番に並べ替えたリスト)を作成し、常にメンテナンスして最新に保つ
  • スプリント(1週間〜4週間)の固定の期間内で、計画、設計、開発、テストなどプロダクトのリリースに必要なすべてのことを行う

スクラムのチーム編成

プロダクトオーナー

  • プロダクトバックログを管理する責任者。プロダクトバックログは誰でも追加して良いが、順序(優先度)を最終的に判断して責任を持つのはプロダクトオーナーである

開発チーム

  • 通常3~9人で構成される。3人未満だと個人のスキルに依存してしまい、10人以上だとコミュニケーションコストが増えてしまう
  • 開発チーム内での仕事の進め方は、開発チームのメンバーの合意のもとに決められ、外部から仕事の進め方を指示されることはない

スクラムマスター

  • スクラムのプロセスを円滑を回して、プロダクトオーナーや開発チームを支える

スクラムで実施するミーティング

スプリントプランニング

  • スプリントの開始時に行う
  • 2つのトピックを扱う
    1. スプリントで何を達成するかを決める。プロダクトオーナーが今回のスプリントで達成したい目標を明らかにし、それを達成するためのプロダクトバックログ項目を選ぶ。バックログの個数は、ベロシティ(後述)を踏まえて決める。スプリントの目標をスプリントゴールとして簡潔にまとめておくと良い 
    2. 開発チームが選択したプロダクトバックログ項目をどうやって実現するかの計画を立てる。具体的な作業を洗い出し、プロダクトバックログの項目と作業を一覧にしたスプリントバックログを作成する。個々の作業は1日以内で終わるように分割するのが一般的で、時間での見積もりがよく使われる
  • 2週間スプリントであれば、4時間程度を使う

プロダクトバックログリファインメント

  • スプリントプランニングでプロダクトバックログの項目からスムーズに選択できるようにするため、プロダクトバックログの上位の項目について事前準備を行う
  • 準備する内容の一例
    • 中身を具体的にする
    • 疑問点を解決する
    • 何ができたら完成なのか(受け入れ基準)を明確にする(デモ手順まで決めておくと認識が揃いやすい)
    • 自分たちが扱えるサイズに分割する(具体的な分割方法はこちらの記事が参考になりました)
    • 見積もる
  • いつどのように行うかはスクラムでは定義していないが、使う時間はスプリントの10%以内にするのが一般的

デイリースクラム

  • スプリント期間中、毎日、同じ場所、同じ時間に行う
  • スプリントバックログの残作業を確認し、このまま進めてスプリントゴールが達成できるのかを確認する
  • 開発チームのメンバーが以下の3つを話す形で進めることが多い
    • スプリントゴールの達成のために、自分が昨日やったことは何か
    • スプリントゴールの達成のために、自分が今日やることは何か
    • スプリントゴールを達成する上で、障害となるものがあるか
  • 問題解決の場ではないことに注意する。開発チームのメンバーが問題を報告した場合は、デイリースクラム終了後に改めて、問題解決に必要な人を集めた別の会議を設定する
  • 開発チームの人数に関係なく 15分間で行う

スプリントレビュー

  • スプリントの終わりに行う
  • 開発チームのスプリントでの成果物を関係者にデモを行い、フィードバックを得てプロダクトバックログを見直す
  • デモができるのは完成したものだけである
  • 2週間スプリントであれば、2時間程度を使う

スプリントレトロスペクティブ

  • スプリントレビューの後に行う
  • スプリントの振り返りを行う。うまくいったこと、今後改善すべき点を整理し、今後のアクションプランをつくる。アクションプランのうち少なくとも1つは次のスプリントのスプリントバックログに含めると良い
  • アクションを検討するときは、アイデアを具体化するために便利な指標であるSMARTを意識すると効果が高まる
    • Specific(具体的な)
    • Measurable(計測可能な)
    • Achievable(達成可能な)
    • Relevant(問題に関連のある)
    • Timely / Time-bounded(すぐできる / 期日のある)
  • 2週間スプリントであれば、1.5時間程度を使う

スクラムを行う上で知っておいた方がいいこと

  • プロダクトバックログは詳細なフォーマットは定められていないが、以下のどちらかの形式で書かれることが多い
    • 機能・目的・詳細でまとめて一覧にした形式
    • 実際に使うユーザーに何を提供してその目的は何かを簡潔に書く、ユーザーストーリーという形式
  • プロダクトバックログに重要な項目が漏れないようにするためのやり方:スクラムチームみんなで、プロダクトバックログに含めたほうがいいと思う項目を付箋などに書き出していく。様々な人のいろんな観点で洗い出すことで、致命的な漏れをなくすことができる
  • インセプションデッキは、プロジェクトを始める前に明らかにしておくべきことを知るための活動。10個の質問という形でまとめられていて、それぞれの質問についてスクラムチーム全員で話し合う。話し合って明らかになったことは、プレゼン資料のようなスライドにまとめていく。スクラムではゴールやミッションを常に強く意識しながら行動することが重要であり、スクラムチーム全員で話し合うことが大切
  • 多くのスクラムチームでは、相対見積もりが使われる。基準となる作業とその時の数字を決めて、それとの比較で作業量を見積もる。実際のやり方としては、多くのチームではラニングポーカーという手法が使われる。それぞれの項目について、1人1人が見積もりを考えて、同時に公開してすり合わせる
  • スプリントごとに終わらせられるポイント数は、ベロシティと呼ばれている。ベロシティはスクラムチームのスピードのようなものである。ベロシティは決めるものではなく測るものであり、実際に行った数字を使うのが一番確実である
  • プロジェクトで調整できるものは次の4つしかない。品質予算期間スコープ である

 

 おわりに

本書は、最初にスクラムについてのポイントをまとめ、その後は実践編としてマンガをはさみながらのストーリー仕立てで解説していくという構成でした。

サクサク読めてとても分かりやすかったので、ご興味ある方は是非お手に取ってみてください。 

次は、会社の方におすすめいただいた カイゼン・ジャーニー (アジャイル開発の実例を書いた有名な本です)を読む予定です。

 

以下の記事を合わせて読むことでスクラムのベースとなるアジャイル開発についての理解がさらに深まると思うので、ご興味ある方は是非ご覧ください。

ysk-pro.hatenablog.com

ysk-pro.hatenablog.com

ysk-pro.hatenablog.com

【Rubyによるデザインパターンまとめ10】シングルトンパターン

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

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

この本で紹介されているサンプルコードそのままではなく、オリジナルのコードで説明しています。

今回は シングルトン(Singleton)パターン についてまとめました。

f:id:ysk_pro:20200112100112p:plain

シングルトンパターンとは

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

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

文章の説明よりも実際のコードを見た方が分かりやすいと思うので、以下のサンプルコードをご覧ください。

サンプルコード

ジムでダンベルを使いたいとき、他の人に使われているとテンションが下がりますよね。。

ということで、ダンベルの貸し借りを管理する簡単なプログラムを考えてみましょう。

class Dumbbell
  def initialize
    @usable = true # ダンベルを使用できるかどうか
  end

  def borrow
    if @usable
      @usable = false
      puts 'ダンベルを借りたよ。筋トレファイト!'
    else
      puts 'ダンベルはレンタル中だよ。他の筋トレをしよう!'
    end
  end

  def return
    @usable = true
    puts 'ダンベルを返却したよ。お疲れさま!'
  end

  @@instance = Dumbbell.new # クラス変数

  def self.instance
    @@instance
  end

  private_class_method :new
end

インスタンスが1つしか存在しないことを利用して、唯一のインスタンスインスタンス変数(@usable)でダンベルを使用できるかを管理しています。

以下のように実行します。

Dumbbell.instance.borrow
Dumbbell.instance.borrow
Dumbbell.instance.return

Dumbell.instanceで、唯一存在するインスタンスを呼び出しています。

ダンベルを借りたよ。筋トレファイト!
ダンベルはレンタル中だよ。他の筋トレをしよう!
ダンベルを返却したよ。お疲れさま!

newメソッドをプライベートメソッドにすることで、外部からDumbbell.newインスタンスを作ることができなくなり、Dumbbelクラスがインスタンスをただ1つしか持たないことを保証しています。

以下のように実行するとエラーとなります。

Dumbbell.new.borrow


また、RubyにはSingletonモジュールが用意されており、Singletonモジュールを使用するとシングルトンパターンがシンプルに実装できます。

先ほどのコードをSingletonモジュールを使ってリファクタリングしてみましょう。

require 'singleton'

class Dumbbell
  include Singleton

  def initialize
    @usable = true # ダンベルを使用できるかどうか
  end

  def borrow
    if @usable
      @usable = false
      puts 'ダンベルを借りたよ。筋トレファイト!'
    else
      puts 'ダンベルはレンタル中だよ。他の筋トレをしよう!'
    end
  end

  def return
    @usable = true
    puts 'ダンベルを返却したよ。お疲れさま!'
  end
end

Singletonモジュールをincludeすると、先に書いたコードと同様の以下3点を行ってくれます。

  • インスタンスを作成し、それをクラス変数に格納すること
  • instance というクラスメソッドを作ること
  • newメソッドをプライベート化すること

全て(実行の仕方・結果・newを呼び出すとエラーとなること)先ほどと同じ結果になります。

シンプルに実装でき、実装漏れもなくなるので、実際にシングルトンパターンを使うときはSingletonモジュールを利用するのが良さそうです。

おわりに

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

Rubyによるデザインパターン の中では、Loggerクラスを題材にしたリアルなサンプルコードの説明や、シングルトンパターンを使う際の注意点などが記載されていて分かりやすかったので、ご興味ある方は是非合わせてご覧ください。

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

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

次回は、ファクトリ(Factory)メソッドパターンをまとめます。

来週も頑張ります!

(追記)
ファクトリメソッドパターンについてまとめました!
是非合わせてご覧ください。
ysk-pro.hatenablog.com

移動時間で絞り込めるゴルフ場検索サービス「楽々ゴルフ」を作りました

ゴルフ場を都道府県でしか絞り込めない既存のサービスにうんざりしてないですか?

僕はしています。

例えば、同じ千葉県のゴルフ場でも、僕の家から1時間で行けるところもあれば、2時間半かかるところもあります。

なるべくゴルフ場への移動時間を短くしたい僕は、まず都道府県で絞り込んで、目星をつけたゴルフ場1つ1つの移動時間をGoogle Mapで調べるという苦肉の策でしのいできました。

でも、このサービスがあればそんなことをする必要はありません。プレー日、予算の項目に加えて「移動時間」でもゴルフ場を絞り込むことができます。今までゴルフ場選びに使っていた時間を、ゴルフの上達のための練習に使うことだってできてしまいます。

 

このような思いで気持ちでサービスを作りました。正月休みに、エンジニアである妻と一緒に作ってました。めちゃくちゃ楽しかったです。

作ったサービスはこちらです。

www.rakuraku-golf.com

 

想定される質問集

移動時間って交通手段は?

車です。ゴルフは車で行くことがほとんどです。

 

私の自宅からの移動時間で絞り込めるの?

すみません。そこまではできませんでした。いくつかの駅をピックアップして、そこからの移動時間で絞り込めるようにしているので、自宅から近い駅を選んでください。

出発地点を増やすことは検討しているので、要望があれば是非教えてください。

 

そのまま予約できたりするの?

はい!できます!

検索結果に楽天GORAの予約ページへのリンクをつけているので、そこから予約できます。

 

対応エリアは?

現状出発地点は首都圏のみです。首都圏以外の方すみません。

 

ゴルフって楽しいの?

めちゃくちゃ楽しいです。特にコースを回って自然の中でプレーするのは最高です。

 

使用した技術

使用した技術を1枚にまとめた図

使用した技術を1枚にまとめた図

この図で雰囲気は分かると思います。

フロントは React を AWS Amplify でホスティングしており、バックエンドは AWS Lambda と Dynamo DBでサーバレスの構成にしました。

ちなみに妻と僕の役割分担は、ざっくり妻がフロントで僕がバックエンドの開発をしました。(相互にレビューを行いとても勉強になりました)

このサービスを作るにあたって、なるべく使ったことのない技術を使おうと思っていたので、あまり使ったことのなかった React や AWS の各サービスを使うことができて良かったです。

これがベストな構成ではないはずなので、これ使った方がいいんじゃない?などあれば是非教えてください。

 

おわりに

まとめると

  • ゴルフ場を探す時は「楽々ゴルフ」使ってみてください
  • 新しい技術で開発するのはとても勉強になりました
  • 妻との共同開発楽しかったです

www.rakuraku-golf.com

【Rubyによるデザインパターンまとめ9】デコレータパターン

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

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

この本で紹介されているサンプルコードそのままではなく、オリジナルのコードで説明しています。

今回は デコレータ(Decorator)パターン についてまとめました。

f:id:ysk_pro:20200104144100p:plain

デコレータパターンとは

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

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

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

文章の説明よりも実際のコードを見た方が分かりやすいと思うので、以下のサンプルコードをご覧ください。

サンプルコード

通知を行うプログラムがあるとします。

元々はサービス内での通知だけだったものの、ユーザーの要望で 通知のタイミングでSlack通知、メール通知、またその両方について既存の通知に追加して行う必要があるケースを考えてみます。

デコレータパターンを使うと以下のようにできます。

class Notifier # 元々存在した通知を行うクラス
  def send(message)
    puts "サービス内で「#{message}」を通知するよ"
  end

  def stop
    puts '通知を止めるよ'
  end
end

class NotifierDecorator # デコレータの基底クラス
  attr_reader :notifiler

  def initialize(notifiler)
    @notifiler = notifiler
  end

  def send(message)
    notifiler.send(message)
  end

  def stop
    notifiler.stop
  end
end

class SlackNotifier < NotifierDecorator # slack通知を行うデコレータ
  def send(message)
    puts "slackで「#{message}」を通知するよ"
    notifiler.send(message)
  end
end

class MailNotifier < NotifierDecorator # メール通知を行うデコレータ
  def send(message)
    puts "メールで「#{message}」を通知するよ"
    notifiler.send(message)
  end
end

次のように実行します。

notifier = MailNotifier.new(SlackNotifier.new(Notifier.new))
notifier.send('投稿にいいねがついたよ')
puts '---'
notifier.stop

メール通知・Slack通知を追加したい時に「MailNotifier.new(SlackNotifier.new(Notifier.new))」のように層状に機能を追加していることが分かると思います。

このように、実行時に必要な機能を組み合わせることができます。

実行結果はこうなります。

メールで「投稿にいいねがつきました!」を通知するよ
slackで「投稿にいいねがつきました!」を通知するよ
サービス内で「投稿にいいねがつきました!」を通知するよ
---
通知を止めるよ

仮にデコレータパターンを使わずに シンプルに継承を使って実現しようとすると、組み合わせごとにクラスを作る必要が出てくるので辛くなります...


また、デコレータの基底クラス(NotifierDecoratorクラス)は、Notifierクラスに処理を移譲しているだけなので、次のようにリファクタリングすることができます。

require 'forwardable'

class NotifierDecorator # デコレータの基底クラス
  extend Forwardable
  attr_reader :notifiler

  def_delegators :notifiler, :send, :stop

  def initialize(notifiler)
    @notifiler = notifiler
  end
end

Forwardableモジュールの def_delegatorsクラスメソッドは、1つ目の引数にインスタンス名を取り、そのインスタンスに2つ目以降の引数にとったメソッドを移譲します。

これにより、1つ1つのメソッドに移譲の処理を書く必要がなくなりました。

実行の仕方、実行結果は先ほどと同じになります。

おわりに

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

Rubyによるデザインパターン の中では、いくつかのサンプルコードを用いた説明、またこの記事で紹介しきれなかったリファクタリングについても解説しているので、ご興味ある方は是非合わせてご覧ください。

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

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

次回は、シングルトン(Singleton)パターンをまとめます。

来週も頑張ります!

(追記)
シングルトンパターンについてまとめました!
是非合わせてご覧ください。
ysk-pro.hatenablog.com

エンジニア2年目の2019年振り返り

2019年も終わりますねー。
気づけば、エンジニアになって1年半が経っていました。

仕事にも慣れてきて毎日楽しく過ごしていたらあっという間の1年でした。
仕事のことは詳細に書けないですが、主に仕事以外でこの1年何をしてきたのかを振り返ります。

ざっくり時系列で書いていきます。

f:id:ysk_pro:20191231100302p:plain

個人開発

2018年は12個リリースした個人開発ですが、今年は1月にリリースした1つに留まりました。
こんなツイートが簡単にできちゃいます。

このサービスは今まで作ってきた中でも結構お気に入りです。

webookshelf.herokuapp.com

2018年にリリースしたサービスはこちらの記事にまとまっています。
エンジニアになって2018年にやってきたことを一覧にしてみた + KPT振り返り - 銀行員からのRailsエンジニア

 

React, Reduxの勉強

フロントエンドのフレームワークを習得したくて、React, Redux を学びました。
また、React, Redux を書く機会もあり、少しはできるようになったかなーと思います。

React, Redux については、こちらの Udemy がめちゃくちゃ分かりやすかったです。
Modern React with Redux [2019 Update]

 

NIKOTAMA.rbの運営

都心にはたくさんのRuby地域コミュニティがあるのですが、二子玉近辺にはなく、二子玉でRubyエンジニアとの繋がりができればいいなぁと思い、会社の先輩と立ち上げました。

こちらは僕が書いた 第1回 NIKOTAMA.rb の開催レポートです。
第1回 NIKOTAMA.rb を開催しました! | 楽天株式会社ラクマ事業部

5月に第1回を開催し、そこから毎月 計8回開催することができました。参加いただいた方々ありがとうございました。
今後も毎月開催する予定で、次の1月のイベントはこちらから申し込みができます。
nikotama.rb #9 - connpass 

個人としてもNIKOTAMA.rbで2回登壇することができ、いい機会になりました。
その2回の登壇資料はこちらです。
サーキットブレーカーを導入しようとしている話 - Speaker Deck
AWS re:Invent 2019 に行ってきました! - Speaker Deck

第1回 NIKOTAMA.rbの集合写真

第1回 NIKOTMA.rbの様子

 

AWSの資格取得、Re:Inventへの参加

AWSを業務でも使用しており、一度幅広く学びたいなーと思っていた時、先輩に資格の存在を教えていただき取得しました。(一度は落ちるなど苦労しました)

また、幸運にも毎年ラスベガスで行われているAWSのイベント「re:Invent」に業務扱いで参加させていただきました。

それぞれの詳細はこちらのブログに書いています。
AWSの資格(SAA-ソリューションアーキテクトアソシエイト)に合格するまでにやったこと・感想 - 銀行員からのRailsエンジニア
AWS re:Invent 2019に参加してきました!体験したことや感想など(雰囲気が伝わるように写真多め) - 銀行員からのRailsエンジニア

ラスベガスのホテルで行われていた噴水ショーの様子

ラスベガスのホテルの噴水ショー

 

AtCoder

元々興味のあった競技プログラミングを始めました。

会社の委員会制度(Googleの20%ルールのように、業務の10%をメインのPJ以外に使える制度)で、競技プログラミング委員会が発足し、slackでワイワイしながら問題を解いています。

来年はなんとか緑色、水色になりたい(競技プログラミングサービス / AtCoderはRating毎に色が分かれています)

AtCoderのRating画面

AtCoderのRating

 

デザインパターンの勉強

書くコードの品質を上げたいと思い、デザインパターンの勉強を始めました。

Rubyによるデザインパターン という本に沿って学んでいるのですが、ただ読むだけでは身につかないと思ったので、デザインパターン1つずつブログにアウトプットしながら読み進めています。

毎週1つずつ書いており、現状8つのデザインパターンについての記事があります。
デザインパターン カテゴリーの記事一覧 - 銀行員からのRailsエンジニア

 

おまけ(プライベート編)

筋トレの継続

昨年8月から始めた筋トレを継続できています。

引っ越しに伴うジムの移籍(ゴールドジム → JOY FIT)はあったのですが、週3〜4で通えています。

身体がどんどん変わっていくのが楽しく、完全にハマりました。

 

ゴルフの再開

銀行から転職してからやらなくなっていたゴルフを再開しました。

会社にゴルフが好きな人が割とおり、みんなでワイワイ打ちっ放しに行ったり、ラウンドを回ったりできて楽しいです。

1月からは妻とゴルフレッスンにも通います。来年は80台が目標(現状ベストスコア94)。

 

オンライン英会話

re:Inventでラスベガスに行く準備として10月に始めたオンライン英会話ですが、re:Inventに行った後も継続できています。

ネイティブキャンプ というサービスを使っているのですが、予約不要でその場でレッスンが始められたり、レッスン受け放題だったり、アプリ内でビデオ通話できたりととても使いやすく気に入っています。

 

おわりに

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

昨年に比べるとアウトプットが少ないかなーという気もしますが、振り返ってみると色々と新しいことにもチャレンジできたのでいい年でした。何より毎日楽しかった。

来年も色々なことにチャレンジする1年にしたいです。

もしご興味あれば、エンジニア1年目の昨年の振り返り記事も合わせてご覧ください。

ysk-pro.hatenablog.com

みなさま良いお年を。