2017-05-08 18 views
0

私は、JAX-RSアノテーションが作成されたインターフェースがわかるように、いくつかのチュートリアルを終えました。そして、後で同じことの実装が行われます。JAX-RS実装用にインタフェースを宣言する必要があるのはなぜですか?

はなぜですか?具体的なクラスをRESTfulサービスとして直接公開することはできませんか?それは悪い習慣ですか?以下は私がthis質問で出会ったサンプルの一つです。

答えて

1

簡潔に言えば、インターフェイスは必須ではありません。クラスをサービスとして公開することができます。

ここでは、この https://softwareengineering.stackexchange.com/questions/150045/what-is-the-point-of-having-every-service-class-have-an-interface

+0

私はポストを見て、ドナルフェローの答えを理解できませんでした。あなたはそれにいくつかの光を置くことができるでしょうか?同氏によると、Springのようなフレームワークとのインタキャスティングはより簡単になるだろう。どうやって? – Sam

+2

私はOSGIでの作業の期限が切れているから、サービス実装が他のマシン/環境/クラスローダーからロードされて実行されるという共通の状況があると思います。サービスと実装の分離によって、APIインターフェイスをインポートし、他のチームによってコード化された実装について「気にしない」ことができました。実装コードの変更は自分のコードには影響しませんでしたので、これはカップリングを減らす方法でした – Kirill

2

についての素晴らしい議論が、私はRESTfulなサービスとして直接具象クラスを公開することはできませんの?あなたは間違いなくでき

。あなたはそれを試しましたか?それはうまくいくはずです。

はその悪い習慣ですか?

個人的に(これは私の好みです)、私はインターフェイスを使用することをお勧めしません。あなたのコードをきれいにすると主張する人もいるかもしれませんが、例えば、annotation inheritanceのように、問題を理解していない人には問題を引き起こすことがあります。見つけにくいです。

あなたの引数は、インタフェースは、コードクリーナーを作るということであるならば、私はカップルの引数を持っています。

(1)あなたのコードはあまり理解できます。どのような引数が必要なのかを確認するには、インターフェースを再度参照する必要があります(たとえば、メソッドのパラメータ注釈を検査するなど)。すべての注釈が実際に記述したコードに含まれている方が簡単です。

(2)インタフェースには、実装を持っていないので、あなたはまだ、すべてのクラスを実装する必要があります。私は個人的にすべての基本的な操作を実装する抽象基本クラスに行きます。例

public abstract class AbstractResource<T extends BaseEntity> { 

    private final Repository<T> repository; 

    public AbstractResource(Repository<T> repository) { 
     this.repository = repository; 
    } 

    @GET 
    public List<T> getAll() { 
     return this.repository.findAll(); 
    } 

    @GET 
    @Path("{id}") 
    public T getOne(@PathParam("id") long id) { 
     T result = this.repository.findOne(id); 
     if (result == null) { 
      throw new NotFoundException(); 
     } 
     return result; 
    } 

    @POST 
    public Response create(T entity, @Context UriInfo uriInfo) { 
     T saved = this.repository.save(entity); 
     // BaseEntity should have an id property 
     long id = saved.getId(); 
     URI createdUri = uriInfo.getAbsoluteUriBuilder() 
      .path(id).build(); 
     return Response.created(createdUri).build(); 
    } 
} 

のためにあなたは@PUT@DELETのために同じことを行うことができます。コア機能はすべてのリソース・コレクションで同じです。変更する必要があるのは、Repositoryタイプのみです。あなたのすべての実装は、それをそのまま拡張することができます

@Path("pets") 
public class PetsResource extends AbstractResource<Pet> { 

    @Inject 
    public PetsResource(PetsRepository repository) { 
     super(repository); 
    } 
} 

これははるかにクリーンです。あなたは、あなたの具体的なリソースに同じ基本的なCRUD操作を実装する必要はありません。具体的なリソースクラスに他のリソースメソッドを提供したい場合は、そうすることができます。

関連する問題