مهاجرت از Groovy به کاتلین DSL
ﺯﻣﺎﻥ ﻣﻄﺎﻟﻌﻪ: 5 دقیقه

مهاجرت از Groovy به کاتلین DSL

برای انعطاف‌پذیری بهتر، اسکریپت‌های ساخت(build) خود را به کاتلین DSL تغییر دهید.در این پست توضیح می‌دهیم که DSL چیست و همچنین مهاجرت از Groovy به کاتلین DSL را انجام می‌دهیم.

مقدمه

در اندروید استودیو فایل‌های ساخت گریدل در ساختار پروژه به طور پیش‌فرض از زبان ساخت Groovy استفاده می‌کند. ما اصولا وابستگی‌ها، پلاگین‌ها، تنظیمات پروژه و غیره را در فایل‌های گریدل خود تعریف می‌کنیم. از آنجایی که ما مشغول کارهای توسعه و جدول زمانی خود هستیم، برای شناخت بیشتر آن‌ها زمانی اختصاص نمی‌دهیم. نوشتن کد در این فایل‌ها هیجان انگیز به نظر نمی‌رسد، زیرا ما مهارت کافی با  Groovy را نداریم.

DSL چیست؟

DSL مخفف Domain Specific Language است که می‌تواند در یک حوزه خاص استفاده شود. این مخالف زبان‌های عمومی(GPL) مانند جاوا است که به طور گسترده‌ای قابل استفاده است یا برای چندین دامنه استفاده می‌شود. این به ما کمک می‌کند که برای کارهای تکراری کدهای اعلانی بنویسیم. خواندن کدی که با DSL نوشته شده است بسیار ساده‌تر است.

متداول‌ترین استفاده از زبان DSL، HTML در توسعه وب، Gradle در ابزار ساخت، SQL در مدیریت داده‌ها، XML در زبان نشانه‌گذاری و ... است. اگر چه ممکن است با یک یا چند مورد ذکر شده تجربه داشته باشیم ولی ممکن است ندانیم در حال استفاده از DSL هستیم.

گریدل

گریدل یک ابزار ساخت قدرتمند است که یک DSL برای توصیف اسکریپت‌های ساخت ارائه داده است. گریدل برای توصیف ساخت از Groovy و کاتلین DSL پشتیبانی می‌کند. یک اسکریپت ساخت Groovy می‌تواند شامل هر عنصر زبان Groovy باشد. همچنین اسکریپت ساخت کاتلین نیز می‌تواند شامل هر عنصر زبان کاتلین باشد.

از آنجا که بیشتر ما از کاتلین برای توسعه استفاده می‌کنیم، تهیه  اسکریپت‌های ساخت در کاتلین آسان و انعطاف‌پذیرتر  از Groovy است. اکنون بیایید به جزئیات کاتلین DSL برویم.

کاتلین DSL

کاتلین DSL در بالای هسته زبان کاتلین ساخته شده است. بنابراین سینتکس آن با زبان اصلی تفاوتی ندارد و مزیت استفاده از کاتلین برای توسعه را به ما می‌دهد. کاتلین DSL به طور کامل در اندروید استودیو پشتیبانی می‌شود.

نکته: Gradle Kotlin DSL یک سینتکس جایگزین برای Groovy DSL سنتی با ویرایش پیشرفته در IDE پشتیبانی شده، با کمک محتوای بهتر، مستند سازی و موارد دیگر ارائه می‌کند. تیم Gradle.

ما با انتخاب کاتلین DSL به جای Groovy می‌توانیم مزایای زیر را داشته باشیم:

  1. خوانایی بهتر
  2. سینتکس آن به راحتی از زبان مادر قابل انطباق است
  3. مسیریابی کد و پیشنهادات خودکار
  4. خطاهای زمان کامپایل
  5. در حال حاضر برای دستیابی به وابستگی‌ها و پیکربندی artifactها، source set و غیره از type-safe مدل‌ها پشتیبانی می‌کند

اما ممکن است در برخی شرایط  مانند clean، تغییرات مربوط به دایرکتوری buildSrc و غیره، کمی کندتر باشد.

