2012-01-19 5 views
25

私は実際のサービスとDAOのクラスと同じ数のインターフェースを持つ、いくつかのSpringHibernate Webアプリケーションプロジェクトを見ました。なぜサービスとDAOのレイヤーには常に1つのimplementaionインターフェイスがありますか?

私は常にこれらのこれらの単一の実装インタフェースを有する主な理由のような2つのことを考えた:

  1. スプリングが所与のクラス(疎結合)

    public class Person { 
        @Autowired 
        private Address address; 
    
        @Autowired 
        private AccountDetail accountDetail; 
    
        public Person(Address address, AccountDetail accountDetail) 
        { // constructor 
    
  2. における依存関係として実際の実装を配線することができ

    単体テストでは、モッククラスを作成し、クラスを単独でテストできます。

    Address mockedAddress = mock(Address); 
    AccountDetail mockedAccountDetail = mock(AccountDetail); 
    Person underTestPerson = new Person(mockedAddress, mockedAccountDetail); 
    // unit test follows 
    

しかし、後半の、私が気づい:

春の依存関係として、具体的な実装クラスを配線することができます:EasyMockのような

public class Person { 

@Autowired 
private AddressImpl address; 

@Autowired 
private AccountDetailImpl accountDetail; 

public Person(AddressImpl address, AccountDetailImpl accountDetail) { 
// constructor 

モックフレームワークは、同様に具体的なクラスをモックすることができます

AddressImpl mockedAddress = mock(AddressImpl); 
AccountDetailImpl mockedAccountDetail = mock(AccountDetailImpl); 
Person underTestPerson = new Person(mockedAddress, mockedAccountDetail); 
// unit test follows 

また、this議論のように、私は概要は、単一のアプリケーション内では、インターフェイスは、おそらく大会や習慣からおそらく過度に使用されていると思う。一般的には、世界中の多くのアプリで使用されているslf4jなどの別のアプリケーションと接続する場合に最適です。 1つのアプリケーション内では、クラスはインターフェイスとほぼ同じ抽象化されています。

私はまだインターフェイスが必要なのですが、* ServiceImplや* DaoImplクラスのような単一の実装を持ち、コードベースサイズを不必要に増やすのはなぜですか?私が気づいていない具体的なクラスを模擬することにいくつかの問題がありますか?

これまで私がチームメイトと話したことがあるときは、インタフェースに基づいたサービスとDAOのクラスを実装することは誰もが守っているデザインだと言います - 彼らは春のベストプラクティス、OOP、DDDなどについて言います。孤立したアプリケーション内に非常に多くのインターフェースを持つことの後で、まだ実用的な理由はありません。

+2

答えにつきましては、各オブジェクトの前にインタフェースを投げる理由としてDDDをどのように呼び出すことができないのか分かりません。 DDDはそれとは関係ありません。 OOPであっても、正当な理由がありません。あなたがSOLIDのL、I、Dのようなものを取るならば、インタフェースなどの抽象化をどのように設計すればよいのか、それらをいつ使うべきかを指定するだけです*。 あなたが言ったように、私はそれがすべて「春のベストプラクティス」のものか、それを習慣からやっている人だけに沸き起こると思います。 – guillaume31

答えて

14

インターフェイスには、プロキシと同様に多くの利点があります。クラスがインタフェースを実装している場合、JDKの動的プロキシはAOPのデフォルトで使用されます。実装を直接使用すると、proxy-target-class = trueにすることによってCGLIBプロキシを使用することが強制されます。これらは、JDKプロキシと異なり、バイトコードの操作が必要です。

詳しくはhereをお読みください。

さらに詳しい情報はwhat reasons are there to use interfaces (Java EE or Spring and JPA)をご覧ください。

14

これは非常に論争の対象です。簡単に言えば、少なくともあなたのために、開発者はいません。

EJB2の世界では、ホームとリモートのインターフェイスは必須であり、まさに@AravindAが言及しています:プロキシです。セキュリティ、リモーティング、プーリングなどはすべてプロキシでラップされ、標準ライブラリ内で厳密に要求されるサービスを提供することができます(DynamicProxyなど)。

javaassistcglibが用意されているので、Spring(Hibernate、EJB3好きなら)は、フレームワークの開発者が好きなクラスを完全に実装することができます。問題は、彼らがしていることは非常に厄介なことです:彼らは通常、パラメータのないコンストラクタを追加するように要求します.-待って、私はここにパラメータを持っていましたか?

インターフェイスはあなたの正気を維持するためにここにあります。それでも、奇妙なことですが、適切なコンストラクタを持つクラスの引数のないコンストラクタは、私にとって意味のあるものではありません。 Springがクラスのインターフェイスと同等の機能を持つこと、すなわち、(ないしは無視された)状態のインスタンスとすべてのメソッドがオーバーライドされていることがわかります。だからあなたは "本当の"インスタンスと "偽のインターフェース"を持っています。そして、偽のインターフェースはあなたにとってセキュリティ/トランザクション/リモーティングのすべての魔法を提供します。ニース、しかし理解するのは難しいですし、あなたはそれを離れていない場合はバグのように見えます。

さらに、あなたのクラスにインターフェイスを実装すると、(少なくともいくつかのバージョンの)Springが突然このインターフェイスだけをプロキシしようとしていることを突き止めました。アプリケーションは明白な理由で動作しません。

これまでのところ、理由は、安全性と健全性です。それが良い習慣である理由はありますが、あなたの投稿から、あなたはすでにそれらのすべてを読んでいます。私が今日見ることができる最も重要な理由は、特にあなたのプロジェクトの新規参入者について話している場合、WTH /分の指標です。

関連する問題