SlideShare a Scribd company logo
1 of 77
Download to read offline
Java x Groovyで
         開発効率を高めよう
         Java Developer Workshop #2
                日本Grails Groovyユーザ会
                       上原 潤二
                      2011.12.1

2011年12月1日木曜日
自己紹介
      上原潤二(@uehaj)
         NTTソフトウェア株式会社
         JGGUG運営委員
         プログラミングGROOVY(技術評
         論社)共著
         Grails徹底入門(翔泳社)共著
         ブログ「Grな日々」
         GroovyServ, LispBuilder, GVM
         開発者
2011年12月1日木曜日
本日皆さんに伝えたいこと
            Groovyとは何か?
            Groovyは簡単なのか?
            Groovyは便利なのか?
            JavaプログラマにとってGroovyと
            は何か?




                3
2011年12月1日木曜日
Groovyとは何か
         Java VM上で動作する動的なスクリプト言語
            構文はJavaと 上位互換
                    ほぼ



            プラットフォームやセキュリティモデルは全く
            同じ
         ユニークな特徴:
         Javaと共存・併用するための言語
         主要開発者はVMWare社(Spring Source)に所属




                4
2011年12月1日木曜日
コード例1: HelloWorld.java __
     public class HelloWorld {
         public static void main(String[] args) {
             System.out.println("Hello world");
         }
     }




                5
2011年12月1日木曜日
コード例1: HelloWorld.groovy
     public class HelloWorld {
         public static void main(String[] args) {
             System.out.println("Hello world");
         }
     }




                6
2011年12月1日木曜日
コード例1: HelloWorld.groovy
     public class HelloWorld {
         public static void main(String[] args) {
             System.out.println("Hello world");
         }
     }




            Javaソースコードの拡張子.java
            を.groovyに変更するだけで
            groovyコードとして実行できる。
                6
2011年12月1日木曜日
コード例1: hello.groovy

     println "hello world"




                7
2011年12月1日木曜日
コード例1: hello.groovy

     println "hello world"


     Groovyでは以下が省略可能:
           main,クラス定義,文末のセミコロ
           ン, System.out,メソッド呼び出し
           の括弧,(例外宣言,静的型宣言,
           import宣言) etc..
                7
2011年12月1日木曜日
Groovyは何で無いか




                8
2011年12月1日木曜日
Groovyは何で無いか
        別言語をJVMにポーティングしたもので
        はない




                8
2011年12月1日木曜日
Groovyは何で無いか
        別言語をJVMにポーティングしたもので
        はない
       ➡JVM以外では動かない




                8
2011年12月1日木曜日
Groovyは何で無いか
        別言語をJVMにポーティングしたもので
        はない
       ➡JVM以外では動かない
        Next Javaではない




                8
2011年12月1日木曜日
Groovyは何で無いか
        別言語をJVMにポーティングしたもので
        はない
       ➡JVM以外では動かない
        Next Javaではない
       ➡Javaを駆逐しない・パラダイムシフトしない




                8
2011年12月1日木曜日
Groovyは何で無いか
        別言語をJVMにポーティングしたもので
        はない
       ➡JVM以外では動かない
        Next Javaではない
       ➡Javaを駆逐しない・パラダイムシフトしない
        過去のOSSプロジェクトではない




                8
2011年12月1日木曜日
Groovyは何で無いか
        別言語をJVMにポーティングしたもので
        はない
       ➡JVM以外では動かない
        Next Javaではない
       ➡Javaを駆逐しない・パラダイムシフトしない
        過去のOSSプロジェクトではない
       ➡活発な開発と意欲的な機能拡張が続いている


                8
2011年12月1日木曜日
Groovyの特徴4つ
                    Javaと親和性
         簡潔         が高い




       高機能           柔軟
                9
2011年12月1日木曜日
Groovyの特徴4つ
                     Javaと親和性
         簡潔          が高い

     本日は上記2つの特徴を中心に紹介し
     ます。

       高機能            柔軟
                10
2011年12月1日木曜日
簡潔

                11
                     http://www.flickr.com/photos/dan_culleton/4905300673/
2011年12月1日木曜日
例:ワードカウント処理
            テキストファイル中の単語の出現回数
            を数える

         $ cat input.txt
         That that is is that that is
         not is not is that it it is

         $ java WordCount input.txt
         1: That
         2: not
         2: it
         4: that
         6: is
                12
