Groovy và Java, những điều khác biệt

Groovy có cách tổ chức cú pháp gần giống Ruby
Những điểm khác biệt
1. Không sử dụng dấu ;
Nếu các bạn đã từng dùng qua C, C++, C# thì các bạn sẽ thấy là cú pháp của các ngôn ngữ trên bắt buộc sử dụng dấu ; nhắm thông báo cho trình biên dịch là đã kết thúc 1 statement. Với Groovy, điều đó là không bắt buộc nữa. Dĩ nhiên làGroovy hổ trợ đến 99% cú pháp của Java nên sẽ rất dễ dàng nếu copy code củaJava và chạy trên Groovy.
2. Return không là một keyword bắt buộc
Với Groovy, kết quả của biểu thức cuối cùng được tính toán trong một hàm có thể được trả về mà không cần từ khóa return. điều này làm cho cú pháp được ngắn gọn, dễ đọc, đặc biệt là với các hàm ngắn hoặc closures.
| String toString() { return "a server" } String toString() { "a server” } |
Theo mình thì các bạn nên sử dụng song song việc có return và không có return. Vì đôi khi từ khóa return sẽ làm cho code của bạn dễ đọc hơn.
Các bộ từ khóa lặp, điều kiện cũng có thể áp dụng điều này
| def foo(n) { if(n == 1) { "Roshan" } else { "Dawrani" } } assert foo(1) == "Roshan" assert foo(2) == "Dawrani" |
3. Def and type
Rất nhiều lập trình viên, lẫn cả chính mình sử dụng từ khóa def. Trong Groovy.def không cần thiết.
Đừng viết:
| def String name = "Guillaume" |
nhưng:
| String name = "Guillaume" |
Khi định nghĩa một phương thức với untype parameters, thay vì viết
| void doSomething(def param1, def param2) { ... } |
Thì bạn nên viết
| void doSomething(param1, param2) { } |
4. Public by default
Mặc định, Groovy hiểu rằng các classes và methods đều mang modifier là public. Trong trường hợp bạn không muốn method đó hoặc class đó là public, thì bạn nên đặt vào đó một modifer keyword
Thay vì viết:
| public class Server { public String toString() { return "a server" } } |
Nên viết:
| class Server { String toString() { "a server" } } |
Groovy hổ trợ package scope annotation nhằm set một biến chỉ public trong package đó.
| class Server { @PackageScope Cluster cluster } |
Tương tự Ruby. Groovy giúp bạn có thể bỏ các dấu () để đánh dấu parameters
| println "Hello" method a, b |
thay vì viết:
| println("Hello") method(a, b) |
Dĩ nhiên là trong một vài trường hợp. Groovy không cho phép bạn bỏ cặp dấu ngoặc đơn, như ví dụ sau:
| def foo(n) { n } println foo 1 // won't work def m = foo 1 |
Đơn giản vì lúc đó Groovy sẽ dễ dàng nhầm tưởng là foo và 1 cùng là tham số đầu vào của hàm println
5. The .class suffix is not needed
Tiếp vị ngữ .class cho một Class Name không cần nữa. Thay vào đó các bạn sẽ dễ dàng viết
Ví dụ như
| connection.doPost(BASE_URI + "/modify.hqu", params, ResourcesResponse.class) |
Có thể viết thành
| connection.doPost("${BASE_URI}/modify.hqu", params, ResourcesResponse) |
6. Getters and Setters
Tương tự như C#, Getter và Setter trong Groovy được gọi là ‘property’ và nó làm cho công việc ghi và đọc một field từ một Object dễ dàng hơn
| resourceGroup.getResourcePrototype().getName() == SERVER_TYPE_NAME resourceGroup.resourcePrototype.name == SERVER_TYPE_NAME resourcePrototype.setName("something”) resourcePrototype.name = “something” |
Trong một Groovy Bean. Thay vì bạn có thể viết:
| class Person { private String name String getName() { return name } void setName(String name) { this.name = name } } |
Bạn có thể viết đơn giản hơn
| class Person { String name } |
7. Initializing beans with named parameters and the default constructor
Với một Bean như thế này
| class Server { String name Cluster cluster } |
Bạn hoàn toàn có thể viết theo phong cách Java như sau.
| def server = new Server() server.name = "Obelix" server.cluster = aCluster |
Nhưng với Groovy bạn có thể viết như sau mà không cần khai báo hàm khởi tạo có tham số
| def server = new Server(name: "Obelix", cluster: aCluster) |
8. Using with() for repeated operations on the same bean
Bạn rất ghét phải gọi tên của một Bean một cách lặp lại liên tục như sau
| server.name = application.name server.status = status server.sessionCount = 3 server.start() server.stop() |
Bạn có thể viết
| server.with { name = application.name status = status sessionCount = 3 start() stop() } |
9. Equals and ==
Trong Java, bạn không thể so sánh hai Object bằng dấu ==. Với Groovy thì điều này đã có thể
Bằng việc sử dụng phương thức equal() trong Java, bạn có thể sử dụng toán tử == để so sánh. Nó sẽ bao gồm cả việc kiểm tra giá trị null mà Java không làm được.
Thay vì:
| status != null && status.equals(ControlConstants.STATUS_COMPLETED) |
Có thể viết
| status == ControlConstants.STATUS_COMPLETED |
10. GStrings (interpolation, multiline)
Để nối các string với nhau, trong Java sử dụng dấu +, nhưng trong Groovy có thể viết khác đi một cách dễ dàng hơn.
Java
| throw new Exception("Unable to convert resource: " + resource) |
Groovy
| throw new Exception("Unable to convert resource: ${resource}") |
hoặc
| throw new Exception("Unable to convert resource: $resource”) |
11. Native syntax for data structures
Groovy hỗ trợ một số hàm khởi tạo cho các cấu trúc dữ liệu như lists, maps, regex…. Nên cố gắng sử dụng nó trong các chương trình Groovy của bạn.
Đây là một vài ví dụ:
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 | def list = [1, 4, 6, 9] // by default, keys are Strings, no need to quote them // you can wrap keys with () like [(variableStateAcronym): stateName] to insert a variable or object as a key. def map = [CA: 'California', MI: 'Michigan'] def range = 10..20 def pattern = ~/fo*/ // equivalent to add() list << 5 // call contains() assert 4 in list assert 5 in list assert 15 in range // subscript notation assert list[1] == 4 // add a new key value pair map << [WA: 'Washington'] // subscript notation assert map['CA'] == 'California' // property notation assert map.WA == 'Washington' // matches() strings against patterns assert 'foo' =~ pattern |
12. The power of switch
Switch trong Groovy rất thú vị vì các case của nó được mở rộng rất nhiều. Ví dụ
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 | def x = 1.23 def result = "" switch (x) { case "foo": result = "found foo" // lets fall through case "bar": result += "bar" case [4, 5, 6, 'inList']: result = "list" break case 12..30: result = "range" break case Integer: result = "integer" break case Number: result = "number" break default: result = "default" } assert result == "number" |
13. Import aliasing
Trong Java. Nếu có 2 class cùng tên. Bạn vẫn có thể import chúng vào code của bạn. Nhưng phải sử dụng fullname của nó khi sử dụng. Groovy đã khắc phục chuyện này bằng việc sử dụng Import aliasing
| import <a href="http://en.wikipedia.org/wiki/Java_(programming_language)">Java</a>.util.List as juList import java.awt.List as aList import <a href="http://en.wikipedia.org/wiki/Java_(programming_language)">Java</a>.awt.WindowConstants as WC |
Bạn cũng có thể import một static method:
| import static pkg.SomeClass.foo foo() |
14. Groovy Truth
Mọi đối tượng trong Groovy có thể đưa về giá trị kiểu boolean. null, void và empty sẽ bị xem là false còn lại là true.
Thay vì viết
| if (name != null && name.length > 0) {} |
có thể viết
Trong trường hợp bạn muốn tùy biến Groovy Truth, bạn có thể overide hàm asBoolean
15. Safe graph navigation
Trong Java, muốn làm 1 hành động gì đó với một Object, bạn phải check null. VớiGroovy thì nó đã hổ trợ bạn chuyện đó
| if (order != null) { if (order.getCustomer() != null) { if (order.getCustomer().getAddress() != null) { System.out.println(order.getCustomer().getAddress()); } } } |
Với toán tử kiểm tra ?., bạn có thể viết đơn giản.
| println order?.customer?.address |
16. Assert
Để kiểm tra parameters, giá trị trả về… bạn có thể dùng lệnh assert
| def check(String name) { // name non-null and non-empty according to Groovy Truth assert name // safe navigation + <a href="http://groovy.codehaus.org/">Groovy</a> Truth to check assert name?.size() > 3 } |
17. Elvis operator for default values
Trong Java các bạn viết
| def result = name != null ? name : “Unknown" |
Nhưng với Groovy
| def result = name ?: "Unknown" |
18. Catch any exception
Trong Java, đôi khi bạn phải dùng TryCatch và buộc phải Catch đúng loại exception
| try { // ... } catch (Throwable t) { // something bad happens } |
với Groovy thì điều này đơn giản hơn
| try { // ... } catch (any) { // something bad happens } |
Kết luận
Là một người từng sử dụng Ruby và Java. Mình thấy Groovy có sự pha trộn giữa cả 2 ngôn ngữ. Nó có rất nhiều cái hay và thú vị. Mình học nó vì nó gần gũi với cả Java và Ruby, nó mang sức mạnh của Java và sự tính tế của Ruby, Và nó là ngôn ngữ cho Grails. Một framework mạnh mẽ. Vậy thì tại sao không bắt tay vào thử tìm hiểu nó xem.
Nguồn: http://bit.ly/16BA4zl