グルーヴィーな理由
Java開発者として、少し前に他のプログラミング言語の方向に目を向け始めました。 かつてJavaプラットフォーム向けの開発経験が少なかった友人の中には、Rubyを使用してレール(レール)でそれぞれ動き始めた人もいました。 Javaプログラマーが動的言語の世界にどのように移行できるかについての十分な本があります。 何かが私たちを止めることができますか?
偶然にも、私のパートナーの隣の椅子からRuby&Railsの開発を観察し、自分自身をおしっこすることさえありました。時にはJavaスタイルに対する批判に耳を傾けました。 その結果、残念ながらまたは幸運にも、まだよくわかりませんが、行き詰まりませんでした。 それでも、私はおそらく、いくつかの基準で、それほど大きくはありませんが、それでも私にとっての主なことは、ほぼ3年間のJavaの経験でした。 同時に、ストリーミングビデオテクノロジーを使用してアプリケーションを作成する際にそのコンポーネントが不可欠であったAS3 / Flexの研究に費やした時間のかなりの部分について、簡単に説明することができます。 しかし、幸いなことに、このプラクティスは終わったようです。
今週末、Groovyについての記事に出会いましたが、それがどのように始まったのか思い出せません。 その後、いくつかの記録された会議を見た後、今回Groovyは間違いなく私に興味を持ちました。 この言語はJavaプラットフォーム向けに設計されており、JVMで実行される他の動的言語の中で最も人気があります。 もちろん、私にとって馴染みのある言語のコンポーネントとのかなり単純な統合、よく知られているフレームワークの使用、OSGi環境での作業に満足しています。これらすべてが、エレガントなコードを書く機会を与えながら、Javaの世界を離れることを本当に妨げます。
さて、十分な水、そうでなければ既にかなり多くのことが判明したので、ビジネスに取り掛かり、先週末の私の活動の1つであった遠足であるGroovyに触発された理由を説明しようと思います。
JavaBeansとGroovy
Javaを少し学び、カプセル化の基本を知った後、これらの2つのアクションがどの順序で完了するかに関係なく、私たちのほとんどはJavaBeanを書く必要に直面しています。 このためのIDEでは、HotKeyでさえもそうでした。 以下は、それぞれJavaとGroovyのJavaBeanです。
//Java
import java.util.Date;
public class Employee {
private String firstName;
private String lastName;
private Date dateSince;
public String getFirstName() {
return firstName;
}
public void setFirstName(String firstName) {
this.firstName = firstName;
}
public String getLastName() {
return lastName;
}
public void setLastName(String lastName) {
this.lastName = lastName;
}
public Date getDateSince() {
return dateSince;
}
public void setDateSince(Date dateSince) {
this.dateSince = dateSince;
}
}
//Groovy
class Employee {
String firstName
String lastName
Date dateSince
}
Javaで31行、Groovyで5行でした。
そして、これはパラメーターを伴う追加のコンストラクターなしで、Groovyで記述しますが、まったく必要ありません。
def e = new Employee(firstName:'Ivan', lastName:'Petrov')
プライベートの場所を教えてください、またはオブジェクトの状態を変更する機会を常に与える必要はないことを教えてください(-seeters + constructor)? そして、このような問題は
@Immutable
アノテーションで解決できることが判明しました
import groovy.lang.Immutable;
@Immutable class Employee {
String firstName
String lastName
Date dateSince
}
例外
このトピックに関しては、長い間議論することができます... Javaで知っているように、例外はチェック済み(チェック済み)と未チェック(未検証)に分けられます。 Groovyでは、すべての例外はチェックされていないクラスに起因する可能性があります。つまり、メソッドを呼び出したり、処理が上記のどこかにあることを示すときに、強制的にそれらをキャッチすることはありません。 ここでは、結局私たちは子供ではなく、このためにウォーダーを必要としないと思うかもしれません。 しかし、同時に、スローを指定したり、try / catchブロックでコードをラップしたりする人はいません。
代表団
コードを短縮するには、コンテナクラスから1つ以上のフィールドにメソッド呼び出しをリダイレクトし、少しばかげた同じタイプのメソッドを生成する必要があります。
以下は、この問題の解決策を示す簡単な例です。
import java.text.SimpleDateFormat
class Event {
@Delegate Date when
String title, url
}
def df = new SimpleDateFormat("yyyy/MM/dd")
def gr8conf = new Event(title: "GR8 Conference",
url: "http://www.gr8conf.org",
when: df.parse("2009/05/18"))
def javaOne = new Event(title: "JavaOne",
url: "http://java.sun.com/javaone/",
when: df.parse("2009/06/02"))
assert gr8conf.before(javaOne.when)
ご覧のとおり、 Dateクラスのメソッドを簡単に使用できるようになりました。
gr8conf.before(javaOne.when)
という式は、コードの純度を維持しながら、非常に論理的に見える。
もちろん、この例は非常に原始的ですが、誰もがこれが彼を助けることができる瞬間を頭の中で再現できると思います。
閉鎖
Javaにはクロージャはありません。Java8では、計画または再び転送されたとおりに、クロージャがいつ表示されるかを正確に言うことはできません。 Groovyでは、今すぐ使用できます。 ここではクロージャーを詳細に検討することはしません。これは別の記事のトピックだと思いますが、コードを削減する方法の一例を示します。
労働者(従業員)のリストがあり、特定の選択基準(給与、年齢、部門など)を満たすサブセットを選択する必要があるとします。
List getStaffWithMuchSalaryThan(List staff, double salary);
List getStaffYoungerThan(List staff, int age);
List getStaffByDepartment(List staff, Dept dept);
それぞれにほぼ同じロジックがあります。サイクルを実行し、条件への準拠を確認します。 満足できる場合は、結果リストに追加します。
つまり、Javaには次の3つのメソッドがあります。
public List getStaffWithMuchSalaryThan(リストスタッフ、二重給与){
リスト結果= new ArrayList();
for(従業員e:スタッフ){
if(e.getSalary()> = salary){
result.add(e);
}
}
結果を返す;
}
上記の2つのメソッドのそれぞれについても同様です。 もちろん、ストラテジーパターンを使用してコード設計の問題を解決できますが、行数は非常に多くなります。
次に、クロージャーを使用して同じことを書き込もうとします。
//
def staff = [
new Employee(firstName: 'A', salary:500, age:20, dept:'K'),
new Employee(firstName: 'B', salary:700, age:30, dept:'K'),
new Employee(firstName: 'C', salary:1000, age:25, dept:'A2') ]
//
def getStaffWithCriteria(staff, criteria) {
result = []
for(e in staff) {
if(criteria(e)) result.add(e)
}
result
}
println getStaffWithCriteria(staff, {e -> e.salary > 600}) // 600
println getStaffWithCriteria(staff, {e -> e.age < 27}) //, 27
println getStaffWithCriteria(staff, {e -> e.dept == 'K'}) // K
// UPD:1つの自転車がなくても、コードは次のように簡素化されます。
println staff.grep {e-> e.salary> 600}
println staff.grep {e-> e.age <27}
println staff.grep {e-> e.dept == 'K'}
どうもありがとう
結果:
[B、C]
[A、C]
[A、B]
コレクションを操作する
Groovyを使用すると、リストの作成から反復まで、リストの操作が非常に簡単になります。
それは非常に論理的です:
def list = ['a', 'b', 'c']
Javaコードの代わりに:
リストリスト= new ArrayList();
list.add( "a");
list.add( "b");
list.add( "c");
要素をリストするだけでよいと仮定します。
Javaの場合:
for(String s: list) {
System.out.println(s);
}
Groovyの場合:
list.each {println it}
要素のインデックスにアクセスする必要がある場合、Javaループはそれほど魅力的ではありません。 次に、以下に示す形式のループなしで、またはこれに加えて追加の変数を導入することによって、ループ内で変数に対してインクリメント操作を実行することはできません。
for (int i = 0; i < list.size(); i++) {
System.out.println(i + " - " + list.get(i));
}
Groovyでは、このタスクにはよりシンプルなソリューションもあります。
list.eachWithIndex {e, i -> println “${i} - ${e}”}
また、最後の要素の後にセパレーターを置いてはならないという条件で、区切り記号付きのリストを表示するコードを作成する必要があった場合もあります。 そして今、これは要素がサイクルの最後かどうかをチェックするための目を引く条件の1つです。
この目的のためのGroovyコードは、joinメソッドを使用して大幅に簡素化されます
list.join(', ')
行を生成します: “ a、b、c”
プロジェクトの組み立て
開発環境の組み込み機能の代わりに、Ant、Mavenなどのプロジェクトを構築するためのツールを使用することに慣れている人は、Gradleを試すことをお勧めします。 Javaプロジェクトを構築するためのMavenに対する私のかなりの愛にもかかわらず、Gradleは私にとってはるかに素晴らしく見えます。 残念ながら、この記事の枠組みでは、Gradleについて良いと言えるすべてのものは当てはまりません。 ちなみに、昨日12月19日、バージョン0.9がリリースされましたが、これには多くの変更が含まれていました。
おわりに
もちろん、この記事は、Guruovyの使用を奨励する第一人者の口実やメインガイドのふりをするものではありません。 新しい経験を共有したかっただけです。 しかし、この言語をさらに研究することで、Javaプラットフォームのサポーターであり続けると同時に、Groovyから多くの動的機能を導入できれば非常に良いでしょう。 ここでは、Groovyがコードをよりシンプルでエレガントなものにする方法のほんの一部を検討しましたが、読者の皆さんがこの言語で提供する他の多くの機能を試してみてください。 結論として、Groovyは若い言語であり、現在コミュニティによって非常に積極的に開発されているという事実に注意を払うことができます。SpringSourceからの投資もあります。 この言語の事実上のWebフレームワークはGrailsです。
主な情報源
groovy.codehaus.org
www.infoq.com/presentations/Transforming-to-Groovy (プレゼンテーションの写真を変更するのを待つことはできません。ビデオの全画面を安全に押すことができます)
www.infoq.com/presentations/Industrial-Strength-Groovy
www.asert.com.au/pubs/Groovy/Groovy.pdf