2011年12月1日木曜日
ワードカウント処理(Java)
      import java.util.Comparator;                      Object[] list = entrySet.toArray();
 import java.util.HashMap;                               Comparator comp = new Comparator(){
 import java.util.Map;                                    public int compare(Object o1, Object o2)
 import java.util.Set;                             {
 import java.util.List;                                     Map.Entry<String, Integer> e1 =
 import java.util.Arrays;                          (Map.Entry<String, Integer>) o1;
 import java.io.FileReader;                                 Map.Entry<String, Integer> e2 =
 import java.io.BufferedReader;                    (Map.Entry<String, Integer>) o2;
 import java.io.FileNotFoundException;                       return e1.getValue() - e2.getValue();
 import java.io.IOException;                               }
                                                         };
 public class WordCount {                                Arrays.sort(list, comp);
   @SuppressWarnings(value = "unchecked")                for (Object it: list) {
   public static void main(String[] args) {                Map.Entry<String, Integer> entry =
     FileReader fis = null;                        (Map.Entry<String, Integer>)it;
     BufferedReader br = null;                             System.out.println(entry.getValue() + ":
     try {                                         "+entry.getKey());
       HashMap<String, Integer> map = new                }
 HashMap<String, Integer>();                           }
       fis = new FileReader(args[0]);                  catch (IOException e) {
       br = new BufferedReader(fis);                     try {if (br != null) br.close();}catch
       String line;                                (IOException ioe){}
       while ((line = br.readLine()) != null) {          try {if (fis != null)fis.close();}catch
         for (String it: line.split("W+")) {     (IOException ioe){}
           map.put(it, (map.get(it)==null) ? 1 :         e.printStackTrace();
 (map.get(it) + 1));                                   }
         }                                           }
       }
      Set<Map.Entry<String, Integer>> entrySet =
                                                   }                    48行
 map.entrySet();
                     13
2011年12月1日木曜日
ワードカウント処理(Groovy)
def words = new File(args[0]).text.split(/W+/)
words.countBy{it}.entrySet().sort{it.value}.each {
   println "${it.value}: ${it.key}"
}




                                       4行


                14
2011年12月1日木曜日
.text
def words = new File(args[0]).text.split(/W+/)
words.countBy{it}.entrySet().sort{it.value}.each {
     .getText()の略記法
   println "${it.value}: ${it.key}"
}
     File#getText()はJava APIに
     対して追加されたGDKメソッド
       ファイル内容の全体を1つの
       Stringとして返す



2011年12月1日木曜日
GDKメソッド
             Java標準APIクラスにメソッドを追加
             java.lang.Stringを例にとると、
                     Java標準APIは、65個メソッド
                     GDKでは、91個のメソッド追加
  asType(Class c)         execute(List envp,      getAt(Collection       padLeft(Number         replaceFirst(Pattern   toInteger()
  bitwiseNegate()         File dir)               indices)               numberOfChars)         pattern, Closure       toList()
  capitalize()            expand()                getChars()             padRight(Number        closure)               toLong()
  center(Number           expand(int tabStop)     isAllWhitespace()      numberOfChars,         reverse()              toSet()
  numberOfChars,          expandLine(int          isBigDecimal()         String padding)        size()                 toShort()
  String padding)         tabStop)                isBigInteger()         padRight(Number        split()                toURI()
  center(Number           find(String regex)      isCase(Object          numberOfChars)         splitEachLine(String   toURL()
  numberOfChars)          find(Pattern pattern)   switchValue)           plus(Object value)     regex, Closure         tokenize(String
  contains(String text)   find(String regex,      isDouble()             previous()             closure)               token)
  count(String text)      Closure closure)        isFloat()              readLines()            splitEachLine          tokenize(Character
  decodeBase64()          find(Pattern pattern,   isInteger()            replaceAll(Pattern     (Pattern pattern,      token)
  denormalize()           Closure closure)        isLong()               pattern, String        Closure closure)       tokenize()
  eachLine(Closure        findAll(String regex)   isNumber()             replacement)           stripIndent()          tr(String sourceSet,
  closure)                findAll(Pattern         leftShift(Object       replaceAll(String      stripIndent(int        String
  eachLine(int            pattern)                value)                 regex, Closure         numChars)              replacementSet)
  firstLine, Closure      findAll(String regex,   matches(Pattern        closure)               stripMargin()          unexpand()
  closure)                Closure closure)        pattern)               replaceAll(Pattern     stripMargin(String     unexpand(int
  eachMatch(String        findAll(Pattern         minus(Object target)   pattern, Closure       marginChar)            tabStop)
  regex, Closure          pattern, Closure        multiply(Number        closure)               stripMargin(char       unexpandLine(int
  closure)                closure)                factor)                replaceFirst(Pattern   marginChar)            tabStop)
  eachMatch(Pattern       getAt(int index)        next()                 pattern, String        toBigDecimal()
  pattern, Closure        getAt(IntRange          normalize()            replacement)           toBigInteger()
  closure)                range)                  padLeft(Number         replaceFirst(String    toBoolean()
  execute()               getAt(EmptyRange        numberOfChars,         regex, Closure         toCharacter()
  execute(String[]        range)                  String padding)        closure)               toDouble()
  envp, File dir)         getAt(Range range)                                                    toFloat()
                            16
2011年12月1日木曜日
GDKメソッド
             Java標準APIクラスにメソッドを追加
             java.lang.Stringを例にとると、
                     Java標準APIは、65個メソッド
                     GDKでは、91個のメソッド追加
  asType(Class c)         execute(List envp,      getAt(Collection       padLeft(Number         replaceFirst(Pattern   toInteger()
  bitwiseNegate()         File dir)               indices)               numberOfChars)         pattern, Closure       toList()
  capitalize()            expand()                getChars()             padRight(Number        closure)               toLong()
  center(Number           expand(int tabStop)     isAllWhitespace()      numberOfChars,         reverse()              toSet()

 “ls”.execute()
  numberOfChars,
  String padding)
  center(Number
                          expandLine(int
                          tabStop)
                          find(String regex)
                                                  isBigDecimal()
                                                  isBigInteger()
                                                  isCase(Object
                                                                         String padding)
                                                                         padRight(Number
                                                                         numberOfChars)
                                                                                                size()
                                                                                                split()
                                                                                                splitEachLine(String
                                                                                                                       toShort()
                                                                                                                       toURI()
                                                                                                                       toURL()


 " lsコマンドを実行(Processが返る)
  numberOfChars)          find(Pattern pattern)   switchValue)           plus(Object value)     regex, Closure         tokenize(String
  contains(String text)   find(String regex,      isDouble()             previous()             closure)               token)
  count(String text)      Closure closure)        isFloat()              readLines()            splitEachLine          tokenize(Character
  decodeBase64()          find(Pattern pattern,   isInteger()            replaceAll(Pattern     (Pattern pattern,      token)
  denormalize()           Closure closure)        isLong()               pattern, String        Closure closure)       tokenize()
  eachLine(Closure        findAll(String regex)   isNumber()             replacement)           stripIndent()          tr(String sourceSet,
  closure)                findAll(Pattern         leftShift(Object       replaceAll(String      stripIndent(int        String
  eachLine(int            pattern)                value)                 regex, Closure         numChars)              replacementSet)
  firstLine, Closure      findAll(String regex,   matches(Pattern        closure)               stripMargin()          unexpand()
  closure)                Closure closure)        pattern)               replaceAll(Pattern     stripMargin(String     unexpand(int
  eachMatch(String        findAll(Pattern         minus(Object target)   pattern, Closure       marginChar)            tabStop)
  regex, Closure          pattern, Closure        multiply(Number        closure)               stripMargin(char       unexpandLine(int
  closure)                closure)                factor)                replaceFirst(Pattern   marginChar)            tabStop)
  eachMatch(Pattern       getAt(int index)        next()                 pattern, String        toBigDecimal()
  pattern, Closure        getAt(IntRange          normalize()            replacement)           toBigInteger()
  closure)                range)                  padLeft(Number         replaceFirst(String    toBoolean()
  execute()               getAt(EmptyRange        numberOfChars,         regex, Closure         toCharacter()
  execute(String[]        range)                  String padding)        closure)               toDouble()
  envp, File dir)         getAt(Range range)                                                    toFloat()
                            16
2011年12月1日木曜日
GDKメソッド
             Java標準APIクラスにメソッドを追加
             java.lang.Stringを例にとると、
                     Java標準APIは、65個メソッド
                     GDKでは、91個のメソッド追加
  asType(Class c)         execute(List envp,      getAt(Collection       padLeft(Number         replaceFirst(Pattern   toInteger()
  bitwiseNegate()         File dir)               indices)               numberOfChars)         pattern, Closure       toList()
  capitalize()            expand()                getChars()             padRight(Number        closure)               toLong()
  center(Number           expand(int tabStop)     isAllWhitespace()      numberOfChars,         reverse()              toSet()

 “ls”.execute()
  numberOfChars,
  String padding)
  center(Number
                          expandLine(int
                          tabStop)
                          find(String regex)
                                                  isBigDecimal()
                                                  isBigInteger()
                                                  isCase(Object
                                                                         String padding)
                                                                         padRight(Number
                                                                         numberOfChars)
                                                                                                size()
                                                                                                split()
                                                                                                splitEachLine(String
                                                                                                                       toShort()
                                                                                                                       toURI()
                                                                                                                       toURL()


 " lsコマンドを実行(Processが返る)
  numberOfChars)          find(Pattern pattern)   switchValue)           plus(Object value)     regex, Closure         tokenize(String
  contains(String text)   find(String regex,      isDouble()             previous()             closure)               token)
  count(String text)      Closure closure)        isFloat()              readLines()            splitEachLine          tokenize(Character
  decodeBase64()          find(Pattern pattern,   isInteger()            replaceAll(Pattern     (Pattern pattern,      token)
  denormalize()           Closure closure)        isLong()               pattern, String        Closure closure)       tokenize()
  eachLine(Closure        findAll(String regex)   isNumber()             replacement)           stripIndent()          tr(String sourceSet,
  closure)                findAll(Pattern         leftShift(Object       replaceAll(String      stripIndent(int        String
  eachLine(int            pattern)                value)                 regex, Closure         numChars)              replacementSet)
  firstLine, Closure      findAll(String regex,   matches(Pattern        closure)               stripMargin()          unexpand()
  closure)                Closure closure)        pattern)               replaceAll(Pattern     stripMargin(String     unexpand(int

    “あいうえお”.tr(“あ-ん”,”ア-ン”)
  eachMatch(String
  regex, Closure
  closure)
                          findAll(Pattern
                          pattern, Closure
                          closure)
                                                  minus(Object target)
                                                  multiply(Number
                                                  factor)
                                                                         pattern, Closure
                                                                         closure)
                                                                         replaceFirst(Pattern
                                                                                                marginChar)
                                                                                                stripMargin(char
                                                                                                marginChar)
                                                                                                                       tabStop)
                                                                                                                       unexpandLine(int
                                                                                                                       tabStop)
  eachMatch(Pattern       getAt(int index)        next()                 pattern, String        toBigDecimal()



    " “アイウエオ”
  pattern, Closure        getAt(IntRange          normalize()            replacement)           toBigInteger()
  closure)                range)                  padLeft(Number         replaceFirst(String    toBoolean()
  execute()               getAt(EmptyRange        numberOfChars,         regex, Closure         toCharacter()
  execute(String[]        range)                  String padding)        closure)               toDouble()
  envp, File dir)         getAt(Range range)                                                    toFloat()
                            16
2011年12月1日木曜日
.split(/正規表現/)
def words = new File(args[0]).text.split(/W+/)
words.countBy{it}.entrySet().sort{it.value}.each {
   println "${it.value}: ${it.key}"
}    /∼/は文字列定数の記法。ただし
     文字’’を特別扱いしない
      “W” == /W/
     Java APIの
     String#split(String)

2011年12月1日木曜日
.countBy{}
def words = new File(args[0]).text.split(/W+/)
words.countBy{it}.entrySet().sort{it.value}.each {
   println "${it.value}: ${it.key}"
} countByはコレクション・イテレータに対
     して追加されたGDKメソッド
     分類基準に基づいて要素をグルーピングし
     た上でグループごとの要素数をカウントする




2011年12月1日木曜日
.countBy{}
     リスト
        “ABC”        “ABC”   “DEF”   “GHI”   “ABC”   “GHI”


                                countBy{it}
                                       分類基準をクロージャで与える

     マップ
         “ABC” : 3              “DEF” : 1        “GHI” : 2


  コレクションやイテレータに対してcountByを適用する
  と、分類基準で分類されたグループをキー、そのグループの
  要素数をバリューとするマップが得られる。(c.f. groupBy)
                19
2011年12月1日木曜日
.entrySet().sort{}
def words = new File(args[0]).text.split(/W+/)
words.countBy{it}.entrySet().sort{it.value}.each {
   println "${it.value}: ${it.key}"
} entrySet()はJava API

     sortはクロージャで比較するソート(GDKメ
     ソッド)




2011年12月1日木曜日
each, GString
def words = new File(args[0]).text.split(/W+/)
words.countBy{it}.entrySet().sort{it.value}.each {
   println "${it.value}: ${it.key}"
}


        eachはそれぞれに対して処理(クロージャ)
        文字列中の$変数名、${ブロック}はその値
        に置換される(GString)



                21
2011年12月1日木曜日
簡潔さをもたらしたもの

      各種の省略
      言語機能
      高機能ライブラリ




                22
2011年12月1日木曜日
短かさの意味
      Javaに比してコード量は1/5∼1/3
          短かければ良いわけではない
            短くて分かりにくくなることもある

      重要なのは「やりたい事(what)/コード量」
      のSN比



                23
2011年12月1日木曜日
これは何でしょう?
                                                        Set<Map.Entry<String, Integer>> entrySet =
import   java.util.Comparator;                    map.entrySet();
import   java.util.HashMap;                             Object[] list = entrySet.toArray();
import   java.util.Map;                                 Comparator comp = new Comparator(){
import   java.util.Set;                                   public int compare(Object o1, Object o2) {
import   java.util.List;                                    Map.Entry<String, Integer> e1 =
import   java.util.Arrays;                        (Map.Entry<String, Integer>) o1;
import   java.io.FileReader;                                Map.Entry<String, Integer> e2 =
import   java.io.BufferedReader;                  (Map.Entry<String, Integer>) o2;
import   java.io.FileNotFoundException;                     return e1.getValue() - e2.getValue();
import   java.io.IOException;                             }
                                                        };
public class WordCount {                                Arrays.sort(list, comp);
  @SuppressWarnings(value = "unchecked")                for (Object it: list) {
  public static void main(String[] args) {                Map.Entry<String, Integer> entry =
    FileReader fis = null;                        (Map.Entry<String, Integer>)it;
    BufferedReader br = null;                             System.out.println(entry.getValue() + ":
    try {                                         ["+entry.getKey()+"]");
      HashMap<String, Integer> map = new                }
HashMap<String, Integer>();                           }
      fis = new FileReader(args[0]);                  catch (IOException e) {
      br = new BufferedReader(fis);                     try {if (br != null) br.close();}catch
      String line;                                (IOException ioe){}
      while ((line = br.readLine()) != null) {          try {if (fis != null)fis.close();}catch
        for (String it: line.split("s+")) {     (IOException ioe){}
          map.put(it, (map.get(it)==null) ? 1 :         e.printStackTrace();
(map.get(it) + 1));                                   }
        }                                           }
      }                                           }


                       24
2011年12月1日木曜日
これは何でしょう?
                                                        Set<Map.Entry<String, Integer>> entrySet =
import   java.util.Comparator;                    map.entrySet();
import   java.util.HashMap;                             Object[] list = entrySet.toArray();
import
import   答:Java版ワードカウントから「処理
         java.util.Map;
         java.util.Set;
                                                        Comparator comp = new Comparator(){
                                                          public int compare(Object o1, Object o2) {
import   java.util.List;                                    Map.Entry<String, Integer> e1 =


         の記述」を抜き出したもの。
import   java.util.Arrays;                        (Map.Entry<String, Integer>) o1;
import   java.io.FileReader;                                Map.Entry<String, Integer> e2 =
import   java.io.BufferedReader;                  (Map.Entry<String, Integer>) o2;
import   java.io.FileNotFoundException;                     return e1.getValue() - e2.getValue();
import   java.io.IOException;                             }
                                                        };
public class WordCount {                                Arrays.sort(list, comp);
  @SuppressWarnings(value = "unchecked")                for (Object it: list) {
  public static void main(String[] args) {                Map.Entry<String, Integer> entry =
    FileReader fis = null;                        (Map.Entry<String, Integer>)it;
    BufferedReader br = null;                             System.out.println(entry.getValue() + ":
    try {                                         ["+entry.getKey()+"]");
      HashMap<String, Integer> map = new                }
HashMap<String, Integer>();                           }
      fis = new FileReader(args[0]);                  catch (IOException e) {
      br = new BufferedReader(fis);                     try {if (br != null) br.close();}catch
      String line;                                (IOException ioe){}
      while ((line = br.readLine()) != null) {          try {if (fis != null)fis.close();}catch
        for (String it: line.split("s+")) {     (IOException ioe){}
          map.put(it, (map.get(it)==null) ? 1 :         e.printStackTrace();
(map.get(it) + 1));                                   }
        }                                           }
      }                                           }


                       24
2011年12月1日木曜日
短かさの効用
      Groovyの記述レベルは人間の認知
      レベルでの「やって欲しいこと」の
      記述に近い
      ➡理解性向上
      ➡リファクタリングの頻度減少

                25
2011年12月1日木曜日
Javaと親和性が高い




                26
2011年12月1日木曜日
Java親和性(1):文法
      正しいJavaコードは、正しいGroovyコード
      (ほぼ上位互換)
         以下を含めて
                アノテーション,enum, Generics
                Java7機能(一部未対応)




                 27
2011年12月1日木曜日
Java親和性(2):API
            Java APIをそのままもしくは拡張して使う
                例えばGroovy独自のコレクションクラス
                群というものはない
            GDK(Groovy Development Kit)
                Java APIにメソッドを追加




                28
2011年12月1日木曜日
Java親和性(3):相互運用
      Groovyコードは常にJavaクラスに変換された上
      で実行される。(次項)
      Java VMから見てGroovyコードは普通のJava
      クラス
            ラッパークラスは無い
            スクリプト(mainメソッドやクラス定義がな
            いGroovyコード)も内部的にクラスが生成さ
            れて実行される


                29
2011年12月1日木曜日
Javaコードの実行
          Javaソース

                javac

          .classファイル


                 javaコマンド

   JVM

          標準クラスローダ

            Javaクラス


                 30

2011年12月1日木曜日
Groovyコードの実行
          Javaソース                Groovyコード

                javac

          .classファイル


                 javaコマンド         groovyコマンド

   JVM

          標準クラスローダ          Groovyクラスローダ
                            (オンメモリ実行時コンパイラ)


            Javaクラス                  Javaクラス


                 31

2011年12月1日木曜日
Groovyコードの実行
          Javaソース                        Groovyコード

                javac        groovyc

          .classファイル        .classファイル


                 javaコマンド                groovyコマンド

   JVM

          標準クラスローダ              Groovyクラスローダ
                               (オンメモリ実行時コンパイラ)


            Javaクラス         Javaクラス          Javaクラス


                 31

2011年12月1日木曜日
Groovyコードの実行
          Javaソース                        Groovyコード

                javac        groovyc

          .classファイル        .classファイル


                 javaコマンド                groovyコマンド

   JVM

          標準クラスローダ              Groovyクラスローダ
                               (オンメモリ実行時コンパイラ)


            Javaクラス         Javaクラス          Javaクラス


                 31     呼び出し・継承自由
2011年12月1日木曜日
Java開発への取り込み方
     7つの利用パターンを元にして
 http://www.flickr.com/photos/holeymoon/1634408365/
              32
2011年12月1日木曜日
Groovy「7つの利用パターン」
                                  by Dierk König
      万能接着剤(Super Glue): Javaのコンポーネントやフレームワークを
      Groovyを糊(glue)としてつなぐ
      やわらかな心臓部(Liquid Heart): 中核となるロジックだけをGroovy/
      DSLで書けるようにする
      お化粧(Lipstick): Javaのライブラリを簡潔に利用できる層をもうけ
      る。
      内視鏡手術(Keyhole Surgery): 実行時にGroovyスクリプトを接続で
      きる小さな口を用意しておく
      無制限の開放(Unlimited Openness): 全部Groovyで書く
      小人さんスクリプト(House-elf Script): 周辺の各種支援スクリプト
      をGroovyで書く
      ゴーストライター(Ghost Writer): 裏でコード生成

                33
2011年12月1日木曜日
Groovyの利用パターン(1 of 7)
     万能接着剤(Super Glue): Javaのコンポーネントやフレー
     ムワークをGroovyが糊(glue)としてつなぐ




                            Groovy

                     Java     Java    Java

                            JavaAPI

                            Java VM

                34
2011年12月1日木曜日
万能接着剤(Super Glue)の例
    やりたいこと:

           指定ファイルをbzip2圧縮して
           httpファイルアップロード



                       Groovy

                     ant   HttpUnit

                35
2011年12月1日木曜日
ant+HtmlUnit
    @Grab('net.sourceforge.htmlunit:htmlunit:2.8')
    import com.gargoylesoftware.htmlunit.WebClient;

    new AntBuilder().bzip2(src:args[0], zipfile:args[0]+".bz2")

    def url = "http://pukiwiki.example.com/index.php?
    plugin=attach&pcmd=upload&page=test"
    def page = new WebClient().getPage(url)
    def fileField = page.getElementById('_p_attach_file')
    fileField.valueAttribute = args[0]+".bz2"
    page.getByXPath("//input[@value='アップロード']")[0].click()




                36
2011年12月1日木曜日
ant+HtmlUnit
    @Grab('net.sourceforge.htmlunit:htmlunit:2.8')
    import com.gargoylesoftware.htmlunit.WebClient;

    new AntBuilder().bzip2(src:args[0], zipfile:args[0]+".bz2")

    def url = "http://pukiwiki.example.com/index.php?
    plugin=attach&pcmd=upload&page=test"
    def page = new WebClient().getPage(url)
    def fileField = page.getElementById('_p_attach_file')
    fileField.valueAttribute = args[0]+".bz2"
    page.getByXPath("//input[@value='アップロード']")[0].click()




                            依存ライブ
                           ラリの実行時
                            自動取得
                36
2011年12月1日木曜日
ant+HtmlUnit
    @Grab('net.sourceforge.htmlunit:htmlunit:2.8')
    import com.gargoylesoftware.htmlunit.WebClient;

    new AntBuilder().bzip2(src:args[0], zipfile:args[0]+".bz2")

    def url = "http://pukiwiki.example.com/index.php?
    plugin=attach&pcmd=upload&page=test"
    def page = new WebClient().getPage(url)
    def fileField = page.getElementById('_p_attach_file')
    fileField.valueAttribute = args[0]+".bz2"
    page.getByXPath("//input[@value='アップロード']")[0].click()



    Java資産の有                依存ライブ
       効活用                 ラリの実行時
    (HtmlUnit, Ant)         自動取得
                36
2011年12月1日木曜日
@Grab/Grape
    @Grab('net.sourceforge.htmlunit:htmlunit:2.8')
    import com.gargoylesoftware.htmlunit.WebClient;

                     group指定       module指定      versoin指定


          Grape
                Groovyスクリプト用の依存Jar管理機構
                Apache Ivyベース/Maven互換
          スクリプトを初回実行時に依存jarを自
          動ダウンロード

                37
2011年12月1日木曜日
Groovyの利用パターン (2 of 7)

     やわらかな心臓部(Liquid Heart): 中核となるロジックだ
     けをGroovy/DSLで書けるようにする


                                  頻繁な変更

                     Groovy/DSL

                        Java

                       JavaAPI

                       Java VM

                38
2011年12月1日木曜日
やわらかな心臓部(LiquidHeart)の例

        JavaからGroovyを呼びだす


   Binding binding = new Binding();
   GroovyShell shell = new GroovyShell(binding);
   File script = new File(filename);
   shell.evaluate(script);




                39
2011年12月1日木曜日
Groovyの利用パターン (3 of 7)

     お化粧(Lipstick): Javaのライブラリ・コンポーネントを
     簡潔に利用できる層をもうける。


                  Groovy
                   Wrapper
                Javaコンポーネント

                   JavaAPI

                   Java VM


2011年12月1日木曜日
お化粧(Lipstick)の例
                GroovyFX

                 JavaFX


                      Grails

          Spring FW            Hibernate



                Geb              Gant/AntBuilder

           Selenium                    Ant

                 41
2011年12月1日木曜日
GroovyFX
     Scene Graph DSL: 画面部品のツリー構造を
     Groovyのビルダーで記述
  new SceneGraphBuilder().
  stage(title:"Title",width:400,height:300,visible:true,resizable:true) {
      scene(fill: groovyblue) {
          rectangle x: 20, y: 20, width: 100, height: 50, fill: blue
          onMouseClicked { println "hello" }
      }
  }


     Timeline DSL: 時間軸制御
  timeline {
      at(2.s) {
          change(myCircle, 'layoutX'){ to 500 }
      }
  }
                42
2011年12月1日木曜日
Groovyの利用パターン (4 of 7)

     内視鏡手術(Keyhole Surgery): 実行時にGroovyスクリ
     プトを接続できる小さな口を用意しておく


                                       外部から
                                       Groovyコードを
                                       注入

                         GroovyShell
                Java

                       JavaAPI

                       Java VM

                43
2011年12月1日木曜日
内視鏡手術(Keyhole Surgery) の例


      Jenkinsのスクリプトコンソール
      Jenkins CLI
      Grails Console Plugin




                44
2011年12月1日木曜日
Groovyの利用パターン (6 of 7)

         小人さんスクリプト(House-elf Script): 周辺の各種支援
         スクリプトをGroovyで書く



                            周辺スクリプト
      開発対象のシステム

              Java            Groovy
            JavaAPI            JavaAPI

            Java VM            Java VM

1                    45
    2011年12月1日木曜日
Groovyの利用パターン (7 of 7)

         ゴーストライター(Ghost Writer): 裏でコード生成




                            Groovyコード

                         自動生成されるバイトコード


                             JavaAPI

                             Java VM

1                   32
                    46
    2011年12月1日木曜日
ゴーストライターの例
       やりたいこと:イミュータブル(不変)クラスを定
       義しよう!
         クラスはfinalに
         全フィールドをfinalかつprivate
         getter定義
         Mutableなフィールド (配列やStringBufferや
       Dateなど) の取得に対しては「防御的コピー」
         全フィールドをコンストラクタで初期化するコン
       ストラクタを定義
         フィールドの値に基づくequals, hashCode,
       toStringを定義する


          参考: Effective Java (2nd Edition), p73: Item15 Minimize
          mutability
2011年12月1日木曜日
Java版 イミュータブルクラス: 57行
  public final class Person {                                         if (getClass() != obj.getClass())
      private final String firstName;                                     return false;
      private final String lastName;                                  Person other = (Person) obj;
                                                                      if (firstName == null) {
      public Person(String firstName, String lastName) {                  if (other.firstName != null)
          this.firstName = firstName;                                         return false;
          this.lastName = lastName;                                   } else if (!firstName.equals(other.firstName))
      }                                                                   return false;
                                                                      if (lastName == null) {
      public String getFirstName() {                                      if (other.lastName != null)
          return firstName;                                                   return false;
      }                                                               } else if (!lastName.equals(other.lastName))
                                                                          return false;
      public String getLastName() {                                   return true;
          return lastName;                                        }
      }
                                                                  @Override
      @Override                                                   public String toString() {
      public int hashCode() {                                         return "Person(firstName:" + firstName
          final int prime = 31;                                           + ", lastName:" + lastName + ")";
          int result = 1;                                         }
          result = prime * result + ((firstName == null)
              ? 0 : firstName.hashCode());                    }
          result = prime * result + ((lastName == null)
              ? 0 : lastName.hashCode());
          return result;
      }

      @Override
      public boolean equals(Object obj) {
                                                                         やすく、
          if (this == obj)
                                                                 、ミスが混入し
              return true;
                                                           作成が大変       はない
                                                                 ド上明確で
          if (obj == null)
              return false;
                                                           意図がコー

                                                                          参考: http://groovy.codehaus.org/Immutable+AST+Macro


                         48
2011年12月1日木曜日
Groovy版イミュータブルクラス: 4行

                     これ
                         だけ
                             です
   @Immutable                  よ!こ
                                     れだ
   class Person {                      け
       String firstName, lastName
   }




                49
2011年12月1日木曜日
Groovy版イミュータブルクラス: 4行

                     これ
                         だけ
                             です
   @Immutable                  よ!こ
                                      れだ
   class Person {                            け
       String firstName, lastName
   }

   x = new Person("Junji","Uehara")
   assert x.lastName == "Uehara"
   x.firstName = "abc"
   //==>
   groovy.lang.ReadOnlyPropertyException:
   Cannot set readonly property: firstName
   for class: Person
                49
2011年12月1日木曜日
強力なゴースト執筆陣
      @Immutable, @ListenerList, @ToString,
      @Equals, @EqualsAndHashcode,
      @AutoClone, @TimedInterrupt, @Lazy,
      @Mixin, @Singleton,
      @InheritConsructors,@WithReadLock,
      @WithWriteLock, @Log, @Delegate,
      @Lazy, @Singleton, @Bindable, ほか

      上記は「AST変換」を起動するアノテーション。


                50
2011年12月1日木曜日
最新動向  http://www.flickr.com/photos/realbreadcampaign/5534567421/
               51
2011年12月1日木曜日
Groovy 2.0へ
      安定版最新
         Groovy 1.8.4
      開発版最新
         Groovy 2.0.0-beta1 (=1.9-beta5相当)
            2012年初頭に正式版登場予定




                52
2011年12月1日木曜日
Groovyの新機能
            Java 7のProject Coin対応(2.0以降)
                二進リテラル
                リテラル中の下線
                マルチキャッチ
                InvokeDynamic対応(2.0以降)
                try-with-resourceなどはいまのところ未
            Groovy自体のモジュール化(1.8以降)
            静的型チェック(2.0.0 beta1で実験的実装)
            静的コンパイル(2.0以降)
                53
2011年12月1日木曜日
まとめ
                     http://www.flickr.com/photos/limonada/214375219/
                54
2011年12月1日木曜日
本日伝えたかったこと
          Groovyとは何か?
          Groovyは簡単なのか?
             Java開発者にとってYES!
             通常のJava開発と地続き
          Groovyは便利なのか?
             Java開発者にとってYES! 簡潔さと高機能さが
             今、手はいる。
          JavaプログラマにとってGroovyとは何か?
             Java x Groovyを実現するもの!

             55
2011年12月1日木曜日
本日伝えたかったこと
          Groovyとは何か?
          Groovyは簡単なのか?
             Java開発者にとってYES!
             通常のJava開発と地続き
          Groovyは便利なのか?
             Java開発者にとってYES! 簡潔さと高機能さが
             今、手はいる。
          JavaプログラマにとってGroovyとは何か?
             Java x Groovyを実現するもの!

             55
2011年12月1日木曜日
本日伝えたかったこと
          Groovyとは何か?
          Groovyは簡単なのか?
             Java開発者にとってYES!
             通常のJava開発と地続き
          Groovyは便利なのか?
             Java開発者にとってYES! 簡潔さと高機能さが
             今、手はいる。
          JavaプログラマにとってGroovyとは何か?
             Java x Groovyを実現するもの!

             55
2011年12月1日木曜日
本日伝えたかったこと
          Groovyとは何か?
          Groovyは簡単なのか?
             Java開発者にとってYES!
             通常のJava開発と地続き
          Groovyは便利なのか?
             Java開発者にとってYES! 簡潔さと高機能さが
             今、手はいる。
          JavaプログラマにとってGroovyとは何か?
             Java x Groovyを実現するもの!

             55
2011年12月1日木曜日
Java x Groovy
      GroovyはJavaの弱点を補う
      組み合わせて使うことで相乗効果を発揮
      Java開発者にとって修得・導入がごく容易



                Java x Groovy
                     (DIxAOP的な意味で)

    Groovy利用をJava開発と組み合わせることで、
    Java開発を加速する!

                56
2011年12月1日木曜日
ご静聴ありがとうご
     ざいました

                57
2011年12月1日木曜日
コミュニティもよろしく
         活発な国内コミュニティ
            電子雑誌 G*マガジン
            月1定例勉強会 G*ワークショップ
            年1恒例合宿
            その他企画




                58
2011年12月1日木曜日

More Related Content

What's hot

Java SE 7 InvokeDynamic in JRuby
Java SE 7 InvokeDynamic in JRubyJava SE 7 InvokeDynamic in JRuby
Java SE 7 InvokeDynamic in JRubyHiroshi Nakamura
 
サーバーサイドでの非同期処理で色々やったよ
サーバーサイドでの非同期処理で色々やったよサーバーサイドでの非同期処理で色々やったよ
サーバーサイドでの非同期処理で色々やったよkoji lin
 
C# 式木 (Expression Tree) ~ LINQをより深く理解するために ~
C# 式木 (Expression Tree) ~ LINQをより深く理解するために ~C# 式木 (Expression Tree) ~ LINQをより深く理解するために ~
C# 式木 (Expression Tree) ~ LINQをより深く理解するために ~Fujio Kojima
 
Java Puzzlers JJUG CCC 2016
Java Puzzlers JJUG CCC 2016Java Puzzlers JJUG CCC 2016
Java Puzzlers JJUG CCC 2016Yoshio Terada
 
Xtend30分クッキング
Xtend30分クッキングXtend30分クッキング
Xtend30分クッキングShinichi Kozake
 
Xtend30分クッキング やきに駆動
Xtend30分クッキング   やきに駆動Xtend30分クッキング   やきに駆動
Xtend30分クッキング やきに駆動Shinichi Kozake
 
Visual C++で使えるC++11
Visual C++で使えるC++11Visual C++で使えるC++11
Visual C++で使えるC++11nekko1119
 
unique_ptrにポインタ以外のものを持たせるとき
unique_ptrにポインタ以外のものを持たせるときunique_ptrにポインタ以外のものを持たせるとき
unique_ptrにポインタ以外のものを持たせるときShintarou Okada
 
TensorFlow XLA 「XLAとは、から、最近の利用事例について」
TensorFlow XLA 「XLAとは、から、最近の利用事例について」TensorFlow XLA 「XLAとは、から、最近の利用事例について」
TensorFlow XLA 「XLAとは、から、最近の利用事例について」Mr. Vengineer
 
Twitter sphere of #twitter4j #twtr_hack
Twitter sphere of #twitter4j #twtr_hackTwitter sphere of #twitter4j #twtr_hack
Twitter sphere of #twitter4j #twtr_hackkimukou_26 Kimukou
 
組み込みでこそC++を使う10の理由
組み込みでこそC++を使う10の理由組み込みでこそC++を使う10の理由
組み込みでこそC++を使う10の理由kikairoya
 
新しい並列for構文のご提案
新しい並列for構文のご提案新しい並列for構文のご提案
新しい並列for構文のご提案yohhoy
 
Java puzzlers 2013 at JavaFesta Japan
Java puzzlers 2013 at JavaFesta JapanJava puzzlers 2013 at JavaFesta Japan
Java puzzlers 2013 at JavaFesta JapanYoshio Terada
 
Tensorflow dynamically loadable XLA plugin ソースコード解析
Tensorflow  dynamically loadable XLA plugin ソースコード解析Tensorflow  dynamically loadable XLA plugin ソースコード解析
Tensorflow dynamically loadable XLA plugin ソースコード解析Mr. Vengineer
 
クロージャデザインパターン
クロージャデザインパターンクロージャデザインパターン
クロージャデザインパターンMoriharu Ohzu
 
Scalaで型クラス入門
Scalaで型クラス入門Scalaで型クラス入門
Scalaで型クラス入門Makoto Fukuhara
 

What's hot (20)

Java SE 7 InvokeDynamic in JRuby
Java SE 7 InvokeDynamic in JRubyJava SE 7 InvokeDynamic in JRuby
Java SE 7 InvokeDynamic in JRuby
 
サーバーサイドでの非同期処理で色々やったよ
サーバーサイドでの非同期処理で色々やったよサーバーサイドでの非同期処理で色々やったよ
サーバーサイドでの非同期処理で色々やったよ
 
C# 式木 (Expression Tree) ~ LINQをより深く理解するために ~
C# 式木 (Expression Tree) ~ LINQをより深く理解するために ~C# 式木 (Expression Tree) ~ LINQをより深く理解するために ~
C# 式木 (Expression Tree) ~ LINQをより深く理解するために ~
 
Java Puzzlers JJUG CCC 2016
Java Puzzlers JJUG CCC 2016Java Puzzlers JJUG CCC 2016
Java Puzzlers JJUG CCC 2016
 
Xtend30分クッキング
Xtend30分クッキングXtend30分クッキング
Xtend30分クッキング
 
Xtend30分クッキング やきに駆動
Xtend30分クッキング   やきに駆動Xtend30分クッキング   やきに駆動
Xtend30分クッキング やきに駆動
 
Visual C++で使えるC++11
Visual C++で使えるC++11Visual C++で使えるC++11
Visual C++で使えるC++11
 
unique_ptrにポインタ以外のものを持たせるとき
unique_ptrにポインタ以外のものを持たせるときunique_ptrにポインタ以外のものを持たせるとき
unique_ptrにポインタ以外のものを持たせるとき
 
TensorFlow XLA 「XLAとは、から、最近の利用事例について」
TensorFlow XLA 「XLAとは、から、最近の利用事例について」TensorFlow XLA 「XLAとは、から、最近の利用事例について」
TensorFlow XLA 「XLAとは、から、最近の利用事例について」
 
C++14 Overview
C++14 OverviewC++14 Overview
C++14 Overview
 
Twitter sphere of #twitter4j #twtr_hack
Twitter sphere of #twitter4j #twtr_hackTwitter sphere of #twitter4j #twtr_hack
Twitter sphere of #twitter4j #twtr_hack
 
More C++11
More C++11More C++11
More C++11
 
組み込みでこそC++を使う10の理由
組み込みでこそC++を使う10の理由組み込みでこそC++を使う10の理由
組み込みでこそC++を使う10の理由
 
新しい並列for構文のご提案
新しい並列for構文のご提案新しい並列for構文のご提案
新しい並列for構文のご提案
 
Java puzzlers 2013 at JavaFesta Japan
Java puzzlers 2013 at JavaFesta JapanJava puzzlers 2013 at JavaFesta Japan
Java puzzlers 2013 at JavaFesta Japan
 
Tensorflow dynamically loadable XLA plugin ソースコード解析
Tensorflow  dynamically loadable XLA plugin ソースコード解析Tensorflow  dynamically loadable XLA plugin ソースコード解析
Tensorflow dynamically loadable XLA plugin ソースコード解析
 
クロージャデザインパターン
クロージャデザインパターンクロージャデザインパターン
クロージャデザインパターン
 
Project lambda
Project lambdaProject lambda
Project lambda
 
Go guide for Java programmer
Go guide for Java programmerGo guide for Java programmer
Go guide for Java programmer
 
Scalaで型クラス入門
Scalaで型クラス入門Scalaで型クラス入門
Scalaで型クラス入門
 

Viewers also liked

Seasar Conference2008 Grails(Final)
Seasar Conference2008 Grails(Final)Seasar Conference2008 Grails(Final)
Seasar Conference2008 Grails(Final)Uehara Junji
 
New features of Groovy 2.0 and 2.1
New features of Groovy 2.0 and 2.1New features of Groovy 2.0 and 2.1
New features of Groovy 2.0 and 2.1Uehara Junji
 
Java One 2012 Tokyo JVM Lang. BOF(Groovy)
Java One 2012 Tokyo JVM Lang. BOF(Groovy)Java One 2012 Tokyo JVM Lang. BOF(Groovy)
Java One 2012 Tokyo JVM Lang. BOF(Groovy)Uehara Junji
 
Jo si se i tu també sessio torrent
Jo si se i tu també sessio torrentJo si se i tu també sessio torrent
Jo si se i tu també sessio torrentAdrian Benet
 
Easy Going Groovy 2nd season on DevLOVE
Easy Going Groovy 2nd season on DevLOVEEasy Going Groovy 2nd season on DevLOVE
Easy Going Groovy 2nd season on DevLOVEUehara Junji
 
Let's go Developer 2011 sendai Let's go Java Developer (Programming Language ...
Let's go Developer 2011 sendai Let's go Java Developer (Programming Language ...Let's go Developer 2011 sendai Let's go Java Developer (Programming Language ...
Let's go Developer 2011 sendai Let's go Java Developer (Programming Language ...Uehara Junji
 

Viewers also liked (7)

Dsl&Builder
Dsl&BuilderDsl&Builder
Dsl&Builder
 
Seasar Conference2008 Grails(Final)
Seasar Conference2008 Grails(Final)Seasar Conference2008 Grails(Final)
Seasar Conference2008 Grails(Final)
 
New features of Groovy 2.0 and 2.1
New features of Groovy 2.0 and 2.1New features of Groovy 2.0 and 2.1
New features of Groovy 2.0 and 2.1
 
Java One 2012 Tokyo JVM Lang. BOF(Groovy)
Java One 2012 Tokyo JVM Lang. BOF(Groovy)Java One 2012 Tokyo JVM Lang. BOF(Groovy)
Java One 2012 Tokyo JVM Lang. BOF(Groovy)
 
Jo si se i tu també sessio torrent
Jo si se i tu també sessio torrentJo si se i tu també sessio torrent
Jo si se i tu també sessio torrent
 
Easy Going Groovy 2nd season on DevLOVE
Easy Going Groovy 2nd season on DevLOVEEasy Going Groovy 2nd season on DevLOVE
Easy Going Groovy 2nd season on DevLOVE
 
Let's go Developer 2011 sendai Let's go Java Developer (Programming Language ...
Let's go Developer 2011 sendai Let's go Java Developer (Programming Language ...Let's go Developer 2011 sendai Let's go Java Developer (Programming Language ...
Let's go Developer 2011 sendai Let's go Java Developer (Programming Language ...
 

Similar to Java x Groovy: improve your java development life

第三回ありえる社内勉強会 「いわががのLombok」
第三回ありえる社内勉強会 「いわががのLombok」第三回ありえる社内勉強会 「いわががのLombok」
第三回ありえる社内勉強会 「いわががのLombok」yoshiaki iwanaga
 
G*workshop sendai 20100424(v2)
G*workshop sendai 20100424(v2)G*workshop sendai 20100424(v2)
G*workshop sendai 20100424(v2)Nobuhiro Sue
 
速くなければスマフォじゃない - インターンバージョン-
速くなければスマフォじゃない - インターンバージョン-速くなければスマフォじゃない - インターンバージョン-
速くなければスマフォじゃない - インターンバージョン-Kazunari Hara
 
クラウド時代の並列分散処理技術
クラウド時代の並列分散処理技術クラウド時代の並列分散処理技術
クラウド時代の並列分散処理技術Koichi Fujikawa
 
Cloud computing competition by Hapyrus
Cloud computing competition by HapyrusCloud computing competition by Hapyrus
Cloud computing competition by HapyrusKoichi Fujikawa
 
from old java to java8 - KanJava Edition
from old java to java8 - KanJava Editionfrom old java to java8 - KanJava Edition
from old java to java8 - KanJava Edition心 谷本
 
夏だからJava再入門
夏だからJava再入門夏だからJava再入門
夏だからJava再入門Katsumi Honda
 
Lisp Tutorial for Pythonista : Day 3
Lisp Tutorial for Pythonista : Day 3Lisp Tutorial for Pythonista : Day 3
Lisp Tutorial for Pythonista : Day 3Ransui Iso
 
初心者講習会資料(Osaka.R#7)
初心者講習会資料(Osaka.R#7)初心者講習会資料(Osaka.R#7)
初心者講習会資料(Osaka.R#7)Masahiro Hayashi
 
JavaからScala、そしてClojureへ: 実務で活きる関数型プログラミング
JavaからScala、そしてClojureへ: 実務で活きる関数型プログラミングJavaからScala、そしてClojureへ: 実務で活きる関数型プログラミング
JavaからScala、そしてClojureへ: 実務で活きる関数型プログラミングKent Ohashi
 
JDK 10 へようこそ
JDK 10 へようこそJDK 10 へようこそ
JDK 10 へようこそDavid Buck
 
Java8から17へ
Java8から17へJava8から17へ
Java8から17へonozaty
 
Lisp tutorial for Pythonista : Day 2
Lisp tutorial for Pythonista : Day 2Lisp tutorial for Pythonista : Day 2
Lisp tutorial for Pythonista : Day 2Ransui Iso
 
LastaFluteでKotlinをはじめよう
LastaFluteでKotlinをはじめようLastaFluteでKotlinをはじめよう
LastaFluteでKotlinをはじめようShinsuke Sugaya
 
明日から使える Java SE 7
明日から使える Java SE 7明日から使える Java SE 7
明日から使える Java SE 7Yuichi Sakuraba
 

Similar to Java x Groovy: improve your java development life (20)

第三回ありえる社内勉強会 「いわががのLombok」
第三回ありえる社内勉強会 「いわががのLombok」第三回ありえる社内勉強会 「いわががのLombok」
第三回ありえる社内勉強会 「いわががのLombok」
 
Scala on Hadoop
Scala on HadoopScala on Hadoop
Scala on Hadoop
 
Rakuten tech conf
Rakuten tech confRakuten tech conf
Rakuten tech conf
 
G*workshop sendai 20100424(v2)
G*workshop sendai 20100424(v2)G*workshop sendai 20100424(v2)
G*workshop sendai 20100424(v2)
 
速くなければスマフォじゃない - インターンバージョン-
速くなければスマフォじゃない - インターンバージョン-速くなければスマフォじゃない - インターンバージョン-
速くなければスマフォじゃない - インターンバージョン-
 
ATN No.2 Scala事始め
ATN No.2 Scala事始めATN No.2 Scala事始め
ATN No.2 Scala事始め
 
クラウド時代の並列分散処理技術
クラウド時代の並列分散処理技術クラウド時代の並列分散処理技術
クラウド時代の並列分散処理技術
 
Cloud computing competition by Hapyrus
Cloud computing competition by HapyrusCloud computing competition by Hapyrus
Cloud computing competition by Hapyrus
 
from old java to java8 - KanJava Edition
from old java to java8 - KanJava Editionfrom old java to java8 - KanJava Edition
from old java to java8 - KanJava Edition
 
夏だからJava再入門
夏だからJava再入門夏だからJava再入門
夏だからJava再入門
 
Lisp Tutorial for Pythonista : Day 3
Lisp Tutorial for Pythonista : Day 3Lisp Tutorial for Pythonista : Day 3
Lisp Tutorial for Pythonista : Day 3
 
Introduction of Python
Introduction of PythonIntroduction of Python
Introduction of Python
 
初心者講習会資料(Osaka.R#7)
初心者講習会資料(Osaka.R#7)初心者講習会資料(Osaka.R#7)
初心者講習会資料(Osaka.R#7)
 
JavaからScala、そしてClojureへ: 実務で活きる関数型プログラミング
JavaからScala、そしてClojureへ: 実務で活きる関数型プログラミングJavaからScala、そしてClojureへ: 実務で活きる関数型プログラミング
JavaからScala、そしてClojureへ: 実務で活きる関数型プログラミング
 
Aizu lt tokyo_luxion
Aizu lt tokyo_luxionAizu lt tokyo_luxion
Aizu lt tokyo_luxion
 
JDK 10 へようこそ
JDK 10 へようこそJDK 10 へようこそ
JDK 10 へようこそ
 
Java8から17へ
Java8から17へJava8から17へ
Java8から17へ
 
Lisp tutorial for Pythonista : Day 2
Lisp tutorial for Pythonista : Day 2Lisp tutorial for Pythonista : Day 2
Lisp tutorial for Pythonista : Day 2
 
LastaFluteでKotlinをはじめよう
LastaFluteでKotlinをはじめようLastaFluteでKotlinをはじめよう
LastaFluteでKotlinをはじめよう
 
明日から使える Java SE 7
明日から使える Java SE 7明日から使える Java SE 7
明日から使える Java SE 7
 

More from Uehara Junji

Use JWT access-token on Grails REST API
Use JWT access-token on Grails REST APIUse JWT access-token on Grails REST API
Use JWT access-token on Grails REST APIUehara Junji
 
Groovy Bootcamp 2015 by JGGUG
Groovy Bootcamp 2015 by JGGUGGroovy Bootcamp 2015 by JGGUG
Groovy Bootcamp 2015 by JGGUGUehara Junji
 
Groovy Shell Scripting 2015
Groovy Shell Scripting 2015Groovy Shell Scripting 2015
Groovy Shell Scripting 2015Uehara Junji
 
Markup Template Engine introduced Groovy 2.3
Markup Template Engine introduced Groovy 2.3Markup Template Engine introduced Groovy 2.3
Markup Template Engine introduced Groovy 2.3Uehara Junji
 
Introduce Groovy 2.3 trait
Introduce Groovy 2.3 trait Introduce Groovy 2.3 trait
Introduce Groovy 2.3 trait Uehara Junji
 
Indy(Invokedynamic) and Bytecode DSL and Brainf*ck
Indy(Invokedynamic) and Bytecode DSL and Brainf*ckIndy(Invokedynamic) and Bytecode DSL and Brainf*ck
Indy(Invokedynamic) and Bytecode DSL and Brainf*ckUehara Junji
 
enterprise grails challenge, 2013 Summer
enterprise grails challenge, 2013 Summerenterprise grails challenge, 2013 Summer
enterprise grails challenge, 2013 SummerUehara Junji
 
Groovy kisobenkyoukai20130309
Groovy kisobenkyoukai20130309Groovy kisobenkyoukai20130309
Groovy kisobenkyoukai20130309Uehara Junji
 
Read Groovy Compile process(Groovy Benkyoukai 2013)
Read Groovy Compile process(Groovy Benkyoukai 2013)Read Groovy Compile process(Groovy Benkyoukai 2013)
Read Groovy Compile process(Groovy Benkyoukai 2013)Uehara Junji
 
groovy 2.1.0 20130118
groovy 2.1.0 20130118groovy 2.1.0 20130118
groovy 2.1.0 20130118Uehara Junji
 
New feature of Groovy2.0 G*Workshop
New feature of Groovy2.0 G*WorkshopNew feature of Groovy2.0 G*Workshop
New feature of Groovy2.0 G*WorkshopUehara Junji
 
G* Workshop in fukuoka 20120901
G* Workshop in fukuoka 20120901G* Workshop in fukuoka 20120901
G* Workshop in fukuoka 20120901Uehara Junji
 
JJUG CCC 2012 Real World Groovy/Grails
JJUG CCC 2012 Real World Groovy/GrailsJJUG CCC 2012 Real World Groovy/Grails
JJUG CCC 2012 Real World Groovy/GrailsUehara Junji
 
Groovy 1.8の新機能について
Groovy 1.8の新機能についてGroovy 1.8の新機能について
Groovy 1.8の新機能についてUehara Junji
 
Jggug ws 15th LT 20110224
Jggug ws 15th LT 20110224Jggug ws 15th LT 20110224
Jggug ws 15th LT 20110224Uehara Junji
 
Easy Going Groovy(Groovyを気軽に使いこなそう)
Easy Going Groovy(Groovyを気軽に使いこなそう)Easy Going Groovy(Groovyを気軽に使いこなそう)
Easy Going Groovy(Groovyを気軽に使いこなそう)Uehara Junji
 
GroovyServ concept, how to use and outline.
GroovyServ concept, how to use and outline.GroovyServ concept, how to use and outline.
GroovyServ concept, how to use and outline.Uehara Junji
 
Groovy, Transforming Language
Groovy, Transforming LanguageGroovy, Transforming Language
Groovy, Transforming LanguageUehara Junji
 
Jggug Nagoya 20090925 Groovy
Jggug Nagoya 20090925 GroovyJggug Nagoya 20090925 Groovy
Jggug Nagoya 20090925 GroovyUehara Junji
 

More from Uehara Junji (20)

Use JWT access-token on Grails REST API
Use JWT access-token on Grails REST APIUse JWT access-token on Grails REST API
Use JWT access-token on Grails REST API
 
Groovy Bootcamp 2015 by JGGUG
Groovy Bootcamp 2015 by JGGUGGroovy Bootcamp 2015 by JGGUG
Groovy Bootcamp 2015 by JGGUG
 
Groovy Shell Scripting 2015
Groovy Shell Scripting 2015Groovy Shell Scripting 2015
Groovy Shell Scripting 2015
 
Markup Template Engine introduced Groovy 2.3
Markup Template Engine introduced Groovy 2.3Markup Template Engine introduced Groovy 2.3
Markup Template Engine introduced Groovy 2.3
 
Introduce Groovy 2.3 trait
Introduce Groovy 2.3 trait Introduce Groovy 2.3 trait
Introduce Groovy 2.3 trait
 
Indy(Invokedynamic) and Bytecode DSL and Brainf*ck
Indy(Invokedynamic) and Bytecode DSL and Brainf*ckIndy(Invokedynamic) and Bytecode DSL and Brainf*ck
Indy(Invokedynamic) and Bytecode DSL and Brainf*ck
 
enterprise grails challenge, 2013 Summer
enterprise grails challenge, 2013 Summerenterprise grails challenge, 2013 Summer
enterprise grails challenge, 2013 Summer
 
Groovy kisobenkyoukai20130309
Groovy kisobenkyoukai20130309Groovy kisobenkyoukai20130309
Groovy kisobenkyoukai20130309
 
Read Groovy Compile process(Groovy Benkyoukai 2013)
Read Groovy Compile process(Groovy Benkyoukai 2013)Read Groovy Compile process(Groovy Benkyoukai 2013)
Read Groovy Compile process(Groovy Benkyoukai 2013)
 
groovy 2.1.0 20130118
groovy 2.1.0 20130118groovy 2.1.0 20130118
groovy 2.1.0 20130118
 
New feature of Groovy2.0 G*Workshop
New feature of Groovy2.0 G*WorkshopNew feature of Groovy2.0 G*Workshop
New feature of Groovy2.0 G*Workshop
 
G* Workshop in fukuoka 20120901
G* Workshop in fukuoka 20120901G* Workshop in fukuoka 20120901
G* Workshop in fukuoka 20120901
 
JJUG CCC 2012 Real World Groovy/Grails
JJUG CCC 2012 Real World Groovy/GrailsJJUG CCC 2012 Real World Groovy/Grails
JJUG CCC 2012 Real World Groovy/Grails
 
Groovy 1.8の新機能について
Groovy 1.8の新機能についてGroovy 1.8の新機能について
Groovy 1.8の新機能について
 
Jggug ws 15th LT 20110224
Jggug ws 15th LT 20110224Jggug ws 15th LT 20110224
Jggug ws 15th LT 20110224
 
Easy Going Groovy(Groovyを気軽に使いこなそう)
Easy Going Groovy(Groovyを気軽に使いこなそう)Easy Going Groovy(Groovyを気軽に使いこなそう)
Easy Going Groovy(Groovyを気軽に使いこなそう)
 
GroovyServ concept, how to use and outline.
GroovyServ concept, how to use and outline.GroovyServ concept, how to use and outline.
GroovyServ concept, how to use and outline.
 
Clojure
ClojureClojure
Clojure
 
Groovy, Transforming Language
Groovy, Transforming LanguageGroovy, Transforming Language
Groovy, Transforming Language
 
Jggug Nagoya 20090925 Groovy
Jggug Nagoya 20090925 GroovyJggug Nagoya 20090925 Groovy
Jggug Nagoya 20090925 Groovy
 

Recently uploaded

5/22 第23回 Customer系エンジニア座談会のスライド 公開用 西口瑛一
5/22 第23回 Customer系エンジニア座談会のスライド 公開用 西口瑛一5/22 第23回 Customer系エンジニア座談会のスライド 公開用 西口瑛一
5/22 第23回 Customer系エンジニア座談会のスライド 公開用 西口瑛一瑛一 西口
 
2024年5月25日Serverless Meetup大阪 アプリケーションをどこで動かすべきなのか.pptx
2024年5月25日Serverless Meetup大阪 アプリケーションをどこで動かすべきなのか.pptx2024年5月25日Serverless Meetup大阪 アプリケーションをどこで動かすべきなのか.pptx
2024年5月25日Serverless Meetup大阪 アプリケーションをどこで動かすべきなのか.pptxssuserbefd24
 
研究紹介スライド: オフライン強化学習に基づくロボティックスワームの制御器の設計
研究紹介スライド: オフライン強化学習に基づくロボティックスワームの制御器の設計研究紹介スライド: オフライン強化学習に基づくロボティックスワームの制御器の設計
研究紹介スライド: オフライン強化学習に基づくロボティックスワームの制御器の設計atsushi061452
 
情報を表現するときのポイント
情報を表現するときのポイント情報を表現するときのポイント
情報を表現するときのポイントonozaty
 
ロボットマニピュレーションの作業・動作計画 / rosjp_planning_for_robotic_manipulation_20240521
ロボットマニピュレーションの作業・動作計画 / rosjp_planning_for_robotic_manipulation_20240521ロボットマニピュレーションの作業・動作計画 / rosjp_planning_for_robotic_manipulation_20240521
ロボットマニピュレーションの作業・動作計画 / rosjp_planning_for_robotic_manipulation_20240521Satoshi Makita
 
部内勉強会(IT用語ざっくり学習) 実施日:2024年5月17日(金) 対象者:営業部社員
部内勉強会(IT用語ざっくり学習) 実施日:2024年5月17日(金) 対象者:営業部社員部内勉強会(IT用語ざっくり学習) 実施日:2024年5月17日(金) 対象者:営業部社員
部内勉強会(IT用語ざっくり学習) 実施日:2024年5月17日(金) 対象者:営業部社員Sadaomi Nishi
 
クラウド時代におけるSREとUPWARDの取組ーUPWARD株式会社 CTO門畑
クラウド時代におけるSREとUPWARDの取組ーUPWARD株式会社 CTO門畑クラウド時代におけるSREとUPWARDの取組ーUPWARD株式会社 CTO門畑
クラウド時代におけるSREとUPWARDの取組ーUPWARD株式会社 CTO門畑Akihiro Kadohata
 
論文紹介:Deep Occlusion-Aware Instance Segmentation With Overlapping BiLayers
論文紹介:Deep Occlusion-Aware Instance Segmentation With Overlapping BiLayers論文紹介:Deep Occlusion-Aware Instance Segmentation With Overlapping BiLayers
論文紹介:Deep Occlusion-Aware Instance Segmentation With Overlapping BiLayersToru Tamaki
 
Amazon Cognitoで実装するパスキー (Security-JAWS【第33回】 勉強会)
Amazon Cognitoで実装するパスキー (Security-JAWS【第33回】 勉強会)Amazon Cognitoで実装するパスキー (Security-JAWS【第33回】 勉強会)
Amazon Cognitoで実装するパスキー (Security-JAWS【第33回】 勉強会)keikoitakurag
 
論文紹介:ViTPose: Simple Vision Transformer Baselines for Human Pose Estimation
論文紹介:ViTPose: Simple Vision Transformer Baselines for Human Pose Estimation論文紹介:ViTPose: Simple Vision Transformer Baselines for Human Pose Estimation
論文紹介:ViTPose: Simple Vision Transformer Baselines for Human Pose EstimationToru Tamaki
 
Intranet Development v1.0 (TSG LIVE! 12 LT )
Intranet Development v1.0 (TSG LIVE! 12 LT )Intranet Development v1.0 (TSG LIVE! 12 LT )
Intranet Development v1.0 (TSG LIVE! 12 LT )iwashiira2ctf
 
20240523_IoTLT_vol111_kitazaki_v1___.pdf
20240523_IoTLT_vol111_kitazaki_v1___.pdf20240523_IoTLT_vol111_kitazaki_v1___.pdf
20240523_IoTLT_vol111_kitazaki_v1___.pdfAyachika Kitazaki
 

Recently uploaded (12)

5/22 第23回 Customer系エンジニア座談会のスライド 公開用 西口瑛一
5/22 第23回 Customer系エンジニア座談会のスライド 公開用 西口瑛一5/22 第23回 Customer系エンジニア座談会のスライド 公開用 西口瑛一
5/22 第23回 Customer系エンジニア座談会のスライド 公開用 西口瑛一
 
2024年5月25日Serverless Meetup大阪 アプリケーションをどこで動かすべきなのか.pptx
2024年5月25日Serverless Meetup大阪 アプリケーションをどこで動かすべきなのか.pptx2024年5月25日Serverless Meetup大阪 アプリケーションをどこで動かすべきなのか.pptx
2024年5月25日Serverless Meetup大阪 アプリケーションをどこで動かすべきなのか.pptx
 
研究紹介スライド: オフライン強化学習に基づくロボティックスワームの制御器の設計
研究紹介スライド: オフライン強化学習に基づくロボティックスワームの制御器の設計研究紹介スライド: オフライン強化学習に基づくロボティックスワームの制御器の設計
研究紹介スライド: オフライン強化学習に基づくロボティックスワームの制御器の設計
 
情報を表現するときのポイント
情報を表現するときのポイント情報を表現するときのポイント
情報を表現するときのポイント
 
ロボットマニピュレーションの作業・動作計画 / rosjp_planning_for_robotic_manipulation_20240521
ロボットマニピュレーションの作業・動作計画 / rosjp_planning_for_robotic_manipulation_20240521ロボットマニピュレーションの作業・動作計画 / rosjp_planning_for_robotic_manipulation_20240521
ロボットマニピュレーションの作業・動作計画 / rosjp_planning_for_robotic_manipulation_20240521
 
部内勉強会(IT用語ざっくり学習) 実施日:2024年5月17日(金) 対象者:営業部社員
部内勉強会(IT用語ざっくり学習) 実施日:2024年5月17日(金) 対象者:営業部社員部内勉強会(IT用語ざっくり学習) 実施日:2024年5月17日(金) 対象者:営業部社員
部内勉強会(IT用語ざっくり学習) 実施日:2024年5月17日(金) 対象者:営業部社員
 
クラウド時代におけるSREとUPWARDの取組ーUPWARD株式会社 CTO門畑
クラウド時代におけるSREとUPWARDの取組ーUPWARD株式会社 CTO門畑クラウド時代におけるSREとUPWARDの取組ーUPWARD株式会社 CTO門畑
クラウド時代におけるSREとUPWARDの取組ーUPWARD株式会社 CTO門畑
 
論文紹介:Deep Occlusion-Aware Instance Segmentation With Overlapping BiLayers
論文紹介:Deep Occlusion-Aware Instance Segmentation With Overlapping BiLayers論文紹介:Deep Occlusion-Aware Instance Segmentation With Overlapping BiLayers
論文紹介:Deep Occlusion-Aware Instance Segmentation With Overlapping BiLayers
 
Amazon Cognitoで実装するパスキー (Security-JAWS【第33回】 勉強会)
Amazon Cognitoで実装するパスキー (Security-JAWS【第33回】 勉強会)Amazon Cognitoで実装するパスキー (Security-JAWS【第33回】 勉強会)
Amazon Cognitoで実装するパスキー (Security-JAWS【第33回】 勉強会)
 
論文紹介:ViTPose: Simple Vision Transformer Baselines for Human Pose Estimation
論文紹介:ViTPose: Simple Vision Transformer Baselines for Human Pose Estimation論文紹介:ViTPose: Simple Vision Transformer Baselines for Human Pose Estimation
論文紹介:ViTPose: Simple Vision Transformer Baselines for Human Pose Estimation
 
Intranet Development v1.0 (TSG LIVE! 12 LT )
Intranet Development v1.0 (TSG LIVE! 12 LT )Intranet Development v1.0 (TSG LIVE! 12 LT )
Intranet Development v1.0 (TSG LIVE! 12 LT )
 
20240523_IoTLT_vol111_kitazaki_v1___.pdf
20240523_IoTLT_vol111_kitazaki_v1___.pdf20240523_IoTLT_vol111_kitazaki_v1___.pdf
20240523_IoTLT_vol111_kitazaki_v1___.pdf
 

Java x Groovy: improve your java development life

  • 1. Java x Groovyで 開発効率を高めよう Java Developer Workshop #2 日本Grails Groovyユーザ会 上原 潤二 2011.12.1 2011年12月1日木曜日
  • 2. 自己紹介 上原潤二(@uehaj) NTTソフトウェア株式会社 JGGUG運営委員 プログラミングGROOVY(技術評 論社)共著 Grails徹底入門(翔泳社)共著 ブログ「Grな日々」 GroovyServ, LispBuilder, GVM 開発者 2011年12月1日木曜日
  • 3. 本日皆さんに伝えたいこと Groovyとは何か? Groovyは簡単なのか? Groovyは便利なのか? JavaプログラマにとってGroovyと は何か? 3 2011年12月1日木曜日
  • 4. Groovyとは何か Java VM上で動作する動的なスクリプト言語 構文はJavaと 上位互換 ほぼ プラットフォームやセキュリティモデルは全く 同じ ユニークな特徴: Javaと共存・併用するための言語 主要開発者はVMWare社(Spring Source)に所属 4 2011年12月1日木曜日
  • 5. コード例1: HelloWorld.java __ public class HelloWorld {     public static void main(String[] args) {         System.out.println("Hello world");     } } 5 2011年12月1日木曜日
  • 6. コード例1: HelloWorld.groovy public class HelloWorld {     public static void main(String[] args) {         System.out.println("Hello world");     } } 6 2011年12月1日木曜日
  • 7. コード例1: HelloWorld.groovy public class HelloWorld {     public static void main(String[] args) {         System.out.println("Hello world");     } } Javaソースコードの拡張子.java を.groovyに変更するだけで groovyコードとして実行できる。 6 2011年12月1日木曜日
  • 8. コード例1: hello.groovy println "hello world" 7 2011年12月1日木曜日
  • 9. コード例1: hello.groovy println "hello world" Groovyでは以下が省略可能: main,クラス定義,文末のセミコロ ン, System.out,メソッド呼び出し の括弧,(例外宣言,静的型宣言, import宣言) etc.. 7 2011年12月1日木曜日
  • 10. Groovyは何で無いか 8 2011年12月1日木曜日
  • 11. Groovyは何で無いか 別言語をJVMにポーティングしたもので はない 8 2011年12月1日木曜日
  • 12. Groovyは何で無いか 別言語をJVMにポーティングしたもので はない ➡JVM以外では動かない 8 2011年12月1日木曜日
  • 13. Groovyは何で無いか 別言語をJVMにポーティングしたもので はない ➡JVM以外では動かない Next Javaではない 8 2011年12月1日木曜日
  • 14. Groovyは何で無いか 別言語をJVMにポーティングしたもので はない ➡JVM以外では動かない Next Javaではない ➡Javaを駆逐しない・パラダイムシフトしない 8 2011年12月1日木曜日
  • 15. Groovyは何で無いか 別言語をJVMにポーティングしたもので はない ➡JVM以外では動かない Next Javaではない ➡Javaを駆逐しない・パラダイムシフトしない 過去のOSSプロジェクトではない 8 2011年12月1日木曜日
  • 16. Groovyは何で無いか 別言語をJVMにポーティングしたもので はない ➡JVM以外では動かない Next Javaではない ➡Javaを駆逐しない・パラダイムシフトしない 過去のOSSプロジェクトではない ➡活発な開発と意欲的な機能拡張が続いている 8 2011年12月1日木曜日
  • 17. Groovyの特徴4つ Javaと親和性 簡潔 が高い 高機能 柔軟 9 2011年12月1日木曜日
  • 18. Groovyの特徴4つ Javaと親和性 簡潔 が高い 本日は上記2つの特徴を中心に紹介し ます。 高機能 柔軟 10 2011年12月1日木曜日
  • 19. 簡潔 11 http://www.flickr.com/photos/dan_culleton/4905300673/ 2011年12月1日木曜日
  • 20. 例:ワードカウント処理 テキストファイル中の単語の出現回数 を数える $ cat input.txt That that is is that that is not is not is that it it is $ java WordCount input.txt 1: That 2: not 2: it 4: that 6: is 12 2011年12月1日木曜日
  • 21. ワードカウント処理(Java) import java.util.Comparator;      Object[] list = entrySet.toArray(); import java.util.HashMap;     Comparator comp = new Comparator(){ import java.util.Map;        public int compare(Object o1, Object o2) import java.util.Set; { import java.util.List;          Map.Entry<String, Integer> e1 = import java.util.Arrays; (Map.Entry<String, Integer>) o1; import java.io.FileReader;          Map.Entry<String, Integer> e2 = import java.io.BufferedReader; (Map.Entry<String, Integer>) o2; import java.io.FileNotFoundException;         return e1.getValue() - e2.getValue(); import java.io.IOException;         }       }; public class WordCount {       Arrays.sort(list, comp);   @SuppressWarnings(value = "unchecked")       for (Object it: list) {   public static void main(String[] args) {         Map.Entry<String, Integer> entry =     FileReader fis = null; (Map.Entry<String, Integer>)it;     BufferedReader br = null;         System.out.println(entry.getValue() + ":     try { "+entry.getKey());       HashMap<String, Integer> map = new       } HashMap<String, Integer>();     }       fis = new FileReader(args[0]);     catch (IOException e) {       br = new BufferedReader(fis);       try {if (br != null) br.close();}catch       String line; (IOException ioe){}       while ((line = br.readLine()) != null) {       try {if (fis != null)fis.close();}catch         for (String it: line.split("W+")) { (IOException ioe){}          map.put(it, (map.get(it)==null) ? 1 :       e.printStackTrace(); (map.get(it) + 1));     }         }   }       }      Set<Map.Entry<String, Integer>> entrySet = } 48行 map.entrySet(); 13 2011年12月1日木曜日
  • 22. ワードカウント処理(Groovy) def words = new File(args[0]).text.split(/W+/) words.countBy{it}.entrySet().sort{it.value}.each { println "${it.value}: ${it.key}" } 4行 14 2011年12月1日木曜日
  • 23. .text def words = new File(args[0]).text.split(/W+/) words.countBy{it}.entrySet().sort{it.value}.each { .getText()の略記法 println "${it.value}: ${it.key}" } File#getText()はJava APIに 対して追加されたGDKメソッド ファイル内容の全体を1つの Stringとして返す 2011年12月1日木曜日
  • 24. GDKメソッド Java標準APIクラスにメソッドを追加 java.lang.Stringを例にとると、 Java標準APIは、65個メソッド GDKでは、91個のメソッド追加 asType(Class c) execute(List envp, getAt(Collection padLeft(Number replaceFirst(Pattern toInteger() bitwiseNegate() File dir) indices) numberOfChars) pattern, Closure toList() capitalize() expand() getChars() padRight(Number closure) toLong() center(Number expand(int tabStop) isAllWhitespace() numberOfChars, reverse() toSet() numberOfChars, expandLine(int isBigDecimal() String padding) size() toShort() String padding) tabStop) isBigInteger() padRight(Number split() toURI() center(Number find(String regex) isCase(Object numberOfChars) splitEachLine(String toURL() numberOfChars) find(Pattern pattern) switchValue) plus(Object value) regex, Closure tokenize(String contains(String text) find(String regex, isDouble() previous() closure) token) count(String text) Closure closure) isFloat() readLines() splitEachLine tokenize(Character decodeBase64() find(Pattern pattern, isInteger() replaceAll(Pattern (Pattern pattern, token) denormalize() Closure closure) isLong() pattern, String Closure closure) tokenize() eachLine(Closure findAll(String regex) isNumber() replacement) stripIndent() tr(String sourceSet, closure) findAll(Pattern leftShift(Object replaceAll(String stripIndent(int String eachLine(int pattern) value) regex, Closure numChars) replacementSet) firstLine, Closure findAll(String regex, matches(Pattern closure) stripMargin() unexpand() closure) Closure closure) pattern) replaceAll(Pattern stripMargin(String unexpand(int eachMatch(String findAll(Pattern minus(Object target) pattern, Closure marginChar) tabStop) regex, Closure pattern, Closure multiply(Number closure) stripMargin(char unexpandLine(int closure) closure) factor) replaceFirst(Pattern marginChar) tabStop) eachMatch(Pattern getAt(int index) next() pattern, String toBigDecimal() pattern, Closure getAt(IntRange normalize() replacement) toBigInteger() closure) range) padLeft(Number replaceFirst(String toBoolean() execute() getAt(EmptyRange numberOfChars, regex, Closure toCharacter() execute(String[] range) String padding) closure) toDouble() envp, File dir) getAt(Range range) toFloat() 16 2011年12月1日木曜日
  • 25. GDKメソッド Java標準APIクラスにメソッドを追加 java.lang.Stringを例にとると、 Java標準APIは、65個メソッド GDKでは、91個のメソッド追加 asType(Class c) execute(List envp, getAt(Collection padLeft(Number replaceFirst(Pattern toInteger() bitwiseNegate() File dir) indices) numberOfChars) pattern, Closure toList() capitalize() expand() getChars() padRight(Number closure) toLong() center(Number expand(int tabStop) isAllWhitespace() numberOfChars, reverse() toSet() “ls”.execute() numberOfChars, String padding) center(Number expandLine(int tabStop) find(String regex) isBigDecimal() isBigInteger() isCase(Object String padding) padRight(Number numberOfChars) size() split() splitEachLine(String toShort() toURI() toURL() " lsコマンドを実行(Processが返る) numberOfChars) find(Pattern pattern) switchValue) plus(Object value) regex, Closure tokenize(String contains(String text) find(String regex, isDouble() previous() closure) token) count(String text) Closure closure) isFloat() readLines() splitEachLine tokenize(Character decodeBase64() find(Pattern pattern, isInteger() replaceAll(Pattern (Pattern pattern, token) denormalize() Closure closure) isLong() pattern, String Closure closure) tokenize() eachLine(Closure findAll(String regex) isNumber() replacement) stripIndent() tr(String sourceSet, closure) findAll(Pattern leftShift(Object replaceAll(String stripIndent(int String eachLine(int pattern) value) regex, Closure numChars) replacementSet) firstLine, Closure findAll(String regex, matches(Pattern closure) stripMargin() unexpand() closure) Closure closure) pattern) replaceAll(Pattern stripMargin(String unexpand(int eachMatch(String findAll(Pattern minus(Object target) pattern, Closure marginChar) tabStop) regex, Closure pattern, Closure multiply(Number closure) stripMargin(char unexpandLine(int closure) closure) factor) replaceFirst(Pattern marginChar) tabStop) eachMatch(Pattern getAt(int index) next() pattern, String toBigDecimal() pattern, Closure getAt(IntRange normalize() replacement) toBigInteger() closure) range) padLeft(Number replaceFirst(String toBoolean() execute() getAt(EmptyRange numberOfChars, regex, Closure toCharacter() execute(String[] range) String padding) closure) toDouble() envp, File dir) getAt(Range range) toFloat() 16 2011年12月1日木曜日
  • 26. GDKメソッド Java標準APIクラスにメソッドを追加 java.lang.Stringを例にとると、 Java標準APIは、65個メソッド GDKでは、91個のメソッド追加 asType(Class c) execute(List envp, getAt(Collection padLeft(Number replaceFirst(Pattern toInteger() bitwiseNegate() File dir) indices) numberOfChars) pattern, Closure toList() capitalize() expand() getChars() padRight(Number closure) toLong() center(Number expand(int tabStop) isAllWhitespace() numberOfChars, reverse() toSet() “ls”.execute() numberOfChars, String padding) center(Number expandLine(int tabStop) find(String regex) isBigDecimal() isBigInteger() isCase(Object String padding) padRight(Number numberOfChars) size() split() splitEachLine(String toShort() toURI() toURL() " lsコマンドを実行(Processが返る) numberOfChars) find(Pattern pattern) switchValue) plus(Object value) regex, Closure tokenize(String contains(String text) find(String regex, isDouble() previous() closure) token) count(String text) Closure closure) isFloat() readLines() splitEachLine tokenize(Character decodeBase64() find(Pattern pattern, isInteger() replaceAll(Pattern (Pattern pattern, token) denormalize() Closure closure) isLong() pattern, String Closure closure) tokenize() eachLine(Closure findAll(String regex) isNumber() replacement) stripIndent() tr(String sourceSet, closure) findAll(Pattern leftShift(Object replaceAll(String stripIndent(int String eachLine(int pattern) value) regex, Closure numChars) replacementSet) firstLine, Closure findAll(String regex, matches(Pattern closure) stripMargin() unexpand() closure) Closure closure) pattern) replaceAll(Pattern stripMargin(String unexpand(int “あいうえお”.tr(“あ-ん”,”ア-ン”) eachMatch(String regex, Closure closure) findAll(Pattern pattern, Closure closure) minus(Object target) multiply(Number factor) pattern, Closure closure) replaceFirst(Pattern marginChar) stripMargin(char marginChar) tabStop) unexpandLine(int tabStop) eachMatch(Pattern getAt(int index) next() pattern, String toBigDecimal() " “アイウエオ” pattern, Closure getAt(IntRange normalize() replacement) toBigInteger() closure) range) padLeft(Number replaceFirst(String toBoolean() execute() getAt(EmptyRange numberOfChars, regex, Closure toCharacter() execute(String[] range) String padding) closure) toDouble() envp, File dir) getAt(Range range) toFloat() 16 2011年12月1日木曜日
  • 27. .split(/正規表現/) def words = new File(args[0]).text.split(/W+/) words.countBy{it}.entrySet().sort{it.value}.each { println "${it.value}: ${it.key}" } /∼/は文字列定数の記法。ただし 文字’’を特別扱いしない “W” == /W/ Java APIの String#split(String) 2011年12月1日木曜日
  • 28. .countBy{} def words = new File(args[0]).text.split(/W+/) words.countBy{it}.entrySet().sort{it.value}.each { println "${it.value}: ${it.key}" } countByはコレクション・イテレータに対 して追加されたGDKメソッド 分類基準に基づいて要素をグルーピングし た上でグループごとの要素数をカウントする 2011年12月1日木曜日
  • 29. .countBy{} リスト “ABC” “ABC” “DEF” “GHI” “ABC” “GHI” countBy{it} 分類基準をクロージャで与える マップ “ABC” : 3 “DEF” : 1 “GHI” : 2 コレクションやイテレータに対してcountByを適用する と、分類基準で分類されたグループをキー、そのグループの 要素数をバリューとするマップが得られる。(c.f. groupBy) 19 2011年12月1日木曜日
  • 30. .entrySet().sort{} def words = new File(args[0]).text.split(/W+/) words.countBy{it}.entrySet().sort{it.value}.each { println "${it.value}: ${it.key}" } entrySet()はJava API sortはクロージャで比較するソート(GDKメ ソッド) 2011年12月1日木曜日
  • 31. each, GString def words = new File(args[0]).text.split(/W+/) words.countBy{it}.entrySet().sort{it.value}.each { println "${it.value}: ${it.key}" } eachはそれぞれに対して処理(クロージャ) 文字列中の$変数名、${ブロック}はその値 に置換される(GString) 21 2011年12月1日木曜日
  • 32. 簡潔さをもたらしたもの 各種の省略 言語機能 高機能ライブラリ 22 2011年12月1日木曜日
  • 33. 短かさの意味 Javaに比してコード量は1/5∼1/3 短かければ良いわけではない 短くて分かりにくくなることもある 重要なのは「やりたい事(what)/コード量」 のSN比 23 2011年12月1日木曜日
  • 34. これは何でしょう?       Set<Map.Entry<String, Integer>> entrySet = import java.util.Comparator; map.entrySet(); import java.util.HashMap;       Object[] list = entrySet.toArray(); import java.util.Map;       Comparator comp = new Comparator(){ import java.util.Set;         public int compare(Object o1, Object o2) { import java.util.List;           Map.Entry<String, Integer> e1 = import java.util.Arrays; (Map.Entry<String, Integer>) o1; import java.io.FileReader;           Map.Entry<String, Integer> e2 = import java.io.BufferedReader; (Map.Entry<String, Integer>) o2; import java.io.FileNotFoundException;           return e1.getValue() - e2.getValue(); import java.io.IOException;         }       }; public class WordCount {       Arrays.sort(list, comp);   @SuppressWarnings(value = "unchecked")       for (Object it: list) {   public static void main(String[] args) {         Map.Entry<String, Integer> entry =     FileReader fis = null; (Map.Entry<String, Integer>)it;     BufferedReader br = null;         System.out.println(entry.getValue() + ":     try { ["+entry.getKey()+"]");       HashMap<String, Integer> map = new       } HashMap<String, Integer>();     }       fis = new FileReader(args[0]);     catch (IOException e) {       br = new BufferedReader(fis);       try {if (br != null) br.close();}catch       String line; (IOException ioe){}       while ((line = br.readLine()) != null) {       try {if (fis != null)fis.close();}catch         for (String it: line.split("s+")) { (IOException ioe){}           map.put(it, (map.get(it)==null) ? 1 :       e.printStackTrace(); (map.get(it) + 1));     }         }   }     } } 24 2011年12月1日木曜日
  • 35. これは何でしょう?       Set<Map.Entry<String, Integer>> entrySet = import java.util.Comparator; map.entrySet(); import java.util.HashMap;       Object[] list = entrySet.toArray(); import import 答:Java版ワードカウントから「処理 java.util.Map; java.util.Set;       Comparator comp = new Comparator(){         public int compare(Object o1, Object o2) { import java.util.List;           Map.Entry<String, Integer> e1 = の記述」を抜き出したもの。 import java.util.Arrays; (Map.Entry<String, Integer>) o1; import java.io.FileReader;           Map.Entry<String, Integer> e2 = import java.io.BufferedReader; (Map.Entry<String, Integer>) o2; import java.io.FileNotFoundException;           return e1.getValue() - e2.getValue(); import java.io.IOException;         }       }; public class WordCount {       Arrays.sort(list, comp);   @SuppressWarnings(value = "unchecked")       for (Object it: list) {   public static void main(String[] args) {         Map.Entry<String, Integer> entry =     FileReader fis = null; (Map.Entry<String, Integer>)it;     BufferedReader br = null;         System.out.println(entry.getValue() + ":     try { ["+entry.getKey()+"]");       HashMap<String, Integer> map = new       } HashMap<String, Integer>();     }       fis = new FileReader(args[0]);     catch (IOException e) {       br = new BufferedReader(fis);       try {if (br != null) br.close();}catch       String line; (IOException ioe){}       while ((line = br.readLine()) != null) {       try {if (fis != null)fis.close();}catch         for (String it: line.split("s+")) { (IOException ioe){}           map.put(it, (map.get(it)==null) ? 1 :       e.printStackTrace(); (map.get(it) + 1));     }         }   }     } } 24 2011年12月1日木曜日
  • 36. 短かさの効用 Groovyの記述レベルは人間の認知 レベルでの「やって欲しいこと」の 記述に近い ➡理解性向上 ➡リファクタリングの頻度減少 25 2011年12月1日木曜日
  • 37. Javaと親和性が高い 26 2011年12月1日木曜日
  • 38. Java親和性(1):文法 正しいJavaコードは、正しいGroovyコード (ほぼ上位互換) 以下を含めて アノテーション,enum, Generics Java7機能(一部未対応) 27 2011年12月1日木曜日
  • 39. Java親和性(2):API Java APIをそのままもしくは拡張して使う 例えばGroovy独自のコレクションクラス 群というものはない GDK(Groovy Development Kit) Java APIにメソッドを追加 28 2011年12月1日木曜日
  • 40. Java親和性(3):相互運用 Groovyコードは常にJavaクラスに変換された上 で実行される。(次項) Java VMから見てGroovyコードは普通のJava クラス ラッパークラスは無い スクリプト(mainメソッドやクラス定義がな いGroovyコード)も内部的にクラスが生成さ れて実行される 29 2011年12月1日木曜日
  • 41. Javaコードの実行 Javaソース javac .classファイル javaコマンド JVM 標準クラスローダ Javaクラス 30 2011年12月1日木曜日
  • 42. Groovyコードの実行 Javaソース Groovyコード javac .classファイル javaコマンド groovyコマンド JVM 標準クラスローダ Groovyクラスローダ (オンメモリ実行時コンパイラ) Javaクラス Javaクラス 31 2011年12月1日木曜日
  • 43. Groovyコードの実行 Javaソース Groovyコード javac groovyc .classファイル .classファイル javaコマンド groovyコマンド JVM 標準クラスローダ Groovyクラスローダ (オンメモリ実行時コンパイラ) Javaクラス Javaクラス Javaクラス 31 2011年12月1日木曜日
  • 44. Groovyコードの実行 Javaソース Groovyコード javac groovyc .classファイル .classファイル javaコマンド groovyコマンド JVM 標準クラスローダ Groovyクラスローダ (オンメモリ実行時コンパイラ) Javaクラス Javaクラス Javaクラス 31 呼び出し・継承自由 2011年12月1日木曜日
  • 45. Java開発への取り込み方 7つの利用パターンを元にして http://www.flickr.com/photos/holeymoon/1634408365/ 32 2011年12月1日木曜日
  • 46. Groovy「7つの利用パターン」 by Dierk König 万能接着剤(Super Glue): Javaのコンポーネントやフレームワークを Groovyを糊(glue)としてつなぐ やわらかな心臓部(Liquid Heart): 中核となるロジックだけをGroovy/ DSLで書けるようにする お化粧(Lipstick): Javaのライブラリを簡潔に利用できる層をもうけ る。 内視鏡手術(Keyhole Surgery): 実行時にGroovyスクリプトを接続で きる小さな口を用意しておく 無制限の開放(Unlimited Openness): 全部Groovyで書く 小人さんスクリプト(House-elf Script): 周辺の各種支援スクリプト をGroovyで書く ゴーストライター(Ghost Writer): 裏でコード生成 33 2011年12月1日木曜日
  • 47. Groovyの利用パターン(1 of 7) 万能接着剤(Super Glue): Javaのコンポーネントやフレー ムワークをGroovyが糊(glue)としてつなぐ Groovy Java Java Java JavaAPI Java VM 34 2011年12月1日木曜日
  • 48. 万能接着剤(Super Glue)の例 やりたいこと: 指定ファイルをbzip2圧縮して httpファイルアップロード Groovy ant HttpUnit 35 2011年12月1日木曜日
  • 49. ant+HtmlUnit @Grab('net.sourceforge.htmlunit:htmlunit:2.8') import com.gargoylesoftware.htmlunit.WebClient; new AntBuilder().bzip2(src:args[0], zipfile:args[0]+".bz2") def url = "http://pukiwiki.example.com/index.php? plugin=attach&pcmd=upload&page=test" def page = new WebClient().getPage(url) def fileField = page.getElementById('_p_attach_file') fileField.valueAttribute = args[0]+".bz2" page.getByXPath("//input[@value='アップロード']")[0].click() 36 2011年12月1日木曜日
  • 50. ant+HtmlUnit @Grab('net.sourceforge.htmlunit:htmlunit:2.8') import com.gargoylesoftware.htmlunit.WebClient; new AntBuilder().bzip2(src:args[0], zipfile:args[0]+".bz2") def url = "http://pukiwiki.example.com/index.php? plugin=attach&pcmd=upload&page=test" def page = new WebClient().getPage(url) def fileField = page.getElementById('_p_attach_file') fileField.valueAttribute = args[0]+".bz2" page.getByXPath("//input[@value='アップロード']")[0].click() 依存ライブ ラリの実行時 自動取得 36 2011年12月1日木曜日
  • 51. ant+HtmlUnit @Grab('net.sourceforge.htmlunit:htmlunit:2.8') import com.gargoylesoftware.htmlunit.WebClient; new AntBuilder().bzip2(src:args[0], zipfile:args[0]+".bz2") def url = "http://pukiwiki.example.com/index.php? plugin=attach&pcmd=upload&page=test" def page = new WebClient().getPage(url) def fileField = page.getElementById('_p_attach_file') fileField.valueAttribute = args[0]+".bz2" page.getByXPath("//input[@value='アップロード']")[0].click() Java資産の有 依存ライブ 効活用 ラリの実行時 (HtmlUnit, Ant) 自動取得 36 2011年12月1日木曜日
  • 52. @Grab/Grape @Grab('net.sourceforge.htmlunit:htmlunit:2.8') import com.gargoylesoftware.htmlunit.WebClient; group指定 module指定 versoin指定 Grape Groovyスクリプト用の依存Jar管理機構 Apache Ivyベース/Maven互換 スクリプトを初回実行時に依存jarを自 動ダウンロード 37 2011年12月1日木曜日
  • 53. Groovyの利用パターン (2 of 7) やわらかな心臓部(Liquid Heart): 中核となるロジックだ けをGroovy/DSLで書けるようにする 頻繁な変更 Groovy/DSL Java JavaAPI Java VM 38 2011年12月1日木曜日
  • 54. やわらかな心臓部(LiquidHeart)の例 JavaからGroovyを呼びだす Binding binding = new Binding(); GroovyShell shell = new GroovyShell(binding); File script = new File(filename); shell.evaluate(script); 39 2011年12月1日木曜日
  • 55. Groovyの利用パターン (3 of 7) お化粧(Lipstick): Javaのライブラリ・コンポーネントを 簡潔に利用できる層をもうける。 Groovy Wrapper Javaコンポーネント JavaAPI Java VM 2011年12月1日木曜日
  • 56. お化粧(Lipstick)の例 GroovyFX JavaFX Grails Spring FW Hibernate Geb Gant/AntBuilder Selenium Ant 41 2011年12月1日木曜日
  • 57. GroovyFX Scene Graph DSL: 画面部品のツリー構造を Groovyのビルダーで記述 new SceneGraphBuilder(). stage(title:"Title",width:400,height:300,visible:true,resizable:true) { scene(fill: groovyblue) { rectangle x: 20, y: 20, width: 100, height: 50, fill: blue   onMouseClicked { println "hello" } } } Timeline DSL: 時間軸制御 timeline {     at(2.s) {         change(myCircle, 'layoutX'){ to 500 } } } 42 2011年12月1日木曜日
  • 58. Groovyの利用パターン (4 of 7) 内視鏡手術(Keyhole Surgery): 実行時にGroovyスクリ プトを接続できる小さな口を用意しておく 外部から Groovyコードを 注入 GroovyShell Java JavaAPI Java VM 43 2011年12月1日木曜日
  • 59. 内視鏡手術(Keyhole Surgery) の例 Jenkinsのスクリプトコンソール Jenkins CLI Grails Console Plugin 44 2011年12月1日木曜日
  • 60. Groovyの利用パターン (6 of 7) 小人さんスクリプト(House-elf Script): 周辺の各種支援 スクリプトをGroovyで書く 周辺スクリプト 開発対象のシステム Java Groovy JavaAPI JavaAPI Java VM Java VM 1 45 2011年12月1日木曜日
  • 61. Groovyの利用パターン (7 of 7) ゴーストライター(Ghost Writer): 裏でコード生成 Groovyコード 自動生成されるバイトコード JavaAPI Java VM 1 32 46 2011年12月1日木曜日
  • 62. ゴーストライターの例 やりたいこと:イミュータブル(不変)クラスを定 義しよう! クラスはfinalに 全フィールドをfinalかつprivate getter定義 Mutableなフィールド (配列やStringBufferや Dateなど) の取得に対しては「防御的コピー」 全フィールドをコンストラクタで初期化するコン ストラクタを定義 フィールドの値に基づくequals, hashCode, toStringを定義する 参考: Effective Java (2nd Edition), p73: Item15 Minimize mutability 2011年12月1日木曜日
  • 63. Java版 イミュータブルクラス: 57行 public final class Person { if (getClass() != obj.getClass()) private final String firstName; return false; private final String lastName; Person other = (Person) obj; if (firstName == null) { public Person(String firstName, String lastName) { if (other.firstName != null) this.firstName = firstName; return false; this.lastName = lastName; } else if (!firstName.equals(other.firstName)) } return false; if (lastName == null) { public String getFirstName() { if (other.lastName != null) return firstName; return false; } } else if (!lastName.equals(other.lastName)) return false; public String getLastName() { return true; return lastName; } } @Override @Override public String toString() { public int hashCode() { return "Person(firstName:" + firstName final int prime = 31; + ", lastName:" + lastName + ")"; int result = 1; } result = prime * result + ((firstName == null) ? 0 : firstName.hashCode()); } result = prime * result + ((lastName == null) ? 0 : lastName.hashCode()); return result; } @Override public boolean equals(Object obj) { やすく、 if (this == obj) 、ミスが混入し return true; 作成が大変 はない ド上明確で if (obj == null) return false; 意図がコー 参考: http://groovy.codehaus.org/Immutable+AST+Macro 48 2011年12月1日木曜日
  • 64. Groovy版イミュータブルクラス: 4行 これ だけ です @Immutable よ!こ れだ class Person { け String firstName, lastName } 49 2011年12月1日木曜日
  • 65. Groovy版イミュータブルクラス: 4行 これ だけ です @Immutable よ!こ れだ class Person { け String firstName, lastName } x = new Person("Junji","Uehara") assert x.lastName == "Uehara" x.firstName = "abc" //==> groovy.lang.ReadOnlyPropertyException: Cannot set readonly property: firstName for class: Person 49 2011年12月1日木曜日
  • 66. 強力なゴースト執筆陣 @Immutable, @ListenerList, @ToString, @Equals, @EqualsAndHashcode, @AutoClone, @TimedInterrupt, @Lazy, @Mixin, @Singleton, @InheritConsructors,@WithReadLock, @WithWriteLock, @Log, @Delegate, @Lazy, @Singleton, @Bindable, ほか 上記は「AST変換」を起動するアノテーション。 50 2011年12月1日木曜日
  • 68. Groovy 2.0へ 安定版最新 Groovy 1.8.4 開発版最新 Groovy 2.0.0-beta1 (=1.9-beta5相当) 2012年初頭に正式版登場予定 52 2011年12月1日木曜日
  • 69. Groovyの新機能 Java 7のProject Coin対応(2.0以降) 二進リテラル リテラル中の下線 マルチキャッチ InvokeDynamic対応(2.0以降) try-with-resourceなどはいまのところ未 Groovy自体のモジュール化(1.8以降) 静的型チェック(2.0.0 beta1で実験的実装) 静的コンパイル(2.0以降) 53 2011年12月1日木曜日
  • 70. まとめ http://www.flickr.com/photos/limonada/214375219/ 54 2011年12月1日木曜日
  • 71. 本日伝えたかったこと Groovyとは何か? Groovyは簡単なのか? Java開発者にとってYES! 通常のJava開発と地続き Groovyは便利なのか? Java開発者にとってYES! 簡潔さと高機能さが 今、手はいる。 JavaプログラマにとってGroovyとは何か? Java x Groovyを実現するもの! 55 2011年12月1日木曜日
  • 72. 本日伝えたかったこと Groovyとは何か? Groovyは簡単なのか? Java開発者にとってYES! 通常のJava開発と地続き Groovyは便利なのか? Java開発者にとってYES! 簡潔さと高機能さが 今、手はいる。 JavaプログラマにとってGroovyとは何か? Java x Groovyを実現するもの! 55 2011年12月1日木曜日
  • 73. 本日伝えたかったこと Groovyとは何か? Groovyは簡単なのか? Java開発者にとってYES! 通常のJava開発と地続き Groovyは便利なのか? Java開発者にとってYES! 簡潔さと高機能さが 今、手はいる。 JavaプログラマにとってGroovyとは何か? Java x Groovyを実現するもの! 55 2011年12月1日木曜日
  • 74. 本日伝えたかったこと Groovyとは何か? Groovyは簡単なのか? Java開発者にとってYES! 通常のJava開発と地続き Groovyは便利なのか? Java開発者にとってYES! 簡潔さと高機能さが 今、手はいる。 JavaプログラマにとってGroovyとは何か? Java x Groovyを実現するもの! 55 2011年12月1日木曜日
  • 75. Java x Groovy GroovyはJavaの弱点を補う 組み合わせて使うことで相乗効果を発揮 Java開発者にとって修得・導入がごく容易 Java x Groovy (DIxAOP的な意味で) Groovy利用をJava開発と組み合わせることで、 Java開発を加速する! 56 2011年12月1日木曜日
  • 76. ご静聴ありがとうご ざいました 57 2011年12月1日木曜日
  • 77. コミュニティもよろしく 活発な国内コミュニティ 電子雑誌 G*マガジン 月1定例勉強会 G*ワークショップ 年1恒例合宿 その他企画 58 2011年12月1日木曜日