0

私たちはSpring MVCアプリケーションを持っています。ほとんどのREST操作はリソースごとの唯一のGET操作です。したがって、現在では、(URL、コンテンツタイプ、パラメータなどであっても)唯一異なるGETメソッドを持つ多くのコントローラがあります。複数のリソースに対して1つのコントローラを持つことの長所と短所

このような重複を排除するために、私たちのチームメイトは、唯一のGET操作とサービス付きマップ(リソース名 - >リソースサービス)を持つ1つのコントローラを作ることを提案します。

しかし、私たちは、より複雑なSpringインジェクションチューニング、コンテンツタイプ、パラメータにいくつかの制限を加える機会がないというような欠点を見ています。さらに、別のコントローラに存在するいくつかのリソースがあります。また、Swaggerの唯一のメソッドを複数の方法で文書化する方法は、少なくとも簡単にはないとは思いません。

私にとっては片側のコードは少ないが、他方では操作のカスタマイズ、アーキテクチャの混在、適切な文書の欠如、または少なくとも複雑な構成の機会が制限されている。一つの方法を作るのが良いアプローチだとは思わない。

私は正しいですか?もしそうなら、どうすればそれを証明できますか?なぜそうならないのでしょうか?時間とアイデアをありがとう!

答えて

2

はい、あなたは正しいです。要するに、single responsibility principleによれば、各コントローラは1つのジョブ(1つのURLのみを処理する)を行うべきである。

ジェネリックコントローラが処理する問題を完全に記述します。また、コントローラーがジェネリックルールに完全に適合していても、来月に特定のものが必要な場合はどうなるか考えてみてください。コードをコピー&ペーストしてから新しいものを追加する必要があります。だからしばらくすると、巨大で複雑な汎用コントローラという重複したコードが混乱する。開発者チームにビジネス要件が予期せず追加される可能性があるため、どれくらいの速さで実行できるか予測できませんでした。

一方、あなたのチームメイトは、重複したコードを減らすことを希望しています。少なくとも、すべての開発者がコードをよりクリーンにするために時間を費やしたいとは限らない。そして、ほとんどの人は認知を得る必要があります(彼らの意見に価値があることを確認する)。だから、:)彼を離れて送る

私はお勧めできるものはありません:抽象親を紹介し、私はプロジェクトに同様のソリューションを想定し、実際には同様のコントローラ

/** Interface mainly works as a marker. 
    At first look, interface isn't necessary but it'll improve maintainability. 
    Next year you say 'thank you' to yourself */ 
interface IController { 
    //some methods which will implement EACH controller even the most specific 
    public void doGet(params) 
} 
abstract class AbstractController implements IController { 
/** Class implements default behavior for controllers. 
    Implementation written so child classes could adopt behaviour easily*/ 
    @Override 
    public void doGet(params) { 
    // use Template pattern 
    doLog(params); 
    prepareStuff(); 
    process(); 
    } 
    // common stuff which should be done at first 
    protected void doLog(params) { // your favorite logger here} 
    // extension point for inherited classes 
    abstract protected void prepareStuff(); 
    // here is the real processing for default controller 
    public void process() { 
    //implement common processing for GET request 
    } 
    // Prefer to use protected method instead of field 
    protected String getURL() { return DEFAULT_URL;} 
} 
// usual controller has nothing special 
class Controller1 extends AbstractController { 
    @Override 
    protected String getURL() { return "url1";} 
    @Override 
    protected prepareStuff() {// do nothing} 
} 
// do some specific preparation/checks 
class Controller2 extends AbstractController { 
    @Override 
    protected prepareStuff() {//preparation/checks here } 
    /** Note I 'forget' to override getURL() so it'll process DEFAULT_URL. 
    It could be useful if AbstractController calculates url dynamically and 
    you don't want to write boilerplate strings "/myApp/section7". 
    Also you could write abstract getURL() 
    */ 
} 
/** custom controller but you want to re-use some common code. 
In fact I would not recommend this way as usual approach */ 
class Controller3 extends AbstractController { 
    /** Overriding this method totally discards the Template pattern. 
     It could (and will) lead to confusing and errors*/ 
    @Override 
    public void doGet(params) { // new implementation } 
    @Override 
    protected prepareStuff() { 
    // you don't need it but you have to override since it abstract 
    } 
} 
// totally custom controller. Implements interface just as a marker 
class SpecificController implements Controller { 
    // In order to support legacy code just call method wich has been already written. You even no need to rename it. 
    @Override 
    public void doGet(params) { specificMethod();} 
    // lagacy method which probably is used somewhere else 
    public void specificMethod() { // the actual logic here} 
} 

の継承とTemplateパターンを使用します。 「メソッドの導入」や「親への移動」のようなIDE機能を使用して、私は一日に数十のクラスをリファクタリングしました。

は、あなたやあなたのチームメイトは、日

+0

のカップルで、このようなアイデアを実装し、比較することを願って、私は本当にあなたが答えを作るために時間を見つけて感謝、ありがとうございます!しかし、私はバニラサーブレットとのアーキテクチャ上の違いは見えません。この場合は、コマンドパターン –

+0

を使用するのと似ているようです。1.重複したコードを親のAbstractControllerに導入して減らします。あなたのチームメートとの違いは示唆しています:伸びにくいシングルコントローラ) – ADS

+0

そして、代わりに、複数のGETメソッドを持つコントローラが1つありますか? –

関連する問題