以下あくまで私見として捉えてください。僕もDDDを勉強中で解釈が間違っていたりとか異なる意見があると思いますので。 あと書きなぐっているので読みづらくてすみません、あとで余裕があれば改めてブログにでもまとめます。
それで、僕の理解だとリポジトリって対象の集約ごとに提供するメソッドが多少ばらつくんですよね。 例えば書き込みをサポートしないリポジトリとか、IDを複数渡して一度に取ってこれるリポジトリ、そうじゃないリポジトリとか。 やりがちな失敗が、最初にスタンダードなread/writeができるリポジトリを定義してすべてのリポジトリでそれを継承しようとしてしまうことです。 これだとReadしかできないリポジトリが発生したとき、それだけリポジトリ基底クラスを継承しないようにするかReadWriteRepositoryの既定クラスとしてReadRepositoryを置くなどしないといけなくなります。 最悪の選択はReadしか不要なのにWriteのメソッドも実装してしまうことで、これは余計なコードが増えるだけではなく他の開発者が「このリポジトリってwriteしていいんだ」と勘違いする理由になります。
より本質的にアンチパターンであるとした場合の理由を考えると リスコフの置換原則「派生型はその基本型と置換可能でなければならない」に反しているからだと思います。
リポジトリの基底クラスって定義しても基底クラスの型へ代入して使うことはまったくないですよね?
だからdef get(id: ID): Aggregate
のようなメソッドを定義したとしても、別々のリポジトリ間でメソッド名が同じである、以上のメリットがないんじゃないかなと。
(これはコップ本12.2 シンインターフェイスとリッチインターフェイスのようなアプローチをする場合はメリットが出ますが、パフォーマンス上の問題などで結局しないことも多いと思います)
あとこれはアンチパターンの論拠とはならないんですが、Scalaの型システムへよく習熟してない人が無理に型パラメータを活用しようとして とんでもないコードになったり本来の意図を表現できない既定リポジトリクラスになることはよくありました(当方2の2でそうなっています)。
そのとおりだと思います。すべてのリポジトリが同じメソッド集合を実装する必要はないと思います。
ただ、いくつかの汎用的な問い合わせや保存機能はあるので、選択的にミックスインして使えるとよいとは思います。
https://github.com/j5ik2o/scala-ddd-base/blob/master/core/src/main/scala/com/github/j5ik2o/dddbase/
https://github.com/j5ik2o/scala-ddd-base/tree/master/jdbc/slick/src/main/scala/com/github/j5ik2o/dddbase/slick
https://github.com/j5ik2o/scala-ddd-base/blob/master/example/src/main/scala/com/github/j5ik2o/dddbase/example/repository/slick/AbstractUserAccountRepositoryBySlick.scala
選択できれば、派生先の実装で無理に実装せざるを得ないという状況にはならないはずです。