مهاجرت کردن اسکریپت‌های ساخت از Groovy به Kotlin

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

از مستندات gradle

  • رشته‌های groovy را می‌توان با نقل قول‌های تکی ‘string’ یا دوتایی “string” نقل کرد، در حالی که کاتلین به نقل قول‌های دوتایی نیاز دارد “string”.
  • Groovy اجازه می‌دهد هنگام استفاده از توابع از پرانتز استفاده نکنید درحالیکه کاتلین همیشه به پرانتز نیاز دارد.
  • Gradle Groovy DSL اجازه می‌دهد تا عملگر انتساب(=) را هنگام اختصاص خصوصیات حذف کنید، درحالیکه کاتلین همیشه به عملگر انتساب نیاز دارد.

بیایید با تبدیلات شروع کنیم و در این پست فایل build.gradle و setting.gradle را به gradle.kts تبدیل کنیم.

اول از همه فایل‌های .gradle را به .gradle.kts تغییر نام دهید (فایل‌های groovy DSL از پسوند .gradle و فایل‌های کاتلین DSL از پسوند .gradle.kts استفاده می‌کنند)

قدم اول

بیایید setting.gradle را به setting.gradle.kts تبدیل کنیم.

//Before
include ':app', ':sampleModule'

//After
include(":app", ":sampleModule")

قدم دوم

اکنون بیایید build.gradle در سطح پروژه را به build.gradle.kts تبدیل کنیم. ریشه پیش‌فرض یا build.gralde در سطح پروژه به صورت زیر نمایش داده می‌شود.

// Top-level build file where you can add configuration options common to all sub-projects/modules.
buildscript {
    ext.kotlin_version = "1.5.0"
    repositories {
        google()
        mavenCentral()
    }
    dependencies {
        classpath "com.android.tools.build:gradle:4.2.1"
        classpath "org.jetbrains.kotlin:kotlin-gradle-plugin:$kotlin_version"

        // NOTE: Do not place your application dependencies here; they belong
        // in the individual module build.gradle files
    }
}

allprojects {
    repositories {
        google()
        mavenCentral()
        jcenter() // Warning: this repository is going to shut down soon
    }
}

task clean(type: Delete) {
    delete rootProject.buildDir
}

همانطور که مشاهده می‌کنیم قسمت اولیه کد، تعیین متغییر است.

ext.kotlin_version = "1.5.0"

که به کد زیر تغییر داده می‌شود.

val kotlin_version = "1.5.0"

با رد کردن قسمت مخازن به قسمت classpath می‌رویم، که توابعی برای افزودن وابستگی به اسکریپت با استفاده از classpath تعیین می‌کنیم.

classpath "com.android.tools.build:gradle:4.2.1"
classpath "org.jetbrains.kotlin:kotlin-gradle-plugin:$kotlin_version"

اما با استفاده از کاتلین DSL، تعیین توابع به صورت زیر است.

classpath ("com.android.tools.build:gradle:4.2.1")
classpath ("org.jetbrains.kotlin:kotlin-gradle-plugin:$kotlin_version")

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

// Top-level build file where you can add configuration options common to all sub-projects/modules.
buildscript {
    val kotlin_version = "1.5.0"
    repositories {
        google()
        mavenCentral()
    }
    dependencies {
        classpath ("com.android.tools.build:gradle:4.2.1")
        classpath ("org.jetbrains.kotlin:kotlin-gradle-plugin:$kotlin_version")

        // NOTE: Do not place your application dependencies here; they belong
        // in the individual module build.gradle files
    }
}

allprojects {
    repositories {
        google()
        mavenCentral()
        jcenter() // Warning: this repository is going to shut down soon
    }
}

tasks.register("clean", Delete::class){
    delete(rootProject.buildDir)
}

همانطور که کار فایل gradle در سطح پروژه تمام شد، اجازه دهید به فایل gradle در سطح برنامه برویم.

قدم سوم

حال باید build.gradle در سطح برنامه را به build.gradle.kts تبدیل کنیم. به صورت پیش‌فرض build.gradle در سطح برنامه ایجاد می‌شود، که محتوای آن همانند زیر است.

