Upgrade to Pro
— share decks privately, control downloads, hide ads and more …
Speaker Deck
Features
Speaker Deck
PRO
Sign in
Sign up for free
Search
Search
今年 会社でのレビューで話した事
Search
Ryz310
December 13, 2019
Programming
2
1.8k
今年 会社でのレビューで話した事
レビューでクラスの設計がムズいという声を受けて幾つか社内で解説をしたのですが、今日はその中から一部を抜粋して持ってきました。
Ryz310
December 13, 2019
Tweet
Share
More Decks by Ryz310
See All by Ryz310
Redis::Objects で遊んでみよう
ryz310
0
800
My API Client
ryz310
0
150
MyApiClient
ryz310
3
1.2k
Other Decks in Programming
See All in Programming
Rubyでつくるパケットキャプチャツール
ydah
0
530
Alba: Why, How and What's So Interesting
okuramasafumi
0
240
EC2からECSへ 念願のコンテナ移行と巨大レガシーPHPアプリケーションの再構築
sumiyae
3
630
Fixstars高速化コンテスト2024準優勝解法
eijirou
0
200
ErdMap: Thinking about a map for Rails applications
makicamel
1
1.1k
[JAWS-UG横浜 #79] re:Invent 2024 の DB アップデートは Multi-Region!
maroon1st
0
130
PicoRubyと暮らす、シェアハウスハック
ryosk7
0
250
ecspresso, ecschedule, lambroll を PipeCDプラグインとして動かしてみた (プロトタイプ) / Running ecspresso, ecschedule, and lambroll as PipeCD Plugins (prototype)
tkikuc
2
2.3k
富山発の個人開発サービスで日本中の学校の業務を改善した話
krpk1900
3
310
Оптимизируем производительность блока Казначейство
lamodatech
0
990
定理証明プラットフォーム lapisla.net
abap34
1
670
月刊 競技プログラミングをお仕事に役立てるには
terryu16
1
1.3k
Featured
See All Featured
Keith and Marios Guide to Fast Websites
keithpitt
410
22k
Why Our Code Smells
bkeepers
PRO
335
57k
Typedesign – Prime Four
hannesfritz
40
2.5k
YesSQL, Process and Tooling at Scale
rocio
171
14k
The Myth of the Modular Monolith - Day 2 Keynote - Rails World 2024
eileencodes
20
2.4k
Being A Developer After 40
akosma
89
590k
Become a Pro
speakerdeck
PRO
26
5.1k
The MySQL Ecosystem @ GitHub 2015
samlambert
250
12k
A designer walks into a library…
pauljervisheath
205
24k
The Language of Interfaces
destraynor
156
24k
For a Future-Friendly Web
brad_frost
176
9.5k
Raft: Consensus for Rubyists
vanstee
137
6.7k
Transcript
今年 会社でのレビ 今年 会社でのレビ ューで話した事 ューで話した事 銀座 Rails #16 Dec
13, 2019
⾃⼰紹介 ⾃⼰紹介
@ryosuke_sato
サトウリョウスケ サトウリョウスケ 株式会社フィードフォース ソーシャル PLUS バックエンドエンジニア 開発リーダー
今年の振り返り 今年の振り返り
銀座 RAILS に 3 回登壇しました 銀座 RAILS に 3 回登壇しました
銀座 Rails #07, Mar. 26 rubocop_challenger という gem を作った 銀座 Rails #10, June 21 My API Client 銀座 Rails #16, Dec. 13 今年 会社でのレビューで話した事 ← New!!!
RUBOCOP_CHALLENGER という GEM を RUBOCOP_CHALLENGER という GEM を 作った (#07)
作った (#07) https://github.com/ryz310/rubocop_challenger
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
来年も登壇がんばりたい
今⽇話すこと 今⽇話すこと
今年 会社でのレビューで話した事 今年 会社でのレビューで話した事
クラスの設計がムズいという声を受けて 会社の勉強会では 45 分 x 2 回話した 今⽇はその中から⼀部を抜粋して持ってきまし た
1. 抽象度を揃える 2. 継承について考える 3. 現実から学ぶ
1. 抽象度を揃える 1. 抽象度を揃える
Q. これは何でしょう? トマトとモッツアレラチーズのサラダ 娼婦⾵スパゲティ ⼦⽺背⾁のリンゴソースかけ プリン
A. トニオさんのレストランのメニュー
例えばこの美味しそうなスパゲティを
仗助に材料別のところまでもどされると
いきなり違和感が出てきた トマトとモッツアレラチーズのサラダ スパゲティ茹でてニンニクと唐⾟⼦とプチトマ トを良い感じに炒めて絡める ← ⼦⽺背⾁のリンゴソースかけ プリン
▶ 抽象度を揃えよう 材料と調理⽅法について知っているのはトニオ さん(シェフ)だけで良いはず このクラスを扱う⼈はどのようなレベル感で対 象を知っているべきなのかを考えよう ※ 抽象化の⽅法はクラス化する、メソッド化す る、とかです。
抽象度が揃わないよくあるケース ワンライナーだからメソッド化しなかった の条件式だから ( 略 ) 単純な処理だから ( 略 )
処理が短くても抽象化すると ⾒えてくる事があります。
イタリアンの中に唐揚げ??? トマトとモッツアレラチーズのサラダ 娼婦⾵スパゲティ 若鶏の唐揚げ ← プリン
抽象化されてないとちょっと気付きづらいかも トマトとモッツアレラチーズをスライスして特 製ドレッシングをかける スパゲティ茹でてニンニクと唐⾟⼦とプチトマ トを良い感じに炒めて絡める チキンに下味をつけて油で揚げる プッチンする
抽象度を揃えるメリット クラスが単⼀責任の原則に従っているかどうか を確認しやすくなる 可読性が上がる リファクタリングしやすくなる
レビュー依頼に出す前に 抽象度が揃っているか確認しよう
抽象度の揃ってないコードで レビュー依頼に出してきたら …
None
2. 継承について考える 2. 継承について考える
クラスの継承にはいくつかの パターンがあると思います。
Interface Pattern Layer Pattern DSL Pattern and so on.
それっぽい名前つけましたが 僕が勝⼿に呼んでるだけです
結論から先に⾔うと
⾊んな継承パターン混ぜて使うのは やめた⽅が良いです
INTERFACE PATTERN INTERFACE PATTERN
クラスの使い⽅を規格化するための継承。 ⾝近な例だと Ruby webserver interface の 。 Rack
def call(env) [ 200, # (Integer) { 'Content-Type' => 'text/plain'
}, # (Hash) ['Hello World'] # (String ] end
Rack の規格(簡略版) メソッドを定義すること 引数 を受け取ること 戻り値は
楽器やってない⼈にはさっぱりかもですが、 エレキギターのエフェクターは 分かりやすい例だと思います
None
規格が揃っているから ⾊んなメーカーのエフェクターを 同じように組み合わせられる
LAYER PATTERN LAYER PATTERN
OSI 参照モデルと同じような考え⽅。 継承の階層ごとに扱う問題を分ける。
例えば JWT で認証するような API を作っている時。
ヘッダから 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
継承先の⼦クラスでは JWT 認証の事は考えずに済む。 class SomeController < ApplicationController def index end
def show end end
DSL PATTERN DSL PATTERN
⾝近な例だと ActiveRecord とか。 class Company < ApplicationRecord has_many :employees validates
:name, presence: true scope :xxx end
親クラスを継承することで DSL ( ドメイン固有⾔語 ) が使えるようになる、 というパターン。
拙作の も 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
3 つのパターンをご紹介しましたが、 親クラスに複数のパターンが 適⽤されている場合は 責務を負い過ぎている可能性があります。
特に DSL パターンはみんな (?) やりたがりますが、 プロダクトのコードではやらない⽅が 良いと思います。
どうしてもやりたい場合は gem にしましょう
3. 現実から学ぶ 3. 現実から学ぶ
世の中の事象は設計に役⽴つ事が多い 世の中の事象は設計に役⽴つ事が多い
⽔道は蛇⼝を右にひねれば⽔が⽌まる
右利きの⼈間の割合が世の中的に多い 右腕は右にひねる⽅が得意 ⽔を⽌める事 の⽅がやりやすい UI の⽅が安全
▶ 突き詰めて考えれば、 ⾃ずと仕様が決定される
時計は少しずつ早い時間にずれていく⏳
時計の誤差は少しずつ蓄積されていく 早まる⽅向に誤差を貯めた⽅が事故を防ぐこと に繋がりやすい (電波時計が無かった頃の話ね)
▶ どうやってもズレる事を防げないのであれば、 安全な⽅向に倒す
普段から⽇常を観察しておくと こういう知識が仕様決める時に役に⽴つ(かも)
他にも話したい事はたくさんありますが、 時間がないのでブログに書きます
ちなみにブログはまだ開設すらしてません (来年の⽬標です)
今年も⼀年お世話に 今年も⼀年お世話に なりました なりました
来年も宜しくお願い 来年も宜しくお願い 致します 致します END