استخدام لغة Kotlin للفرق الكبيرة

قد يكون الانتقال إلى أي لغة جديدة مهمة شاقة. وصفة النجاح هي والبدء ببطء، والتحرك على شكل أجزاء، والاختبار بشكل متكرر لمواءمة فريقك لتحقيق النجاح. تجعل Kotlin عملية الترحيل أمرًا سهلاً، حيث إنها تتحول إلى رمز بايت JVM يمكن التفاعل معه بشكل كامل مع Java.

بناء الفريق

تتمثل الخطوة الأولى قبل الترحيل في بناء فهم أساسي مشترك فريقك. فيما يلي بعض النصائح التي قد تجدها مفيدة لتسريع تعلم فريق العمل.

تشكيل مجموعات دراسة

تُعد مجموعات الدراسة طريقة فعالة لتسهيل التعلّم والاحتفاظ بالمستخدمين. تقترح الدراسات أن سرد ما تعلمته في إعداد المجموعة يساعد على وتعزيز المواد. احصل على كتاب Kotlin أو غير ذلك لكل عضو من أعضاء المجموعة، وتطلب من المجموعة إجراء فصلين كل أسبوع. خلال كل اجتماع، يجب على المجموعة مقارنة التي تعلموها ويناقشون أي أسئلة أو ملاحظات.

بناء ثقافة التعليم

لا يعتبر الجميع أنفسهم معلمين، ولكن بإمكان الجميع التدريس. بدءًا من التكنولوجيا أو الفريق وصولاً إلى مساهم فردي، يمكن للجميع وشجع بيئة تعليمية يمكن أن تساعد في ضمان النجاح. من بين طرق تسهيل ذلك وهو إجراء عروض تقديمية دورية حيث يكون هناك شخص واحد في الفريق مخصص للحديث عن شيء تعلموه أو يريدون مشاركته. يمكنك الاستفادة من مجموعة الدراسة من خلال مطالبة المتطوعين بتقديم فصل جديد في كل أسبوع حتى تصل إلى مرحلة يشعر فيها فريقك بالراحة تجاه .

اختَر بطلاً لا يُقهر

وأخيرًا، قم بتعيين بطل لقيادة جهود التعلم. يمكن لهذا الشخص أن يتصرف خبير مختص (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 واستخدامها بواسطة قاعدة رموز 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 نفسها ويوفر المتصلون في 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
}

لاحظ أنه يمكن الآن استدعاء هذه الدوال باستخدام Java أو Kotlin مع الاصطلاحات التي تتطابق مع كل لغة.

Kotlin

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

Java

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

إكمال نقل البيانات

وبعد أن يشعر فريقك بالارتياح تجاه استخدام Kotlin وترقية مناطق أصغر، يمكنك الانتقال إلى معالجة مكونات أكبر مثل الأجزاء والأنشطة عناصر ViewModel، وفئة أخرى مرتبطة بمنطق الأعمال.

الاعتبارات

وكما هي الحال في لغة Java، فإن لغة Kotlin لها أسلوبها الخاص في التعبير إلى إيجازها. ومع ذلك، قد تجد في البداية أن يبدو رمز Kotlin الذي ينتجه فريقك أشبه برمز Java الذي يحل محله. يتغير هذا الأمر بمرور الوقت مع نمو تجربة Kotlin لفريقك. تذكر، التدريجي التغيير هو مفتاح النجاح.

إليك بعض الأشياء التي يمكنك تنفيذها لتحقيق الاتساق كقاعدة رموز Kotlin الخاصة بك ينمو:

معايير الترميز الشائعة

تأكد من تحديد مجموعة قياسية من اصطلاحات البرمجة في وقت مبكر من اعتمادك الدفع. يمكنك الابتعاد عن نظام Android دليل أسلوب Kotlin إذا كان ذلك منطقيًا.

أدوات التحليل الثابت

فرض معايير البرمجة المحددة لفريقك باستخدام Android Lint وأدوات التحليل الثابتة الأخرى. klint، وهي جهة خارجية بلغة Kotlin كما يوفر أيضًا قواعد إضافية للغة Kotlin.

التكامل المستمر

التأكد من التوافق مع معايير الترميز الشائعة، وتوفير الاختبارات الكافية الخاصة بأكواد Kotlin. جعل هذا الجزء من عملية إنشاء آلية يمكن أن يساعد في ضمان الاتساق والالتزام بهذه المعايير.

إمكانية التشغيل التفاعلي

تتفاعل Kotlin مع Java بسلاسة في الغالب، ولكن لاحظ المتابعة.

القابلية للإلغاء

تعتمد لغة Kotlin على التعليقات التوضيحية للقيم الفارغة في التعليمات البرمجية المجمّعة لاستنتاج إمكانية قبول القيم الفارغة. من جانب Kotlin. إذا لم تتوفر تعليقات توضيحية، يتم ضبط Kotlin تلقائيًا على نوع النظام الأساسي الذي يمكن التعامل معه على أنّه نوع قابل للقيم الفارغة أو غير قابل للقيم. هذا النمط قد تؤدي إلى حدوث مشاكل NullPointerException في وقت التشغيل، ما لم يتم معالجتها بعناية.

استخدام ميزات جديدة

توفر لغة Kotlin الكثير من مكتبات جديدة والسكر التركيبي لتقليل النص النموذجي، ما يساعد على زيادة النمو السرعة. ومع ذلك، كن حذرًا ومنهجيًا عند استخدام لغة البرمجة Kotlin. دوال المكتبة، مثل دوال التجميع كوروتين، وlambdas

هذا فخ شائع جدًا يواجهه مطورو Kotlin الجدد. افترض أن التعليمات البرمجية التالية بلغة Kotlin:

val nullableFoo: 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، والتي تتيح لك محاكاة الفئات والأساليب النهائية. وبدلاً من ذلك، يمكنك استخدام المكوّن الإضافي لبرنامج التجميع الكامل المفتوح فتح أي فئة في Kotlin وأعضائها الذين تريد اختبارهم كجزء من التحويل البرمجي. الميزة الأساسية لاستخدام هذا المكون الإضافي هي أنه يعمل من خلال اختبارات الوحدة والأجهزة.

مزيد من المعلومات

للحصول على مزيد من المعلومات حول استخدام Kotlin، يمكنك الاطلاع على الروابط التالية: