Sự khác nhau giữa Scala và Java 8 (Phần 2)

Screenshot from 2016-11-06 23-01-55.png

Sau khoảng 1 tháng bận bịu không có ngày chủ nhật thì hôm nay mình sẽ viết tiếp phần 1 , mời các bạn theo dõi.

3. Immutability

Tính bất biến trong ngôn ngữ lập trình làm là cách tiếp cận làm cho mọi thứ trở nên khác biệt trong kinh nghiêm phát triển phần mềm.

Tính bất biến là mô hình mà đối tượng sau khi được tạo ra sẽ không thể thay đổi trạng thái của nó. Nếu bạn muốn thay đổi trạng thái của đối tượng bất biến thì bạn cần tạo ra bản sao của nó và thay đổi các thuộc tính cần thiết.

Trong Java, ví dụ về tính bất biến đơn giản nhất là đối tượng String. Mỗi khi đối tượng String thay đổi là một bản sao của nó được tạo ra.

Tính bất biến có thể coi là chìa khóa của ngôn ngữ lập trình hàm (lập trình chức năng). Bởi vì nó phù hợp với mục tiêu giảm tải sự thay đổi các đối tượng trong chương trình, điều này giúp ta quản lý dễ dàng suy luận và quản lý các thành phần trong chương trình.

4. Traits trong Scala và Virtual extension method trong Java

Scala cung cấp một cơ chế tuyệt vời để mở rộng các class. Về mặt kỹ thuật thì Trait cung cấp giao diện(interface), bao gồm các tùy chọn (phương thức hoặc thuộc tính). Một class có thể gọi nhiều Trait.

Lưu ý rằng Scala giống với Java là đều không hỗ trợ đa kế thừa, một subClass chỉ có thể kế thừa từ một superClass. Nhưng với Trait thì khác, một class có thể gọi nhiều Trait với từ khóa "with".

Với Trait, bạn có thể cô lập các tính năng chung chung theo kiểu moduls và gọi lại chúng ở bất cứ class nào khi cần sử dụng.

Bên cạnh đó, trong Java 8 mới đây có giới thiệu Virtual Extension Methods (hay còn được gọi là Default Methods)

5. Kiểu dữ liệu và thư viện đa dạng

Không giống như Virtual Extension Methods trong Java 8, Scala cung cấp các implicit class giúp bạn có thể định nghĩa những hành vi mới và sử dụng chúng ở bất kỳ class nào với cách import đơn giản. Ví dụ:

    // định nghĩa Implicit class
    object IntExtensions {
      implicit class IntPredicates(i: Int) {
        def isEven = i % 2 == 0
        def isOdd  = !isEven
      }
    }

    import IntExtensions._  // import ở nơi cần dùng
    4.isEven  // sử dụng function trong implicit class đã import

Một trong những điều đáng chú ý nhất trong cách tiếp cận này là có một bộ thư viện chuẩn là cầu nối giữa bộ thư viện của Java và bộ thư viện của Scala. Nhờ đó trong mã Scala ta có thể gọi phương thức ".asJava()" và trong mã Java có thể gọi ".asScala()" làm cho cách xử lý phong phú đa dạng hơn.

6. Việc sử dụng các mẫu thiết kế (design patern)

Ghé qua một diễn đàn nào đó có thể bạn bắt gặp một số bài viết như "A factory pattern in Scala”, “a Command pattern in Scala”. Mình từng đọc được một bài viết nói về việc sử dụng các mấu thiết kế, tác giả của bài viết là một người nhiều năm kinh nghiệm làm việc trên cả 2 ngôn ngữ Java và Scala. Ông nói rằng việc sử dụng các mẫu thiết kế trong scala không thật sự cần thiết như trong Java. Bởi vì cách tiếp cận vấn đề theo hướng kiểu function mở ra nhiều hướng giải quyết hơn và khi đó cách giải quyết phụ thuộc vào logic của người lập trình nên không còn phụ thuộc vào các mẫu thiết kế.

7. Minimal codebase

Có nghĩa là tối thiểu code. Đây là một tính năng trong Scala mà Java chưa được thông qua.

-Ví dụ điển hình nhất là khai báo một class. Trong Java bạn sẽ khải báo như thế nào???

    public class Person {
         private final Integer id;
         private String name;

         public Person(Integer id, String name) {
             this.id = id;
             this.name = name;
         }

         public Integer getId() {..}

         public String getName() {..}
         public void setName(String newName) {..}

         @ Override
         public boolean equals(Object obj) {..}

         @ Override
         public int hashCode() {..}
    }

Dưới đây là cách bạn khai báo nó tương tự trong Scala:

    case class Person(@BeanProperty val id: Int,@BeanProperty var name: String)
 /*@BeanProperty là annotation mà khi compiler sẽ tự động tạo ra getters and setters giống java-style,
  như là getId(), setName(..),...., thay cho các getter-setters như mã code java. */

-Đê khởi tạo một biến trong Java:

    public final String myCoolString = "My cool final string";

thì trong Scala bạn chỉ cần khai báo ngắn gọn:

 val myCoolString = "My cool final string"

-Cách sử dụng Java string:

 log.debug(String.format("This is %s, %s = %d", SomeClass.someMethod(), someVariable, someStatusCode));

thì Scala cung cấp tính năng nội suy mạnh mẽ:

 log.debug(s"This is ${SomeClass.someMethod}, $someVariable = $someStatusCode")

trong Scala cũng cung cấp tính năng multi-line string, cho phép viết một string trên nhiều dòng, điều này thật sự hữu ích ví dụ như trường hợp viết câu truy vấn SQL:

     """
         SELECT column1,
                column2
         FROM table1
         WHERE column1 > 0;
     """

8. Code and runtime compatibility

Scala và Java đều chạy trên môi trường (jdk, jre). Vì vậy khi JRE, hay JDK cập nhật Scala sẽ không bỏ lỡ những cải tiến nào từ Java.

================================================== Phần 2 bài viết về một vài điểm khác nhau giữa Scala và Java mình xin dừng lại tại đây. Các bạn có thể theo dõi Phần 1 tại link này.

Xin cảm ơn các bạn đã theo dõi bài viết.


All Rights Reserved