Java の世界 (より正確には、複数の継承/ミックスインがない場合) の経験則は非常に単純です: 「クラスの継承よりもオブジェクトの構成を優先する」。
特にscalaで、ミックスインも検討する場合、それがどのように変更されるかを知りたいですか?
ミックスインは、複数の継承またはより多くのクラス構成の方法と見なされますか?
「クラス構成よりもオブジェクト構成を優先する」(またはその逆) ガイドラインもありますか?
オブジェクト構成でも機能する場合に mixin を使用 (または悪用) する例をいくつか見てきましたが、どちらが優れているかは常にわかりません。それらを使用して非常に類似したことを達成できるように思えますが、いくつかの違いもあります。いくつかの例:
- 可視性 - ミックスインを使用すると、すべてがパブリック API の一部になりますが、コンポジションの場合はそうではありません。
- 冗長性 - ほとんどの場合、ミックスインは冗長性が低く、使いやすいですが、常にそうであるとは限りません (たとえば、複雑な階層で自己型も使用する場合)
短い答えが「場合による」であることは知っていますが、おそらく、これまたはそれが優れている典型的な状況がいくつかあります。
これまでに思いついたガイドラインの例をいくつか示します (2 つの特性 A と B があり、A が B のいくつかのメソッドを使用したいと仮定します)。
- A の API を B のメソッドで拡張したい場合は mixin、それ以外の場合はコンポジションです。しかし、作成しているクラス/インスタンスがパブリック API の一部でない場合は役に立ちません。
- ミックスインを必要とするいくつかのパターン (例: Stackable Trait Pattern )を使用したい場合は、簡単に決定できます。
- 循環依存関係がある場合は、自己型の mixin が役立ちます。(私はこの状況を回避しようとしますが、必ずしも簡単ではありません)
- 動的な実行時の決定が必要な場合は、合成を行う方法、次にオブジェクトの合成を行います。
多くの場合、mixin の方が簡単 (および/または冗長度が低い) ように見えますが、"God クラス" や、artima の 2 つの記事: part 1、part 2 (BTW it他の問題のほとんどは関連性がなく、scala にはそれほど深刻ではないように思えます)。
このようなヒントは他にありますか?