plugins {
    id 'com.android.application'
    id 'kotlin-android'
}

android {
    compileSdkVersion 30
    buildToolsVersion "30.0.3"

    defaultConfig {
        applicationId "com.sample.myapplication"
        minSdkVersion 21
        targetSdkVersion 30
        versionCode 1
        versionName "1.0"

        testInstrumentationRunner "androidx.test.runner.AndroidJUnitRunner"
    }

    buildTypes {
        release {
            minifyEnabled false
            proguardFiles getDefaultProguardFile('proguard-android-optimize.txt'), 'proguard-rules.pro'
        }
    }
    compileOptions {
        sourceCompatibility JavaVersion.VERSION_1_8
        targetCompatibility JavaVersion.VERSION_1_8
    }
    kotlinOptions {
        jvmTarget = '1.8'
    }
}

dependencies {
    implementation 'androidx.core:core-ktx:1.5.0'
    implementation 'androidx.appcompat:appcompat:1.3.0'
    implementation 'com.google.android.material:material:1.3.0'
    implementation 'androidx.constraintlayout:constraintlayout:2.0.4'
    testImplementation 'junit:junit:4.+'
    androidTestImplementation 'androidx.test.ext:junit:1.1.2'
    androidTestImplementation 'androidx.test.espresso:espresso-core:3.3.0'
}

پس از تبدیل، محتوای آن همانند زیر است.

plugins {
    id("com.android.application")
    kotlin("android")
}

android {
    compileSdkVersion(30)
    buildToolsVersion("30.0.3")

    defaultConfig {
        applicationId = "com.sample.dsl"
        minSdkVersion(21)
        targetSdkVersion(30)
        versionCode = 1
        versionName = "1.0"

        testInstrumentationRunner = "androidx.test.runner.AndroidJUnitRunner"
    }

    buildTypes {
        getByName("release") {
            isMinifyEnabled = false
            proguardFiles(
                getDefaultProguardFile("proguard-android-optimize.txt"),
                "proguard-rules.pro"
            )
        }
    }
    compileOptions {
        sourceCompatibility = JavaVersion.VERSION_1_8
        targetCompatibility = JavaVersion.VERSION_1_8
    }
    tasks.withType<org.jetbrains.kotlin.gradle.tasks.KotlinCompile> {
        kotlinOptions {
            jvmTarget = "1.8"
        }
    }
}

dependencies {
    implementation("androidx.core:core-ktx:1.5.0")
    implementation("androidx.appcompat:appcompat:1.3.0")
    implementation("com.google.android.material:material:1.3.0")
    implementation("androidx.constraintlayout:constraintlayout:2.0.4")
    testImplementation("junit:junit:4.+")
    androidTestImplementation("androidx.test.ext:junit:1.1.2")
    androidTestImplementation("androidx.test.espresso:espresso-core:3.3.0")
}

کم و بیش هر دو شبیه به هم هستند اما فایل‌های کاتلین می‌توانند خوانایی بهتری داشته باشند. که تغییرات جزئی در آن ایجاد شده است:

  • مانند نوع انتشار، باید از getByName(“release”) به جای release استفاده کنیم
  • و تخصیص مقادیر، مانند versionCode = 1 به جای versionCode 1
  • برای خصوصیاتی مانند minifyEnabled تغییر نام نیز وجود دارد که به جای آن از isMinifyEnabled استفاده می‌کنیم

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

خلاصه

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

منبع

چه امتیازی برای این مقاله میدهید؟

خیلی بد
بد
متوسط
خوب
عالی
در انتظار ثبت رای

9 ماه پیش
کاتلین
DSL
Groovy
/@pouryasharifi78
پوریا شریفی
توسعه‌دهنده‌ی اندروید

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

دیدگاه و پرسش

برای ارسال دیدگاه لازم است وارد شده یا ثبت‌نام کنید

ورود یا ثبت‌نام

در حال دریافت نظرات از سرور، لطفا منتظر بمانید

در حال دریافت نظرات از سرور، لطفا منتظر بمانید

پوریا شریفی

توسعه‌دهنده‌ی اندروید