استفاده از Kotlin برای تیم‌های بزرگ

رفتن به زبان جدید می‌تواند چالش‌برانگیز باشد. برای اینکه تیمتان را برای موفقیت آماده کنید، آهسته شروع کنید، در بخش‌های کوچک انتقال دهید، و مرتباً آزمایش کنید. Kotlin به بایت‌کد JVM کامپایل می‌شود و کاملاً با Java هم‌کنش‌پذیر است، که این امر انتقال را آسان‌تر می‌کند.

ساختن تیم

اولین گام قبل‌از انتقال، ایجاد درک پایه مشترک برای تیمتان است. در اینجا چند نکته آورده شده است که ممکن است برای تسریع یادگیری تیمتان مفید باشد.

تشکیل گروه‌های مطالعه

گروه‌های مطالعه روشی مؤثر برای تسهیل یادگیری و حفظ اطلاعات هستند. مطالعات نشان می‌دهد که بازگو کردن آنچه در محیط گروهی آموخته‌اید به تقویت مطالب کمک می‌کند. یک کتاب کاتلین یا سایر مطالب مطالعه را برای هر عضو گروه تهیه کنید و از گروه بخواهید هر هفته چند فصل را مرور کنند. درطول هر جلسه، گروه باید آنچه را که یاد گرفته‌اند مقایسه کنند و درباره هرگونه سؤال یا مشاهده بحث کنند.

ایجاد فرهنگ آموزش

اگرچه همه خود را معلم نمی‌دانند، اما همه می‌توانند آموزش دهند. از رهبر فناوری یا تیم گرفته تا همیار فردی، همه می‌توانند محیط یادگیری را تشویق کنند که می‌تواند به تضمین موفقیت کمک کند. یک راه برای تسهیل این امر، برگزاری ارائه‌های دوره‌ای است که در آن یک نفر از اعضای تیم برای صحبت درباره چیزی که یاد گرفته یا می‌خواهد هم‌رسانی کند، تعیین می‌شود. می‌توانید از گروه مطالعه‌تان استفاده کنید و از داوطلبان بخواهید هر هفته فصل جدیدی را ارائه دهند تا به نقطه‌ای برسید که تیمتان با زبان احساس راحتی کند.

تعیین قهرمان

درنهایت، قهرمانی را برای رهبری تلاش یادگیری تعیین کنید. این شخص می‌تواند درحین شروع فرایند پذیرش به‌عنوان متخصص موضوعی (SME) عمل کند. مهم است که این شخص را در همه جلسات تمرینی مربوط به Kotlin شرکت دهید. به‌طور ایده‌آل، این شخص ازقبل به Kotlin علاقه دارد و دانش کاری در این زمینه دارد.

ادغام تدریجی

شروع آهسته و تفکر استراتژیک درباره اینکه کدام بخش‌های اکوسیستم خود را ابتدا منتقل کنید، کلیدی است. اغلب بهتر است این کار را در یک برنامه واحد در سازمانتان انجام دهید تا در یک برنامه شاخص. ازنظر انتقال برنامه انتخابی، هر موقعیتی متفاوت است، اما در اینجا چند مکان رایج برای شروع آورده شده است.

مدل داده

مدل داده شما احتمالاً از اطلاعات وضعیت زیادی به‌همراه چند روش تشکیل شده است. مدل داده ممکن است روش‌های رایجی مانند toString، equals، و hashCode نیز داشته باشد. معمولاً می‌توانید این روش‌ها را انتقال دهید و آن‌ها را به‌صورت مجزا آزمایش واحد کنید.

برای مثال، تکه‌کد Java زیر را درنظر بگیرید:

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 + '\'' +
               '}';
   }
}

می‌توانید کلاس Java را با یک خط Kotlin جایگزین کنید، همان‌طور که در مثال زیر نشان داده شده است:

data class Person(var firstName: String?, var lastName: String?)

سپس می‌توانید این کد را دربرابر مجموعه آزمایشی کنونی‌تان آزمایش واحد کنید. با یک مدل در هر زمان شروع کنید و کلاس‌هایی را که بیشتر حالت هستند تا رفتار انتقال دهید. درطول مسیر، اغلب آزمایش کنید.

