1

初期の問題

基本的に1行しか異なる異なるメソッドがある場合、1つのメソッドを作成してDRYにする方法はありますか。

例:

def showA( ) {
   def instance

    try {
        instance = A.findById( params.id )
    } catch ( Exception e ) {
        def message = "Error while retrieving details for the given id ${ params.id }, $e"
        log.error message
        responseAsJson( 400, "Invalid id", message )
        return false
    }

    return checkAndRender(instance,  params.id);
}

def showB( ) {

       def instance

        try {
            instance = B.findByBId( params.BId )
        } catch ( Exception e ) {
            def message = "Error while retrieving details for the given id ${ params.id }, $e"
            log.error message
            responseAsJson( 400, "Invalid id", message )
            return false
        }

        return checkAndRender(instance,  params.id);
    }

したがって、1 つのメソッドを作成し、単純にパラメーターとして渡す方法はありますか。

  • ドメインクラス
  • 検索するID

それとも、代わりに SQL ステートメントを渡すほうがよいでしょうか?

アップデート

@dmahapatro のコメントに基づいて、次のことを思いつきました。

def showA( ) {
        def clos = {id -> A.findByAId( id ) }
        return findAndShow(clos, params.AId, params )
    }

def showB( ) {
        def clos = {id -> B.findByBId( id ) }
        return findAndShow(clos, params.BId, params )
    }

 def findAndShow(Closure closure, def id, def p)
    {
        def instance
        try {
            instance = closure(id)
        }
        catch ( Exception e ) {
            def message = "Error while retrieving instance details for the given id ${ id }, $e"
            log.error message
            responseAsJson( 400, "Invalid Id", message )
            return false
        }

        return checkAndRender(instance,  id);
    }

残りの問題は次のとおりです。

  • さらにクリーンアップする方法/よりクリーンにする方法。
  • 警告を回避する方法:

    [ApiController] の [findAndShow] アクションは、タイプ [groovy.lang.Closure] のパラメーターを受け入れます。インターフェイス型と抽象クラス型は、コマンド オブジェクトとしてサポートされていません。このパラメーターは無視されます。

       def findAndShow(Closure closure, def id, def p)
    
4

1 に答える 1

1

DRY コードが必要な場合に最初に心配する必要があるのは、より優れた例外処理を定義することです。クライアントへの応答を処理するためにどこでもコードをキャッチしてみるのは、あまり DRY ではありません。データ アクセス コードをサービスに配置すると、サービスから例外をスローし、グローバル コントローラーを使用してエラーをキャッチし、応答を処理できます。例えば:

class ErrorController {

    def serverError() {
         if (request.format == 'json') {
            //Code for handling errors in json request, request.exception stores the data about the exception. 
        } else {
            //Code for handling errors in non-json request, e.g:
            render(view: 'error', model: [msg: 'Something went wrong']) //add an error view for this
        }
    }
}

必要に応じて、他の種類のエラー (403、404 など) のハンドラーを追加することもできます。

UrlMappings.groovy に追加

    "500"(controller: "error", action: "serverError")

これで、新しいエラー処理とリフレクションを使用してコードをリファクタリングできます。

コントローラ:

   class MyController {

        def myService

        def show() {
            def result = myService.myFind(params.className,params.id)
            render result as JSON //Render stuff
        }
    }

サービス:

       import grails.util.Holders

       class MyService {

            def myFind(String className, Long id) {
                def result = Holders.getGrailsApplication().getDomainClass('com.mypack.'+ className).findById(id)
                if(!result) {
                    throw new ServiceException('really descriptive and usefull error msg')
                }
            }
        }

instanceOf 演算子を使用して ErrorController にカスタム ロジックを追加できるように、ServiceException クラスを定義しました。

于 2014-12-03T18:07:25.630 に答える