ナレマネするように設計する
いろんな設計思想あるけど、基本的なところをカバーできたら、そこから先はナレマネだと思う。 副作用のある関数やめようとかは「基本的な設計」の話 そこらへんはカバーできたとして、その上の設計の話
システムとして綺麗であるだけでなく、ドキュメントとして綺麗なコード
この二つはほとんどの場合において、強く相関する
ドキュメントとして綺麗なコードを書いていれば、システムとして綺麗になると思う
逆も然り
誰が何の目的でこのコードに辿り着くのか?でそのファイルに書くべき情報を決める
コードの1 fileは1つのscrapbox pageと同じ
| 具体例
二つのシナリオを考える
1. プレミアム会員であれば、ホーム画面の上にスターを表示する
2. プレミアム会員向けに誕生日祝いキャンペーンの通知を送る
どちらも「会員クラス」にメソッドを作るけど、どれくらいストレートなメソッドを作るかを考えたいjyori112.icon
1.ではpremium?というメソッドを作る
2.ではsend_birthday_campaign?というメソッドを作らないと思う
まず1.を作るために、Userクラスにpremium?メソッドを作る
code:rb
class User
def premium?
...
end
end
そして、ホーム画面を表示するクラスでこのメソッドにアクセスするだろう
code:rb
if user.premium?
....
end
次に2.を実現しようと思うと、まず今日が誕生日かどうかを判定するbirthday?メソッドが必要そう
code:rb
class User
def premium?
...
end
def birthday?(date:)
...
end
end
ここで分岐する
一つの方法は、Userクラスにsend_birthday_campaign?というmethodを作る方法
code:rb
class User
def premium?
...
end
def birthday?(date:)
...
end
def send_birthday_campaign?
premium? && birthday(date: Date.today)
end
end
もう一つの方法は、campaignを送るサービスで判定する方法
code:user.rb
class User
def premium?
...
end
def birthday?(date:)
...
end
end
code:birthday_campaign_servive.rb
class BirthdayCampaignService
def initialize(user:)
@user = user
end
private
def send?
@user.premium? && birthday(date: Date.today)
end
end
メモ
Serviceを避けるべきみたいな議論はあると思うけど、ここでは「Userクラスにどこまで書くか?」を考えたい
Userにpremium?というメソッドを作ったのと同じように、send_birthday_campaign?というmethodを作っても良さそう
でも、違和感ある
jyori112.iconはこういう時「誰が何の目的でどのファイルを読みにくるか?」を考える
特にどんな疑問を持つ人はどのファイルを見るか?を考えると良い
コードを読みにくる人は「疑問」を持っていることが多いので
今回は「どういう条件で誕生日のキャンペーン通知が送られるんだろう?」という疑問だと思う
この時、多分みんなBirthdayCampaignServiceを見にくる
この疑問を持った結果、Userを見にくる人はいない
だとすると、このロジックはBirthdayCampaignServiceに書いてあった方が良さそう
同じことを「責任」という言葉で語ることもある