انتقال آزمایش‌ها

جای دیگری که می‌توانید شروع کنید، آزمایش‌هایتان است: آزمایش‌های موجود را تبدیل کنید و آزمایش‌های جدید را در Kotlin بنویسید. این کار به تیم شما زمان می‌دهد تا با زبان آشنا شوند پیش‌از اینکه کدی بنویسید که با برنامه‌تان ارسال می‌شود.

انتقال روش‌های ابزار به توابع افزونه

می‌توانید کلاس‌های ابزار ایستا، مانند StringUtils، IntegerUtils، DateUtils، یا YourCustomTypeUtils را به‌عنوان توابع افزونه Kotlin نمایش دهید و از آن‌ها در پایگاه کد جاوا موجود خود استفاده کنید.

برای مثال، فرض کنید کلاس StringUtils با چند روش دارید:

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
   }

}

سپس ممکن است از این روش‌ها در جای دیگری از برنامه‌تان استفاده شود، همان‌طور که در مثال زیر نشان داده شده است:

...

String myString = ...
String fooString = StringUtils.foo(myString);

...

بااستفاده از توابع افزونه Kotlin، می‌توانید همان میانای Utils را برای فراخوانندگان Java ارائه دهید و درعین‌حال میانای برنامه‌سازی کاربردی مختصرتری برای پایگاه کد Kotlin درحال رشدتان ارائه دهید.

برای انجام این کار، می‌توانید با تبدیل این کلاس Utils به Kotlin بااستفاده از تبدیل خودکار ارائه‌شده توسط IDE شروع کنید. برونداد نمونه ممکن است شبیه به موارد زیر باشد:

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
   }

}

سپس، تعریف کلاس یا شیء را بردارید، پیشوند هر نام تابع را با نوعی که این تابع باید بر آن اعمال شود مشخص کنید، و از این برای ارجاع به نوع داخل تابع استفاده کنید، همان‌طور که در مثال زیر نشان داده شده است:

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
}

در آخر، یک گزارمان JvmName به بالای فایل منبع اضافه کنید تا نام ترجمه‌شده با بقیه برنامه‌تان سازگار شود، همان‌طور که در مثال زیر نشان داده شده است:

@file:JvmName("StringUtils")
package com.java.project
...

نسخه نهایی باید شبیه به تصویر زیر باشد:

@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
}

توجه داشته باشید که اکنون می‌توان این توابع را بااستفاده از جاوا یا Kotlin با قراردادهایی که با هر زبان مطابقت دارد فراخوانی کرد.

کاتلین

// ...

val myString: String = "hello"
val fooString = myString.foo()

// ...

جاوا

...
String myString = ...
String fooString = StringUtils.foo(myString);
...

تکمیل انتقال

پس‌از اینکه تیم شما با Kotlin راحت شد و بخش‌های کوچک‌تر را انتقال دادید، می‌توانید به مؤلفه‌های بزرگ‌تر مانند قطعه‌ها، فعالیت‌ها، ViewModel اشیا، و کلاس‌های دیگر مربوط به منطق کسب‌وکار بروید.

ملاحظات

همان‌طور که Java سبک خاصی دارد، Kotlin نیز سبک اصطلاحی خاص خود را دارد که به مختصر بودن آن کمک می‌کند. بااین‌حال، در ابتدا ممکن است متوجه شوید که کد Kotlin که تیمتان می‌نویسد بیشتر شبیه کد Java است که جایگزین آن می‌شود. این با کسب تجربه تیم شما در Kotlin تغییر می‌کند. تغییر تدریجی کلید موفقیت است.

در اینجا چند کار که می‌توانید برای حفظ یکپارچگی پایگاه کد Kotlin خود درحین رشد آن انجام دهید آورده شده است:

استانداردهای کدنویسی مشترک

حتماً در اوایل فرایند پذیرش، مجموعه استانداردی از قراردادهای کدنویسی را تعریف کنید. درصورت لزوم می‌توانید از راهنمای سبک Kotlin در Android پیروی نکنید.

