web-dev-qa-db-ja.com

APIサービスへの呼び出しをキャプチャするときにコードをリファクタリングする方法

現在、新サービスのAPIの設計を担当しています。それは十分に単純に始まり、10個ほどの異なるURIが許可されました。私は最善のコードを実行していないことを知っていましたが、率直に言って、経験が足りず、AWSとAPI Gatewayを使用しているため、推奨されるオブジェクトの数が少ないため、何らかの防御策になる可能性があると考えました"より少ないクラスを使用するため。

URIを受け取って分解し、SQLクエリを作成して、行をPreparedStatementとして返すメソッド。以前は200行のコードでした。もう大きかった。

今、私ははるかに多くの電話、より多くのケースを持っています、彼らは元のケースの考えの2倍以上を望んでいます。同じ期間ですが...メソッドは500行のコードを超えるため、このように要求の厳しい変更の割合が続く場合、元の状態に維持するのが簡単ではないのではないかと心配しています。

重要なのは、アノテーションでSpringやHibernateなどを使用しないと、コードをよりオブジェクト指向にして適切にリファクタリングする方法がわかりません。

コードの例:

if(pathParameters.containsValue("profile")) {
            if(numPaths == 2 && numFilters == 0) {//http:API/profile/id
                preparedstatement = con.prepareStatement("SELECT id_profile, nombre_profile "
                        + " from profile WHERE id_profile = ?;");
                preparedstatement.setString(1, pathParameters.get("nivelPath1"));
            }
            else if(numPaths == 1) {

            //[... More code....]


if(pathParameters.containsValue("skill")) {
            if(pathParameters.size() == 2 && numFilters == 0) {//http:API/skill/id
                preparedstatement = con.prepareStatement("SELECT id_skill, nombre_skill FROM skill WHERE id_skill = ?;");
                preparedstatement.setString(1, pathParameters.get("nivelPath1"));
            }
            else if (numPaths == 1) {
            if(queryParameters == null || queryParameters.isEmpty()) {//http:API/skill
                    preparedstatement = con.prepareStatement("SELECT oferta_skill_perfil.id_skill " + 
                            "FROM oferta_skill_perfil " + 
                            "INNER JOIN skill " + 
                            "ON skill.id_skill=oferta_skill_perfil.id_skill  " + 
                            "GROUP BY oferta_skill_perfil.id_skill " + 
                            "ORDER BY COUNT(oferta_skill_perfil.id_skill) DESC " + 
                            "LIMIT 10 ;");
                }
                //[... More code....]

            //[... More code....]

//[... More code....]

つまり、基本的に方法は大きすぎますが、それをどのように分解すればよいのかを理解するのに苦労しています。これは、URIを取得し、それを分解してクエリを作成するメソッドであるため、それを小さなメソッドに分割しても、リファクタリングの方法を確認できないため、ロジックがより頻繁に適用され、行の総数を減らすことができます。

1
monkey intern

コードをよりオブジェクト指向にして適切にリファクタリングする方法を知りません

コードを「よりオブジェクト指向」にしたくない。 OOはそれ自体が目的ではなく、目的を達成するための手段です。 より少ないコード、特により少ないボイラープレートコード、より少ない繰り返しコードを記述したいとします。 APIの実装の多くには、何度も繰り返したくない非常によく似たセクションが含まれていると思います。

残念ながら、これに対する特効薬はありません。コードを進化させるには、いくつかの設計技法を適用する必要があります。それらのいくつかは多分OO技法であり、いくつかはより機能的であり、いくつかはSOLID原則のようにより一般的です。手始めに、厳格に実行すると、目標に近づくのに役立ついくつかの戦術について述べたいと思います。

  • 小さいメソッドに大きくリファクタリングします。200行は大きすぎて、20行でもIMHOはまだ大きすぎます。コードをより乾燥させたい場合は、メソッドごとに2行から6行を超えないようにすると思われる基本的な再利用可能な関数のセットが必要です。次のような習慣を身に付けることをお勧めします。エディターで「コピーと貼り付け」を使用するときは常に、少し息を止めて、コピーしているものの少なくとも一部を別のメソッドにリファクタリングできるかどうか自問してください。

  • 実装をより多く作成しようデータ駆動型:APIパラメータとデータモデルのニュートラルで簡潔な機械可読な記述を作成し、それを表形式のデータ構造またはXMLファイルに入れて、生成を試みますそれに関連するすべてのSQLステートメント。これには、いくつかのメタデータ(dbテーブルの列名やデータ型など)へのアクセスが必要になります。これらを説明テーブルに提供するか、データベースから取得できます。そして、この考えの延長:

  • 独自の「コードジェネレーター」を開発します。SQLステートメントの生成だけでは不十分な場合は、CRUDコードのほとんどを自分で生成しませんか? 1つまたは2つのdbテーブルの場合、これはおそらく価値がありませんが、テーブルの数が10を超えると、通常は効果があります。

ジェネレーターツールは、テキストファイルやXMLファイルを入力として使用したり、データベースからのメタデータを使用したり、クラスの注釈やリフレクションを使用したり、ドメイン固有の言語を使用したりするなど、さまざまな方法で実装できます。生成は、コンパイル前、実行時、またはその両方で行うことができます。これには「万能」の解決策はありません。あなたは自分の状況に最適なものを実験して見つける必要があります。

今度は「私のSQLはすべて異なって見え、それぞれにこれらの異なるGROUP BYまたはLIMITステートメントがあり、十分に均一ではありません」ですが、これはたとえば、データベースにいくつかのビューを導入して、結合、集計、制限をカプセル化することで、少なくともビューに均一な方法でアクセスできるようになります。それほど簡単に解決できない場合は、コードを手動で作成する必要があります。しかし、ジェネレーターツールなしでCRUDコードの30%を記述する必要があることが判明した場合でも、「退屈なコード」の70%を節約したので、現在の状況よりも有利です。

2
Doc Brown

ディスパッチャのようなもの、つまりパス/ URIをアクション/コントローラにマッピングするもの、たとえば.

/API/profile/:id => ProfilesController.getProfileById()
/API/skill/:id   => SkillsController.getSkillById()

これは、左側のパスを指定して、右側のクラス/メソッドを呼び出すことです。

このようにして、すべての異なるアクションをいくつかの小さなクラスに分割して、より保守しやすくすることができます。

URIにはパラメータが含まれている可能性があるため、ルータからコントローラにURIを渡す方法が必要になることに注意してください。また、要件に応じて、パス、クエリ文字列、ヘッダーなどにパラメーターを含めることができます。そのため、これらのパラメーターをすべてRequestクラスに抽出できます。そして、コントローラーはそのリクエストをディスパッチします。

おおまかに言えば、次のようになります。

  1. URIを受け取り、それを解析してRequestオブジェクトにします
  2. リクエストに応じて適切なコントローラーを選択します
  3. コントローラーでメソッドを呼び出す

もちろん、独自の自家製ルーター/ディスパッチャーを使用することもできます...または、Springのようなフレームワークを使用することもできます。

あなたがあなた自身の実装に本当に興味があるなら、私が説明したものはかなり 戦略パターン です。

2
Armando Garza