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

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

ساختن تیم

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

گروه‌های مطالعه فرم

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

ایجاد فرهنگ تدریس

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

قهرمانی را تعیین کنید

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

ادغام تدریجی

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

مدل داده

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

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

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 نمایش داده شود و توسط پایگاه کد Java موجود شما استفاده شود.

برای مثال، درنظر بگیرید که کلاس 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 را برای فراخوان‌های جاوا ارائه دهید و درعین‌حال یک API کوتاه‌تر برای پایگاه کد 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 و دیگر ابزارهای تحلیل ایستایی، استانداردهای کدنویسی تعیین‌شده برای تیمتان را اعمال کنید. klint، یک 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 برای پیاده‌سازی رفتار ازطریق واگذاری پشتیبانی داخلی دارد تا به ساده‌سازی ترکیب کمک کند.

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

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

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