Việc chuyển sang một ngôn ngữ mới có thể là một thử thách. Để giúp nhóm của bạn thành công, hãy bắt đầu từ từ, di chuyển theo từng phần nhỏ và kiểm thử thường xuyên. Kotlin biên dịch thành mã byte JVM và hoàn toàn tương thích với Java, giúp quá trình di chuyển trở nên dễ dàng hơn.
Xây dựng nhóm
Bước đầu tiên trước khi di chuyển là xây dựng kiến thức chung cơ bản cho nhóm của bạn. Sau đây là một số mẹo có thể giúp bạn đẩy nhanh tốc độ học tập của nhóm mình.
Thành lập nhóm học tập
Nhóm học tập là một cách hiệu quả để thúc đẩy việc học và khả năng tiếp thu. Các nghiên cứu cho thấy việc nhắc lại những điều đã học trong một nhóm sẽ giúp ghi nhớ nội dung tốt hơn. Hãy tìm sách về Kotlin hoặc tài liệu học tập khác cho từng thành viên trong nhóm và yêu cầu nhóm đọc một vài chương mỗi tuần. Trong mỗi cuộc gặp, nhóm nên so sánh nội dung đã học và thảo luận về những thắc mắc hoặc nhận định của mình.
Xây dựng văn hoá dạy học
Mặc dù không phải ai cũng tự nhận mình là giáo viên, nhưng mọi người đều có thể dạy học. Từ trưởng nhóm hoặc kỹ sư trưởng đến cộng tác viên cá nhân, ai cũng có thể góp phần tạo ra môi trường học tập có thể giúp đảm bảo thành công. Một cách để thúc đẩy việc này là tổ chức các buổi thuyết trình định kỳ, trong đó một người trong nhóm được chỉ định để nói về những điều họ đã học hoặc muốn chia sẻ. Bạn có thể tận dụng nhóm học tập của mình bằng cách tìm người xung phong trình bày một chương mới mỗi tuần cho đến khi nhóm của bạn cảm thấy quen thuộc với ngôn ngữ này.
Chọn người dẫn dắt
Cuối cùng, hãy chọn ra người dẫn dắt một chiến dịch học tập. Người này có thể đóng vai trò là chuyên gia giải đáp vấn đề (SME) khi bạn bắt đầu quá trình áp dụng ngôn ngữ mới. Điều quan trọng là phải đưa người này vào tất cả các buổi thực hành liên quan đến Kotlin. Tốt nhất, đây nên là người vốn đã đam mê Kotlin và có kiến thức thực tiễn.
Tích hợp từ từ
Hãy bắt đầu từ từ và suy nghĩ một cách có chiến lược về những phần cần di chuyển đầu tiên trong hệ sinh thái của bạn. Tốt nhất là bạn nên di chuyển một ứng dụng đơn lẻ trong tổ chức thay vì một ứng dụng hàng đầu. Đối với việc di chuyển ứng dụng đã chọn, mỗi trường hợp đều khác nhau, nhưng dưới đây là một số điểm chung để bắt đầu.
Mô hình dữ liệu
Mô hình dữ liệu của bạn chắc hẳn sẽ bao gồm nhiều thông tin trạng thái cùng với một số phương thức. Mô hình dữ liệu cũng có thể có các phương thức phổ biến như toString, equals và hashCode. Bạn thường có thể di chuyển các phương thức này và kiểm thử đơn vị một cách riêng biệt.
Chẳng hạn, giả sử bạn có đoạn mã Java sau đây:
public class Person {
private String firstName;
private String lastName;
// ...
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;
}
@Override
public boolean equals(Object o) {
if (this == o) return true;
if (o == null || getClass() != o.getClass()) return false;
Person person = (Person) o;
return Objects.equals(firstName, person.firstName) &&
Objects.equals(lastName, person.lastName);
}
@Override
public int hashCode() {
return Objects.hash(firstName, lastName);
}
@Override
public String toString() {
return "Person{" +
"firstName='" + firstName + '\'' +
", lastName='" + lastName + '\'' +
'}';
}
}
Bạn có thể thay thế lớp trên Java bằng một dòng trên Kotlin, như minh hoạ bên dưới:
data class Person(var firstName: String?, var lastName: String?)
Sau đó, bạn có thể kiểm thử đơn vị mã này theo bộ kiểm thử hiện tại. Hãy bắt đầu từ từ bằng lần lượt từng mô hình và di chuyển những lớp chủ yếu là trạng thái mà không phải hành vi. Hãy kiểm thử thường xuyên trong suốt quá trình di chuyển.
Di chuyển mã kiểm thử
Một nơi khác để bắt đầu là các kiểm thử: chuyển đổi các kiểm thử hiện tại và viết mã kiểm thử mới trong Kotlin. Cách này giúp nhóm của bạn có thời gian để làm quen với ngôn ngữ trước khi bạn viết mã nguồn được cung cấp qua ứng dụng.
Di chuyển các phương thức tiện ích sang hàm mở rộng
Bạn có thể biểu thị các lớp tiện ích tĩnh, chẳng hạn như StringUtils,
IntegerUtils, DateUtils, hoặc YourCustomTypeUtils, dưới dạng
các hàm mở rộng của Kotlin
và sử dụng chúng từ toàn bộ mã nguồn Java hiện tại.
Ví dụ: hãy xem xét sử dụng lớp StringUtils qua một số phương thức:
package com.java.project;
public class StringUtils {
public static String foo(String receiver) {
return receiver...; // Transform the receiver in some way
}
public static String bar(String receiver) {
return receiver...; // Transform the receiver in some way
}
}
Sau đó, các phương thức này có thể được dùng ở nơi khác trong ứng dụng của bạn, như trong ví dụ sau:
...
String myString = ...
String fooString = StringUtils.foo(myString);
...
Khi sử dụng các hàm mở rộng của Kotlin, bạn có thể cung cấp cùng một giao diện Utils cho phương thức gọi Java, đồng thời cung cấp API ngắn gọn hơn cho toàn bộ mã nguồn Kotlin mà bạn đang phát triển.
Để thực hiện việc này, bạn có thể bắt đầu bằng cách chuyển đổi lớp Utils này thành Kotlin bằng cách sử dụng lệnh chuyển đổi tự động do IDE cung cấp. Dữ liệu đầu ra có thể có dạng như trong ví dụ sau:
package com.java.project
object StringUtils {
fun foo(receiver: String): String {
return receiver...; // Transform the receiver in some way
}
fun bar(receiver: String): String {
return receiver...; // Transform the receiver in some way
}
}
Tiếp theo, hãy xoá định nghĩa lớp hoặc định nghĩa đối tượng, thêm tiền tố vào mỗi tên hàm bằng loại dữ liệu mà hàm này sẽ áp dụng, sau đó sử dụng thông tin này để tham chiếu loại trong hàm, như trong ví dụ sau:
package com.java.project
fun String.foo(): String {
return this...; // Transform the receiver in some way
}
fun String.bar(): String {
return this...; // Transform the receiver in some way
}
Cuối cùng, hãy thêm chú thích JvmName vào đầu tệp nguồn để giúp
tên đã biên dịch tương thích với phần còn lại của ứng dụng, như trong ví dụ
sau:
@file:JvmName("StringUtils")
package com.java.project
...
Phiên bản cuối cùng sẽ có dạng như sau:
@file:JvmName("StringUtils")
package com.java.project
fun String.foo(): String {
return this...; // Transform `this` string in some way
}
fun String.bar(): String {
return this...; // Transform `this` string in some way
}
Xin lưu ý rằng hiện bạn có thể gọi các hàm này bằng cách sử dụng Java hoặc Kotlin thông qua các quy ước phù hợp với từng ngôn ngữ.
Kotlin
// ... val myString: String = "hello" val fooString = myString.foo() // ...
Java
... String myString = ... String fooString = StringUtils.foo(myString); ...
Hoàn tất quá trình di chuyển
Sau khi nhóm của bạn đã thấy thoải mái với Kotlin và bạn đã di chuyển xong các phần nhỏ, thì bạn có thể chuyển sang giải quyết những thành phần lớn hơn, chẳng hạn như phân đoạn, hoạt động, đối tượng ViewModel và các lớp khác liên quan đến logic nghiệp vụ.
Những yếu tố nên cân nhắc
Giống như Java có một phong cách cụ thể, Kotlin cũng có phong cách riêng để giúp mã nguồn trở nên súc tích. Tuy nhiên, ban đầu bạn có thể thấy mã nguồn Kotlin mà nhóm của bạn tạo ra có vẻ giống với mã nguồn Java mà nhóm đang thay thế. Điều này sẽ thay đổi khi nhóm của bạn có thêm kinh nghiệm với Kotlin. Thay đổi dần dần là chìa khoá để thành công.
Dưới đây là một vài việc bạn có thể làm để duy trì tính nhất quán cho toàn bộ mã nguồn Kotlin khi phát triển:
Tiêu chuẩn lập trình phổ biến
Hãy nhớ xác định bộ quy ước lập trình ngay từ bước đầu của quá trình sử dụng. Bạn có thể làm khác hướng dẫn về quy tắc lập trình Android bằng Kotlin khi thích hợp.
Công cụ phân tích tĩnh
Thực thi bộ tiêu chuẩn lập trình đã đặt ra cho nhóm của bạn bằng cách sử dụng công cụ tìm lỗi mã nguồn Android và các công cụ phân tích tĩnh khác. ktlint, một linter Kotlin của bên thứ ba, cũng cung cấp các quy tắc bổ sung cho Kotlin.
Tích hợp liên tục
Đảm bảo tuân thủ các tiêu chuẩn lập trình thông dụng và cung cấp đầy đủ phạm vi kiểm thử cho mã nguồn Kotlin. Khi đưa cách làm này vào quy trình xây dựng tự động, bạn có thể đảm bảo tính nhất quán và tuân thủ các tiêu chuẩn này.
Khả năng tương tác
Kotlin gần như tương tác liền mạch với Java, nhưng hãy lưu ý những điểm sau.
Tính chất rỗng
Kotlin dựa vào các chú giải tính chất rỗng trong mã đã biên dịch để suy ra tính chất rỗng ở phía Kotlin. Nếu không có chú giải, Kotlin sẽ mặc định sử dụng một loại nền tảng có thể được coi là loại có thể hoặc không thể nhận giá trị rỗng. Nếu không xử lý cẩn thận các loại nền tảng, điều này có thể dẫn đến các vấn đề NullPointerException trong thời gian chạy.
Áp dụng các tính năng mới
Kotlin cung cấp nhiều thư viện mới và cú pháp dễ hiểu để giảm lượng mã nguyên mẫu, giúp tăng tốc độ phát triển ứng dụng. Tuy nhiên, hãy thận trọng và bài bản khi sử dụng các hàm thư viện chuẩn của Kotlin, chẳng hạn như hàm tập hợp, coroutine, và hàm lambda.
Đây là một cái bẫy phổ biến mà các nhà phát triển mới làm quen với Kotlin hay mắc phải. Hãy xem xét mã nguồn Kotlin sau:
val nullableFoo: Foo? = Foo() // This lambda executes only if nullableFoo is not null // and `foo` is of the non-nullable Foo type nullableFoo?.let { foo -> foo.baz() foo.zap() }
Mục đích trong ví dụ này là thực thi foo.baz và foo.zap nếu nullableFoo khác rỗng, qua đó tránh NullPointerException. Mặc dù mã này
hoạt động như dự kiến, nhưng sẽ khó đọc hơn so với mã đơn giản để kiểm tra giá trị rỗng và
truyền thông minh,
như minh hoạ trong ví dụ sau đây:
val nullableFoo: Foo? = null if (nullableFoo != null) { nullableFoo.baz() // Using !! or ?. isn't required; the Kotlin compiler infers non-nullability nullableFoo.zap() // from guard condition; smart casts nullableFoo to Foo inside this block }
Thử nghiệm
Trong Kotlin, theo mặc định, các lớp và hàm của lớp sẽ bị đóng để mở rộng. Bạn phải có mã rõ ràng để mở các lớp và hàm mà bạn muốn đưa vào lớp. Kotlin đưa ra lựa chọn này để ưu tiên việc soạn mã mới thay vì dùng lại mã cũ. Để giúp đơn giản hoá quá trình soạn mã, Kotlin đã tích hợp tính năng hỗ trợ triển khai hành vi thông qua tính năng uỷ quyền.
Hành vi này sẽ gây ra vấn đề khi mô phỏng các khung tiêu chuẩn (như Mockito) nếu khung đó dựa trên việc triển khai giao diện hoặc kế thừa mã cũ để ghi đè các hành vi trong quá trình thử nghiệm. Đối với các kiểm thử đơn vị, bạn có thể cho phép sử dụng tính năng Mock Maker Inline của Mockito để có thể mô phỏng các lớp và phương thức cuối cùng. Ngoài ra, bạn có thể sử dụng plugin biên dịch All-Open để mở lớp bất kỳ trong Kotlin và thành phần đi kèm mà bạn muốn kiểm thử trong quá trình biên dịch. Lợi thế chính của việc sử dụng plugin này là plugin hoạt động được với cả kiểm thử đơn vị và kiểm thử đo lường.
Thông tin khác
Để biết thêm thông tin về cách sử dụng Kotlin, hãy xem các đường liên kết sau:
- Phương pháp tiếp cận ưu tiên Kotlin của Android
- Các tài nguyên giúp bạn bắt đầu sử dụng mã Kotlin
- Các tài nguyên để người dùng Java học Kotlin
- Lộ trình di chuyển từ Java sang Kotlin, tập hợp các tài nguyên giúp lập trình viên Java học và viết Kotlin đúng quy ước.