ابزارهای تجزیه‌وتحلیل ایستا

بااستفاده از Android lint و دیگر ابزارهای تحلیل ایستایی، استانداردهای کدنویسی تعیین‌شده برای تیمتان را اعمال کنید. ktlint، یک linter شخص ثالث Kotlin، قوانین اضافه‌ای برای Kotlin ارائه می‌دهد.

یکپارچه‌سازی مداوم

حتماً از استانداردهای رایج کدنویسی پیروی کنید و پوشش آزمایشی کافی برای کد Kotlin خود ارائه دهید. تبدیل این به بخشی از فرایند ساخت خودکار می‌تواند به اطمینان از ثبات و رعایت این استانداردها کمک کند.

هم‌کنش‌پذیری

‫Kotlin در بیشتر موارد به‌طور یکپارچه با Java تعامل‌پذیر است، اما نکات زیر را درنظر داشته باشید.

قابلیت تهی بودن

‫Kotlin برای استنباط تهی‌پذیری در سمت Kotlin به گزارمان‌های تهی‌پذیری در کد کامپایل‌شده متکی است. اگر گزارمان ارائه نشود، Kotlin به‌طور پیش‌فرض از نوع پلاتفرمی استفاده می‌کند که می‌تواند هم تهی‌پذیر و هم تهی‌ناپذیر درنظر گرفته شود. اگر انواع پلاتفرم را با دقت مدیریت نکنید، این امر می‌تواند منجر به مشکلات زمان اجرا NullPointerException شود.

استفاده از ویژگی‌های جدید

Kotlin تعداد زیادی کتابخانه جدید و قند نحوی برای کاهش کد قالبی ارائه می‌دهد که به افزایش سرعت توسعه کمک می‌کند. بااین‌حال، هنگام استفاده از توابع کتابخانه استاندارد Kotlin، مانند توابع مجموعه، کوروتین‌ها، و لامبداها، احتیاط و روش‌مندی را رعایت کنید.

در اینجا تله رایجی وجود دارد که توسعه‌دهندگان تازه‌کار Kotlin با آن مواجه می‌شوند. کد Kotlin زیر را درنظر بگیرید:

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()
}

هدف در این مثال اجرای foo.baz و foo.zap است اگر nullableFoo تهی نباشد، بنابراین از NullPointerException اجتناب می‌شود. اگرچه این کد طبق انتظار کار می‌کند، اما خواندن آن نسبت‌به بررسی تهی و تبدیل هوشمند، همان‌طور که در مثال زیر نشان داده شده است، کمتر شهودی است:

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
}

آزمایش

در Kotlin، کلاس‌ها و توابع آن‌ها به‌طور پیش‌فرض برای افزونه بسته هستند. باید کلاس‌ها و توابعی را که می‌خواهید زیرکلاس کنید به‌طور صریح باز کنید. Kotlin این انتخاب را برای ترویج ترکیب‌بندی به‌جای وراثت انجام می‌دهد. برای کمک به ساده‌سازی ترکیب، Kotlin از پیاده‌سازی رفتار ازطریق واگذاری پشتیبانی داخلی دارد.

این رفتار برای چارچوب‌های شبیه‌سازی، مانند Mockito، که برای لغو کردن رفتارها درطول آزمایش به پیاده‌سازی رابط یا وراثت متکی هستند، مشکل ایجاد می‌کند. برای آزمایش‌های واحد، می‌توانید استفاده از ویژگی Mock Maker Inline Mockito را فعال کنید که به شما امکان می‌دهد کلاس‌ها و روش‌های نهایی را شبیه‌سازی کنید. یا می‌توانید از افزونه کامپایلر All-Open برای باز کردن هر کلاس Kotlin و اعضای آن که می‌خواهید به‌عنوان بخشی از فرایند کامپایل آزمایش کنید استفاده کنید. مزیت اصلی استفاده از این افزایه این است که با هر دو نوع آزمایش واحد و ابزاری کار می‌کند.

اطلاعات بیشتر

برای اطلاعات بیشتر درباره استفاده از Kotlin، پیوندهای زیر را ببینید: