続、BirthdayというValueObjectはありなのか?

https://togetter.com/li/1401992 の議論を受けて、 みなさまによる深掘り、拾えた限りで。 特化型, 合目的的性, Liskov置換原則, 正/負の可変性, 使用可能性, 非内包, 型エイリアス, 過剰設計か否か, 文脈の前提は?
8
杉本啓 @sugimoto_kei

@Tanaka9230 Ageという値クラスを設ける理由が(年齢計算以外に)存在するからAgeを作る。そのうえで Ageのファクトリーメソッドに年齢計算をやらせる。ということでしたら賛成です。年齢計算をやらせるためにAgeという値クラスを作る、のなら反対です。コードの字面(じづら)ではなく、目的適合性の話なんです。

2019-09-09 09:29:58
天重誠二 @tenjuu99

目的適合性はデザインそのものだと思う。

2019-09-09 10:32:43
天重誠二 @tenjuu99

ソフトウェアデザインに美意識みたいなのが絡んでいるのもこれだと思っている。

2019-09-09 10:33:58
増田 亨 @masuda220

私はプログラミング言語や型システムをビジネスルールを表現する手段と考えている。 アプリケーション全体でビジネスルールを直接的に表現するのは一部のコード。 その一部のコード表現の工夫と改善がアプリケーションの多くの部分に波及する。 そうなるように設計するアプローチに取り組んでいる。

2019-09-09 12:54:04
加藤潤一(かとじゅん) @j5ik2o

期日は未来を指定する。期日は約束事に含まれる。たとえば請求に含まれるのは支払い期日。支払い期日は請求日に依存する。請求日から30日以内など。こういうのがユビキタス言語で表現されるモデルだよね。この段階ではクラスとかプロパティ、メソッドとか持ち出さない。利害関係者と会話できないから

2019-09-09 19:27:41
杉本啓 @sugimoto_kei

値クラスを細かく作る話。発注を例にすれば、発注予定日、発注日、納期、納入予定日、納入日、検収日、支払締日等ある。これら全部を別のクラスにして何の意味があるのか。比較したり日数差を算出しようとすれば、全部、toDate()で変換やん。こんなの本当にやってるの? twitter.com/sugimoto_kei/s…

2019-09-09 19:44:44
杉本啓 @sugimoto_kei

@Tanaka9230 僕としては、Birthdayというクラスを設けることについて、基本的には、違和感を感じます。誕生日は、人の集合を定義域とし日付の集合を値域とする関数であって、値集合ではないと思うからです。

2019-09-07 09:12:48
天重誠二 @tenjuu99

素朴にValue Objectを作ってしまうと、汎用的な定義から特化した定義を作ってしまいそうな気がする。プログラムとしてそう表現していなくとも、観念としてBirthday extends Dateになってしまうことが多いというか。

2019-09-09 23:00:30
天重誠二 @tenjuu99

これ自体はわりと素朴な知識表現の形式で、たぶん「定義は最近類と種差によって表現される」という古典的カテゴリー観。

2019-09-09 23:00:30
ポリドッグ@PartyHard Inc. @polidog

まさに「汎用的な定義から特化した定義を作ってしまいそうな気がする」ってのは自分も感じていた事

2019-09-09 23:20:14
天重誠二 @tenjuu99

@polidog 「string では役不足だから独自型を定義しよう」という考えだと、 string をちょっと制限する特殊型を作ってしまうことになりそうですよね。

2019-09-10 00:15:59
takasek @takasek

@tenjuu99 @polidog Birthday extends Dateのときリスコフの置換原則によりBirthdayはDateができること全部できなきゃいけなくて、それは制限とは逆の力学なのでは

2019-09-10 00:20:37
天重誠二 @tenjuu99

ウィトゲンシュタインの言語ゲームとかリスコフ置換原則とかDuck Typingとかと似たようなアイデアなきがしてるんだけど気のせいなのかどうか

2019-09-10 00:22:52
天重誠二 @tenjuu99

@takasek @polidog なるほど、多分そのとおりだと思います。そうするとDateで足りないからBirthdayという型を作ろうという発想じたいに意味的なコンフリクトがあるかなと思いました。たぶん実際にはリスコフ置換原則の抜け道でextendsしないと思いますが、deligateするようにしてもうーんという感じ。

2019-09-10 00:57:26
天重誠二 @tenjuu99

言語ゲームをちゃんと理解しているかはわからないけど、語の意味は使用可能性であって内包(intension)ではないという話、Duck Typingは典型的にそうだとおもうんですよね。

2019-09-10 01:02:32
天重誠二 @tenjuu99

指摘をうけて思ったけど、よく考えたらマルチパラダイムデザインの負の可変性とリスコフ置換原則はセットで考えてもいいのかも。負の可変性をクラス継承で考えたときに、リスコフ置換原則が破られているはず。

2019-09-10 01:17:50
Atsuhiro Kubo @iteman

負の可変性の現れは、新たなドメイン(さらにいえば存在)の創造のチャンスなんだと思います。 github.com/phpmentors-jp/… twitter.com/tenjuu99/statu…

2019-09-10 01:24:34
天重誠二 @tenjuu99

負の可変性とリスコフ置換原則の関係をコプリエンさんが見逃すはずもないので、言及がないかと探そうかと思ったけど本が手元になかった

2019-09-10 01:36:07
Atsuhiro Kubo @iteman

@tenjuu99 「…例えば、継承に正の可変性を導入するときには、Liskov置換原則(Liskov substitutability principle)を用いることができる。しかし、負の可変性に対しても、マルチパラダイムデサインのアイディアを適切に組み込むことができる。…」 iteman.tumblr.com/post/187602341… #mpdosaka

2019-09-10 02:18:59
天重誠二 @tenjuu99

リスコフ置換原則関連の箇所読んでたら負の可変性とDCIとの関連がようやくわかってきた気がする。まさに extends がもたらす意味的な破綻(リスコフ置換原則の破綻)が問題なんだ。DCIだとオブジェクトの相互作用の場(Context)でのみ意味が成立している。 sites.google.com/a/gertrudandco…

2019-09-10 02:45:18
ますごん @ymasuda_

@sugimoto_kei 目的に依るところはあるでしょうね 個人的には年月日までに意味のあるDateと、時分秒までに意味のあるDateくらいには分けたいです 例えば誕生日は前者で、タイムゾーン間を換算すべきでないけど、後者は換算すべきなど、求めるCapabilityは違います かといって、例にあったのは分けすぎだと思います

2019-09-10 08:22:55
加藤潤一(かとじゅん) @j5ik2o

これをDCIでどう考えるか。期日はデータ、コンテキストは請求、ロールは請求後30日以内の期限を判定できる。コンテキストが違えば納品期日もありえる。請求コンテキストの中で期日データは支払いロールを持つと言い方になるかな。納入コンテキストなら納品ロールが与えられる? twitter.com/j5ik2o/status/…

2019-09-10 08:56:26
加藤潤一(かとじゅん) @j5ik2o

これ圧倒的に正しい。ScalaでのDCI実装も思いついた!けど、コード量が増えてメンテナンスがつらくなりそうでは。なので支払期日や納品期日など別のモデルとして実装しそうだよね。つまりモジュールを分けることになるのでは。とりあえずコードにしてみるか。

2019-09-10 08:56:26
杉本啓 @sugimoto_kei

蛇足。英語的には、birthdayっていうと例えば7月4日ってことになるので、年まで含めた生年月日をいうならbirthdateですね。どうでもいいけど。

2019-09-10 09:09:06
きょん@アジャイルコーチ、システムアーキテクト @kyon_mm

@sugimoto_kei ほんとそうで、振る舞いと実装を区別できてないんだと思います。

2019-09-10 09:10:26