Kotlin Tips : Sử dụng Singleton, Utility Functions, Group Object Initialization và nhiều hơn nữa

Tất cả những Tips này để hỗ trợ các bạn viết code Kotlin trở nên tốt hơn và sử dụng tối đa những gì mà ngôn ngữ cung cấp.

Có rất nhiều lợi ích cho Android Developer chúng ta khi sử dụng Kotlin như ngắn gọn, súc tích, an toàn và quan trọng hơn nó có thể tương tác với Java 100%. Và ngôn ngữ này cũng được phát triển để cố gắng giải quyết một số hạn chế của Java. Các bạn có thể tham khảo một cái liệu rất hay của Jake Wharton đã viết vào năm 2015 để biết lý do tại sao Square nên bắt đầu sử dụng Kotlin. Và bây giờ cũng là thời điểm tốt để xem xét sử dụng Kotlin cho những tính năng hoặc dự án tiếp theo của các bạn, bởi vì Google cuối cùng cũng đã công bố nó là một ngôn ngữ hạng nhất để viết các ứng dụng Android trong Google I/O 17.

Vì vậy dây là một số lời khuyên để giúp bạn bắt đầu sử dụng những tính năng và ngôn ngữ này cung cấp và để viết code Kotlin tốt hơn.

1. Singleton

Triển khai Lazy Loaded hoặc Thread safe trong Kotlin thực sự dễ dàng, không giống như Java mà bạn phải dự vào mô hình double-checked locking pattern khá là phức tạp. Và mặc dù các kiểu dữ liệu Java enum singleton là Thread safe, nhưng chúng lại không phải Lazy Loaded.

object Singleton {
    var s: String? = null
}

Trái ngược với Kotlin Class, một Kotlin Object không thể có bất kỳ một Contructor nào. nhưng nếu cần khởi tạo một số field thì có thể đặt trong init block.

Singleton.s = "test" // class is initialized at this point

Kotlin Object sẽ được khởi tạo và init blocks của nó sẽ được thực hiện Lazy Loaded trong lần đầu truy vấn, đây cũng là một cách dùng thread-safe.

2. Utility Functions

Các chức năng mở rộng cấp cao nhất của Kotlin là sử dụng được các class Utitlity điển hình của Java. Và để sử dụng dễ dàng hơn trong Code Java, sư dụng từ khóa @file:JvmName để xác định tên của lớp Java mà bạn muốn gọi mà sẽ được khởi tạo bởi trình biên dịch Kotlin.

//Kotlin 
@file:JvmName("DemoUtils")

package demo

class Foo

fun bar() {
}

// Java
new demo.Foo();
demo.DemoUtils.bar();

3. Object Initialization

Sử dụng apply cho việc khởi tạo một nhóm các giá trị trong object để code sáng hơn và đọc dễ hiểu hơn.

// Không nên
val textView = TextView(this)
textView.visibility = View.VISIBLE
textView.text = "test"

// Nên
val textView = TextView(this).apply {
    visibility = View.VISIBLE
    text = "test"
}

4. Một vài Tips nhỏ nữa chỉ dành cho các bạn thôi nhé.

* let()

Sử dụng let() có thể ngắn gọn và súc tích hơn việc sử dụng if. Xem ví dụ ở dưới đây

val listWithNulls: List<String?> = listOf("A", null)
for (item in listWithNulls) {
    if (item != null) {
        println(item!!)
    }
}

Với let() không cần phải dùng đến if

val listWithNulls: List<String?> = listOf("A", null)
for (item in listWithNulls) {
    item?.let { println(it) } // prints A and ignores null
}

* when()

when thay thế cho switch của Java và nó có thể được sử dụng để làm sạch một số khó khăn khi đọc câu lệnh điều kiện if Ví dụ :

// Java
public Product parseResponse(Response response) {
   if (response == null) {
       throw new HTTPException("Something bad happened");
   }
   int code = response.code();
   if (code == 200 || code == 201) {
       return parse(response.body());
   }
   if (code >= 400 && code <= 499) {
       throw new HTTPException("Invalid request");
   }
   if (code >= 500 && code <= 599) {
       throw new HTTPException("Server error");
   }
   throw new HTTPException("Error! Code " + code);
}

Và trong Kotlin nó có thể được nhìn như thế này :

fun parseResponse(response: Response?) = when (response?.code()) {
   null -> throw HTTPException("Something bad happened")
   200, 201 -> parse(response.body())
   in 400..499 -> throw HTTPException("Invalid request")
   in 500..599 -> throw HTTPException("Server error")
   else -> throw HTTPException("Error! Code ${response.code()}")
}

* Read-only lists, maps, …

Kotlin có phân việt giữa các Collections(lists, sets, maps...) có thể thay đổi (mutable) và không thể thay đổi (immutable). Kiểm soát chính xác khi nào collections có thể được chỉnh sửa rất hữu ích để loại bỏ lỗi và để thiết kế các API tốt. Thư viện chuẩn của Kotlin chứa các hàm và kiểu tiện ích cho tất cả collections có thể thay đổi và không thể thay đổi ví dụ như listOf(), và mutableListOf().

val list = listOf(“a”, “b”, “c”)
val map = mapOf("a" to 1, "b" to 2, "c" to 3)

* Lazy property

lazy is good (Có nghĩa là cứ lười biếng đều alf tốt cả =))). Nói đùa thôi chứ sử dụng từ khóa lazy là khi nó có ý nghĩa :3. Như là giảm bộ nhớ sử dụng là trường hợp sử dụng tốt nhất và cũng tiết kiệm chu kỳ CPU nếu hàm khởi tạo của nó ngốn bộ nhớ. Lazy properties chỉ được tính khi truy cập lần đầu tiên.

val str: String by lazy {
     // Compute the string
}

Bạn muốn tìm hiểu nhiều hơn nữa chứ

Tài liệu tham khảo đầy đủ về ngôn ngữ Kotlin có thể được tìm thấy ở đây Bạn đã có thể sẵn sàng thử Kotlin chứ. Thế thì vào đây thử nhé