今年 会社でのレビューで話した事

7c4ff97e74b3f52858796fd0cc358fb5?s=47 Ryz310
December 13, 2019

今年 会社でのレビューで話した事

レビューでクラスの設計がムズいという声を受けて幾つか社内で解説をしたのですが、今日はその中から一部を抜粋して持ってきました。

7c4ff97e74b3f52858796fd0cc358fb5?s=128

Ryz310

December 13, 2019
Tweet

Transcript

  1. 今年 会社でのレビ 今年 会社でのレビ ューで話した事 ューで話した事 銀座 Rails #16 Dec

    13, 2019
  2. ⾃⼰紹介 ⾃⼰紹介

  3. @ryosuke_sato

  4. サトウリョウスケ サトウリョウスケ 株式会社フィードフォース ソーシャル PLUS バックエンドエンジニア 開発リーダー

  5. 今年の振り返り 今年の振り返り

  6. 銀座 RAILS に 3 回登壇しました 銀座 RAILS に 3 回登壇しました

    銀座 Rails #07, Mar. 26 rubocop_challenger という gem を作った 銀座 Rails #10, June 21 My API Client 銀座 Rails #16, Dec. 13 今年 会社でのレビューで話した事 ← New!!!
  7. RUBOCOP_CHALLENGER という GEM を RUBOCOP_CHALLENGER という GEM を 作った (#07)

    作った (#07) https://github.com/ryz310/rubocop_challenger
  8. MY API CLIENT (#10) MY API CLIENT (#10) class ExampleApiClient

    < MyApiClient::Base endpoint 'https://example.com/v1' error_handling status_code: 200, json: { '$.errors.code': 10 }, raise: MyApiClient::ClientError attr_reader :access_token def initialize(access_token:) @access_token = access_token end # GET https://example.com/v1/users def get_users(condition:) https://github.com/ryz310/my_api_client
  9. 来年も登壇がんばりたい

  10. 今⽇話すこと 今⽇話すこと

  11. 今年 会社でのレビューで話した事 今年 会社でのレビューで話した事

  12. クラスの設計がムズいという声を受けて 会社の勉強会では 45 分 x 2 回話した 今⽇はその中から⼀部を抜粋して持ってきまし た

  13. 1. 抽象度を揃える 2. 継承について考える 3. 現実から学ぶ

  14. 1. 抽象度を揃える 1. 抽象度を揃える

  15. Q. これは何でしょう? トマトとモッツアレラチーズのサラダ 娼婦⾵スパゲティ ⼦⽺背⾁のリンゴソースかけ プリン

  16. A. トニオさんのレストランのメニュー

  17. 例えばこの美味しそうなスパゲティを

  18. 仗助に材料別のところまでもどされると

  19. いきなり違和感が出てきた トマトとモッツアレラチーズのサラダ スパゲティ茹でてニンニクと唐⾟⼦とプチトマ トを良い感じに炒めて絡める ← ⼦⽺背⾁のリンゴソースかけ プリン

  20. ▶ 抽象度を揃えよう 材料と調理⽅法について知っているのはトニオ さん(シェフ)だけで良いはず このクラスを扱う⼈はどのようなレベル感で対 象を知っているべきなのかを考えよう ※ 抽象化の⽅法はクラス化する、メソッド化す る、とかです。

  21. 抽象度が揃わないよくあるケース ワンライナーだからメソッド化しなかった の条件式だから ( 略 ) 単純な処理だから ( 略 )

  22. 処理が短くても抽象化すると ⾒えてくる事があります。

  23. イタリアンの中に唐揚げ??? トマトとモッツアレラチーズのサラダ 娼婦⾵スパゲティ 若鶏の唐揚げ ← プリン

  24. 抽象化されてないとちょっと気付きづらいかも トマトとモッツアレラチーズをスライスして特 製ドレッシングをかける スパゲティ茹でてニンニクと唐⾟⼦とプチトマ トを良い感じに炒めて絡める チキンに下味をつけて油で揚げる プッチンする

  25. 抽象度を揃えるメリット クラスが単⼀責任の原則に従っているかどうか を確認しやすくなる 可読性が上がる リファクタリングしやすくなる

  26. レビュー依頼に出す前に 抽象度が揃っているか確認しよう

  27. 抽象度の揃ってないコードで レビュー依頼に出してきたら …

  28. None
  29. 2. 継承について考える 2. 継承について考える

  30. クラスの継承にはいくつかの パターンがあると思います。

  31. Interface Pattern Layer Pattern DSL Pattern and so on.

  32. それっぽい名前つけましたが 僕が勝⼿に呼んでるだけです

  33. 結論から先に⾔うと

  34. ⾊んな継承パターン混ぜて使うのは やめた⽅が良いです

  35. INTERFACE PATTERN INTERFACE PATTERN

  36. クラスの使い⽅を規格化するための継承。 ⾝近な例だと Ruby webserver interface の 。 Rack

  37. def call(env) [ 200, # (Integer) { 'Content-Type' => 'text/plain'

    }, # (Hash) ['Hello World'] # (String ] end
  38. Rack の規格(簡略版) メソッドを定義すること 引数 を受け取ること 戻り値は

  39. 楽器やってない⼈にはさっぱりかもですが、 エレキギターのエフェクターは 分かりやすい例だと思います

  40. None
  41. 規格が揃っているから ⾊んなメーカーのエフェクターを 同じように組み合わせられる

  42. LAYER PATTERN LAYER PATTERN

  43. OSI 参照モデルと同じような考え⽅。 継承の階層ごとに扱う問題を分ける。

  44. 例えば JWT で認証するような API を作っている時。

  45. ヘッダから JWT を検証する処理は で実装する。 class ApplicationController < ActionController::API before_action :verify_authentication_header

    def verify_authentication_header decode_authentication_header rescue InvalidAuthenticationScheme render status: :bad_request rescue VerificationFailed, Expired render status: :unauthorized end end
  46. 継承先の⼦クラスでは JWT 認証の事は考えずに済む。 class SomeController < ApplicationController def index end

    def show end end
  47. DSL PATTERN DSL PATTERN

  48. ⾝近な例だと ActiveRecord とか。 class Company < ApplicationRecord has_many :employees validates

    :name, presence: true scope :xxx end
  49. 親クラスを継承することで DSL ( ドメイン固有⾔語 ) が使えるようになる、 というパターン。

  50. 拙作の も DSL Pattern です(宣伝) class ExampleApiClient < MyApiClient::Base endpoint

    'https://example.com/v1' error_handling status_code: 200, json: { '$.errors.code': 10 }, raise: MyApiClient::ClientError https://github.com/ryz310/my_api_client
  51. 3 つのパターンをご紹介しましたが、 親クラスに複数のパターンが 適⽤されている場合は 責務を負い過ぎている可能性があります。

  52. 特に DSL パターンはみんな (?) やりたがりますが、 プロダクトのコードではやらない⽅が 良いと思います。

  53. どうしてもやりたい場合は gem にしましょう

  54. 3. 現実から学ぶ 3. 現実から学ぶ

  55. 世の中の事象は設計に役⽴つ事が多い 世の中の事象は設計に役⽴つ事が多い

  56. ⽔道は蛇⼝を右にひねれば⽔が⽌まる

  57. 右利きの⼈間の割合が世の中的に多い 右腕は右にひねる⽅が得意 ⽔を⽌める事 の⽅がやりやすい UI の⽅が安全

  58. ▶ 突き詰めて考えれば、 ⾃ずと仕様が決定される

  59. 時計は少しずつ早い時間にずれていく⏳

  60. 時計の誤差は少しずつ蓄積されていく 早まる⽅向に誤差を貯めた⽅が事故を防ぐこと に繋がりやすい (電波時計が無かった頃の話ね)

  61. ▶ どうやってもズレる事を防げないのであれば、 安全な⽅向に倒す

  62. 普段から⽇常を観察しておくと こういう知識が仕様決める時に役に⽴つ(かも)

  63. 他にも話したい事はたくさんありますが、 時間がないのでブログに書きます

  64. ちなみにブログはまだ開設すらしてません (来年の⽬標です)

  65. 今年も⼀年お世話に 今年も⼀年お世話に なりました なりました

  66. 来年も宜しくお願い 来年も宜しくお願い 致します 致します END