0

私は、メタクラス プログラミングを行ったり、Grails アプリケーションを開発するときに Groovy の動的機能を (明示的に) 利用したりしていません。私は見逃しているように感じます。Grails プロジェクトで Groovy の動的機能をどこで、いつ、どのように使用するかの例をいくつか挙げていただけますか (たとえば、ドメイン、コントローラーにメソッドを追加しますか)。

4

2 に答える 2

1

Grails プロジェクトではありませんが、広範な Groovy コードを含む JBoss Seam プロジェクトで 2 年間働きました。通常、最初の引数メソッドが通常モデル クラスであるいくつかのサービス クラスがありました。カテゴリを通じて、それらは実際にオブジェクト指向になりました。

class InvoiceService {
  static void sendToWs(Invoice invoice, wsEndpoint) {
    // neat stuff
  }

  static void validate(Invoice invoice) throws InvoiceValidationException {
    // more neat stuff
  }

  static InternationalInvoice buildInternationalInvoice(Invoice invoice) {
    // builds new object
  }
}


def invoice = new Invoice()

use(InvoiceService) {
  invoice.validate()
  invoice.sendToWs endpoint
}

同じことがGrailsにも当てはまると思います。

また、多くの位置テキスト ファイルを作成し、特にカテゴリの下で多くのグルーヴィーなメソッドを使用しました。

class PositionalFormatCategory {
  static String pad(String value, Integer times) {
    value.trim().padRight times, " "
  }
  static String pad(BigDecimal value, Integer times) {
    value.toString().padLeft times, " "
  }
}

しかし、Groovy は XML の構文解析と書き込みに本当に力を入れています。4 つの異なる XML 形式に変換する必要がある単一のモデル クラスがありました。

class XmlFormat1 {
  ServiceInvoice invoice

  String toXml() {
    new StreamingMarkupBuilder().bind {
      xml {
        price invoice.value
        date invoice.creationDate
        invoice.items.each { item ->
          invoiceItem {
            price item.price
            quantity item.qty
          }
        }
      }
    }
  }
}

メタプログラミングを使用して、ダウンしている可能性のある残りのサービスに接続する小さな lib メソッドにフックしました (lib の名前は覚えていません)。タイムアウトを定義するためにそれにフックしました。そうしないと、失敗せずに一日中かかります。

def oldConnect = RestConn.metaClass.&connect
RestConn.metaClass.connect = {
  try {
    delegate.setTimeout 5000
    oldConnect()
  } catch (TimeoutException t) {
    throw new BusinessException("Timeout connecting to the server")
  }
}

打ち負かすのは難しい:-)

于 2013-02-04T12:04:13.487 に答える
0

私はメタ プログラミング機能を使用して、アプリケーション レベルでの作業を容易にしています。

EG 作成/更新時にインデックスを作成する必要があり、インデックスからコンテンツを取得するためにいくつかの動的ファインダー メソッドも必要とする検索エンジンがあります。

class SearchableClass {
    static searchable = ['foo']

    String foo
}
def searchService = [ search:{ Class clazz, Map opts, String query ->  // This would be a real service
    // doSearch
    query.collect { it }
} ]

def searchBindService = [ bindSearch:{ Class clazz ->  // This would be a real service
    clazz.metaClass.static.with {
        search = searchService.search.curry(clazz, [:])
        searchOne = { String q ->
            searchService.search(clazz, [:], q).take(1)
        }
    }
} ]

[SearchableClass, String, Map, List].findAll { // Only get things that have the 'searchable' static prop
    try {
        it.searchable != null
    }catch(e){ }
}.each searchBindService.bindSearch


assert ["q", "u", "e", "r", "y"] == SearchableClass.search('query')
assert ["q"] == SearchableClass.searchOne('query')
于 2013-02-04T10:48:36.297 に答える