Java 6 を使用してmixinを実装するにはどうすればよいですか? それは非常に簡単で、Ruby で可能です。Javaでどうすれば似たようなものにできますか?
17 に答える
デフォルトのメソッド
私は質問がJava6と言ったことを知っていますが、Java 8には、かなりまともな代替手段があります。デフォルトのメソッドです。
インターフェイスメソッドの「デフォルト」実装を追加できるので、インターフェイスを実装するすべてのクラスを壊すことなく、新しいメソッドを追加できます。
ミックスインに状態が必要ない限り、インターフェイスでコードを記述できます。そうすれば、クラスはこれらのインターフェースを必要なだけ実装でき、ブームになります。ミックスインがあります。
これはシステムの悪用ですか?少しですが、状態がないため、多重継承問題にはなりません。
もちろん、それはこのアプローチの最大の欠点でもあります。
オブジェクト構成を使用するだけだと思います。新しい機能を追加するたびに、別のオブジェクトをメンバーとしてクラスに構成します。混合されたすべてのクラスを同じ型にしたい場合は、各要素が他のすべての要素で構成されているメンバー オブジェクトとして配列を使用し、特定の要素にディスパッチできます。
最も簡単な方法は、静的インポートを使用することです。クラスの一部のように「見える」が、実際には別の場所で定義されているコードの再利用が可能になります。
長所:
- 本当に簡単
- 好きなだけ静的インポートを「ミックス」できます
短所:
- 静的メソッドは「this」にアクセスできないため、手動で渡す必要があります
- 状態なし: 静的メソッドは独自のインスタンス フィールドを持つことはできません。独自の静的フィールドのみを定義でき、静的メソッドを呼び出すオブジェクトによって共有されます。
- クライアント クラス (コードが混在しているクラス) でパブリック メソッドを定義することはできません。Ruby では、ミックスインをインポートすると、実際にはこれらのパブリック メソッドがクラスのパブリック メソッドとして定義されます。Java では、この場合、継承がより良い解決策になります (複数のクラスを拡張する必要がない場合)。
例:
import static my.package.MyHelperUtility.methodDefinedInAnotherClass;
public class MyNormalCode {
public void example() {
methodDefinedInAnotherClass();
}
}
更新: Qi4j は Apache Polygene ( https://polygene.apache.org ) になりました。
Qi4j の Mixin の定義は、基本クラスから始まっていないため、おそらく非常にユニークです。その極端に進むことで、アプリケーションの構築方法に関するまったく新しいパラダイムが出現し、それをコンポジット指向プログラミングと呼んでいます。Composite は「オブジェクト」に相当するものであり、Mixin が相互に接続されているだけでなく、Constraints (検証)、Concerns (周囲のアドバイス)、および SideEffects (メソッドの結果を変更できません) も含まれています。
ですから、Qi4j には非常に強力な Mixin ストーリーがあると思います。ミックスインは「型付き」または「汎用」にすることができ、パブリック (コンポジットの外部からアクセス可能) または純粋にプライベート (コンポジット内) にすることができます。Qi4j は、Properties とは何かを強力に定義し、永続性を組み込みます。これにより、ストレージの実装がドメインに漏れることはありません (注意: Qi4j はドメインに漏れます)。また、永続化されたエンティティが登場すると、関連付けの強力な定義も必要になります (Qi4j に含まれます)。
概要については、http://www.qi4j.org/state-modeling.htmlを参照してください。
Qi4j では、Mixin のみが状態を持ちます。Constraints/Concerns/SideEffects は状態を持つことができません (そうする場合は、プライベート mixin を参照する必要があります)。
Qi4j でコンポジットを定義するには、型自体で構造的に行うか、ランタイム モデルが作成されるブートストラップ時に行うことができます。
構造的に;
@Mixins({PetrolEngfineMixin.class, FourWheelsMixin.class})
public interface Car extends HasEngine, HasWheels, EntityComposite
{}
起動時。
public interface Car
{}
public class CarModuleAssembler
implements Assembler
{
public void assemble( ModuleAssembly module )
{
module.entities( Car.class )
.withMixins( PetronEngineMixin.class, FourWheelsMixin.class );
}
}
しかし、これは Qi4j の機能のほんの一部にすぎません。
http://code.google.com/p/javadude/wiki/AnnotationsMixinExampleをのぞいてみましょう
私が作成した一連の注釈を使用しています。
注: 私は注釈の大幅な更新に取り組んでおり、これには API の破損が含まれています。今後数週間以内に新しいバージョンをリリースする予定です。
ちょうど出くわしました: https://blog.berniesumption.com/software/mixins-for-Java/ (Borken リンクが更新されました)
AspectJ ITD を使用して、現在 Java で Mixin を実行できます (つまり、5、6、7) 。もちろん、Java 8 では、防御メソッドにより優れた機能が追加されます。
探しているミックスインの機能が正確にはわかりませんが、その多くはデコレータ パターンを使用して実行できます。
はい、Javaでミックスインアプローチを実装するための最も簡単で便利な方法は、静的メソッドを含むクラスからの静的インポートを使用することです。
Java 7 にこれを提供することを検討しています。私の最初のカットは、この記事に示されている例を使用することです。
上記の他のインジェクション オプションと同様に、Java 6 で動作するはずです。C# と Ruby での Mixins に関する私の経験に基づくと、単にエミュレートしたり偽装したりするのではなく、Mixins の実装を目指すべきです。
もう 1 つのモデルは、Jacksonで使用されるものです。
新しい Java 8 リリースを使用できる場合、たとえばプレリリース モードの場合は、それが役立つ可能性があります。
「 be-a 」ミックスインに労力を必要とする仮想拡張メソッドを使用します。したがって、私の考えでは、まだ初期の段階であり、最初のリンクで提供されるすっきりとした外観のアプローチ (または同様のもの) を好みます。
「Mixin」という用語は、アスペクト指向プログラミング運動における Java 用語「アスペクト」と同等ではありませんか? AspectJ はおそらく一見の価値があります。