Boilerplate — bu proqramçıların hər yeni modul və ya layihədə minimal dəyişikliklərlə yazdıqları şablon koddur. O, unikal biznes məntiqi ehtiva etmir, sadəcə infrastrukturu hazırlayır: konfiqurasiya, kitabxanaların qoşulması, standart işləyicilər və DTO sinifləri. CodeScene Engineering Productivity Report (2025) tədqiqatına görə, boilerplate tipik kommersiya tətbiqində bütöv kodun 20 ilə 40 faizini təşkil edir. Əsas problem belə kodun təkrarlanması deyil, hər təkrarlamanın bir uğursuzluq nöqtəsi olmasıdır: bir nüsxədəki səhv digərləri ilə sinxronlaşmır və səhvlər layihə boyu yayılır. Kod generasiyası, annotasiyalar və makrolar vasitəsilə boilerplate-in avtomatlaşdırılması keyfiyyət itkisi olmadan inkişafı sürətləndirməyin ən təsirli yollarından biridir.
Əsas məqamlar
Boilerplate (şablon kod) — layihənin müxtəlif hissələrində minimal dəyişikliklərlə təkrarlanan mənbə kodu fraqmentləridir. Termin mətbəə işindən gəlir, burada boilerplate qəzetlər üçün yenidən yazılması tələb olunmayan şablon mətnlər adlanırdı. Proqramlaşdırmada bu, freymvorkun, dilin və ya arxitekturanın tələblərini ödəmək üçün təkrar-təkrar yazmalı olduğunuz istənilən koddur.
Boilerplate klassik mənada texniki borc deyil — o, səhvlər ehtiva etmir və SOLID prinsiplərini pozmur. Bununla belə, o, dəstəklənməli, test edilməli və oxunmalı olan kodun həcmini artırır. Hər bir boilerplate sətri kompilatorun həmişə tuta bilmədiyi potensial səhv yeridir.
JetBrains Developer Ecosystem (2025) hesabatına görə, proqramçıların 67 faizi boilerplate-i məhsuldarlığın azalmasının əsas səbəbi hesab edir. Mobil inkişafda bu rəqəm daha yüksəkdir: Java-da Android layihələri findViewById, Intent-lər, RecyclerView adapterləri və ContentProvider-lər üçün əhəmiyyətli miqdarda şablon kod ehtiva edir. Kotlin və Swift bu problemlərin bir hissəsini sintaktik vasitələrlə həll etdi, lakin boilerplate tamamilə yox olmadı.
Arxitekturanı layihələşdirərkən, şablon kodu minimuma endirən həlləri seçməyə çalışın. Məsələn, əl ilə Parcelable tətbiqi yazmaq əvəzinə Kotlin-də @Parcelize istifadə edin. ViewModel üçön fabriklər əvəzinə — @HiltViewModel ilə Hilt. Hər belə optimallaşdırma layihə miqyasında saatlarla iş vaxtına qənət etdirir.
Android inkişafında ən tanınan boilerplate nümunəsi RecyclerView.Adapter-dir. Kotlin və ViewBinding meydana çıxmamışdan əvvəl, hər adapter təxminən 80–100 sətir şablon kod tələb edirdi: onCreateViewHolder, onBindViewHolder, getItemCount, daxili ViewHolder sinfi, konstruktor, sahə bağlantısı. ViewBinding ilə kod qısaldı, lakin tamamilə yox olmadı.
class UserAdapter(
private val users: List<User>
) : RecyclerView.Adapter<UserAdapter.ViewHolder>() {
override fun onCreateViewHolder(
parent: ViewGroup,
viewType: Int
): ViewHolder {
val view = LayoutInflater
.from(parent.context)
.inflate(R.layout.item_user, parent, false)
return ViewHolder(view)
}
override fun onBindViewHolder(
holder: ViewHolder,
position: Int
) {
holder.bind(users[position])
}
override fun getItemCount(): Int = users.size
class ViewHolder(itemView: View) :
RecyclerView.ViewHolder(itemView) {
fun bind(user: User) {
Glide.with(itemView)
.load(user.avatarUrl)
.into(itemView.avatar)
}
}
}
Digər göstəricili nümunə — kitabxanasız Java-da JSON xəritələməsidir. API cavabının əl ilə pars edilməsi hər biri açarın varlığını yoxlayan, dəyəri alan və sahəyə təyin edən onlarla metodun yazılmasını tələb edir. Gson, Moshi və ya Kotlin Serialization kimi kitabxanalarla — bu, bir @Serializable annotasiyasıdır.
iOS inkişafında klassik boilerplate — hər API cavabı üçün CodingKey və Decodable tətbiqi, xüsusən də JSON açarları xassələrin camelCase adlarından fərqləndikdə. Codable-in avtomatik generasiyasına baxmayaraq, CodingKeys-in əl ilə sadalanması şablon kod mənbəyi olaraq qalır.
Quraşdırma mərhələsində boilerplate yaratmaq üçün kod generasiyasından istifadə edin. Android-də — Room, Dagger, Moshi üçün Annotation Processing (KSP). iOS-da — Codable və AutoMockable üçün Sourcery. Generasiyanın qurulmasına sərf edilən hər saata görə, əl ilə kopyalamadan günlərə qənət edirsiniz.
Boilerplate layihəyə üç şəkildə zərər verir: yeni funksionallığın yazılmasını yavaşaldır, mövcud kodun oxunmasını çétinləşdirir və dəyişikliklər zamanı desinxronizasiya nöqtələri yaradır.
Inkişafın yavaşlaması aŗkardır: proqramçı biznes məntiqi ehtiva etməyən kod yazmağa vaxt sərf edir. Yeni funksiya tətbiq etmək əvəzinə (məsələn, istifadəçi profilinə sahə əlavə etmək), o, verilənlər bazası miqrasiyası, DTO sinfi, domenda varlığa mapper, giriş sahəsi olan ekran, validasiya və hər təbəqə üçün testlər yazır. Bu işin böyük hissəsi mexanikidir.
Desinxronizasiya daha mürəkkəb problemdir. Bir yerdə verilən strukturun dəyişməsi (məsələn, API cavabına sahə əlavə edilməsi) proqramçının DTO-nu, mapper-i, modeli, ekranı və testləri yeniləməsini tələb edir. Yerlərdən biri buraxılarsa, tətbiq kompilyasiya olunur, lakin iş zamanı çökür və ya — daha pisi — səhvsiz yanlış məlumat göstərir. Boilerplate təbəqələri nə qədər çox olarsa, belə desinxronizasiya ehtimalı da bir o qədər yüksəkdir.
Layihəni təkrarlanan nümunələr baxımından təhlil edin. Fərqli adlarla üç eyni sinif görürsünüzsə — bu generasiya üçün namizəddir. Kod generasiyasını bir dəfəlik optimallaşdırma kimi deyil, arxitektura qərarının bir hissəsi kimi tətbiq edin. Bu, hər yeni modulda özünü doğruldur.
Kod generasiyası — boilerplate ilə mübarizənin ən etibarlı üsuludur. Əl ilə şablon kod yazmaq əvəzinə, proqramçı metadata (annotasiyalar, sxemlər, konfiqurasiyalar) təsvir edir və generator kompilyasiya mərhələsində hazır kod yaradır.
Android ekosistemində standart kod generasiyası vasitəsi KSP-dir (Kotlin Symbol Processing). Köhnəlmiş KAPT-əd əvəz edir və Java stubları yaratmadan Kotlin AST-’yə birbaşa çıxış sayəsində daha sürətli işləyir. KSP Room (DAO tətbiqlərinin generasiyası), Moshi (JsonAdapter generasiyası), Glide (hədəf yükləmə siniflərinin generasiyası) və Dagger (DI qrafının generasiyası) tərəfindən istifadə olunur.
@Entity(tableName = "users")
data class UserEntity(
@PrimaryKey val id: Long,
@ColumnInfo(name = "full_name") val name: String,
@ColumnInfo(name = "avatar_url") val avatarUrl: String
)
@Dao
interface UserDao {
@Query("SELECT * FROM users WHERE id = :id")
suspend fun getById(@Param("id") id: Long): UserEntity?
}
iOS inkişafında kod generasiyası rolunu Sourcery oynayır — Stencil şablonlarını emal edən və şərhlərdəki annotasiyalar əsasında Swift kodu yaradan vasitə. Tipik ssenarilər: AutoMockable (testlər üçün mockların generasiyası), AutoCodable (CodingKeys olmadan Decodable tətbiqinin generasiyası), AutoEquatable və AutoLenses.
Flutter layihələri üçün boilerplate build_runner vasitəsilə generatorlar tərəfindən azaldılır: JSON xəritələməsi üçün json_serializable, copyWith ilə dəyişməz modellər üçün freezed, API müştəriləri üçün retrofit_generator və DI üçün injectable_generator. Bu generatorların hər biri 10–20 sətir annotasiyanı yüzlərlə sətir hazır koda çevirir.
Annotasiyalar və makrolar — kompilyatora və ya preprosesora hansı kodun yaradılması lazım olduğunu göstərməyin deklarativ üsuludur. Proqramçı tətbiqi yazmır, sadəcə niyyəti qeyd edir və generator işarələri hazır koda çevirir.
Ən parlaq nümunə — Java-da Lombok (tarixən) və Kotlin data class. Kotlin-də data class avtomatik olaraq equals, hashCode, toString, componentN və copy yaradır — Java-da bu, əl ilə təxminən 80 sətir kod və ya @Data ilə Lombok istifadəsini tələb edirdi. Kotlin problemi dil səviyyəsində həll edərək boilerplate-i gizli etdi.
Swift-də oxşar rolu makrolar (Swift 5.9-da təqdim olunan Swift Macros) oynayır. Codable tətbiqini əl ilə yazmaq əvəzinə, proqramçı strukturu @Codable ilə qeyd edir — və kompilyator özü lazımlı kodu yaradır. Digər daxili makrolar: @Observable (müşahidə olunan vəziyyət), @ResultBuilder (nəticə qurucuları) və @MainActor (əsas axına göndərmə).
@Codable
struct UserProfile {
let id: Int
let displayName: String
let avatarURL: URL
let bio: String?
}
// @Codable makro generasiya edir:
// extension UserProfile: Codable { }
// private enum CodingKeys: String, CodingKey {
// case id, displayName, avatarURL, bio
// }
Kod generasiyası ilə makrolar arasında seçim edərkən, dil dəstək edirsə, makrolara üstünlük verin. Makrolar kompilyator səviyyəsində işləyir, build-skriptlərin qurulmasını tələb etmir, kompilyasiyanı yavaşlatmır (Annotation Processing-ən fərqli olaraq) və həmişə mənbə kodu ilə sinxronlaşdırılır. Makrolar mövcud deyilsə — KSP, Sourcery və ya build_runner vasitəsilə xarici generatorlardan istifadə edin.
Hər dil və platforma boilerplate-i minimuma endirmək üçün öz vasitələrini təklif edir. Aşağıda mobil inkişafın əsas yığımları üçün konkret təcrübələr verilmişdir.
| Platforma | Vasitə / Texnika | Nəyi əvəz edir |
|---|---|---|
| Android / Kotlin | data class | equals, hashCode, toString, copy, componentN |
| Android / Kotlin | @Parcelize | Parcelable tətbiqi |
| Android / Kotlin | ViewBinding / DataBinding | findViewById, ButterKnife |
| iOS / Swift | Codable + makrolar | Əl ilə JSON pars etmə, CodingKeys |
| iOS / Swift | Sourcery | AutoMockable, AutoEquatable, AutoLenses |
| Flutter / Dart | freezed + json_serializable | copyWith, sealed siniflər, equals/hashCode, JSON |
| Flutter / Dart | retrofit_generator | Sorğu və cavab tipləri ilə API müştərisi |
Veb frontendi üçün (React Native / TypeScript) əsas vasitə OpenAPI spesifikasiyasından tiplərin generasiyasıdır (openapi-typescript, swagger-codegen). Hər endpoint avtomatik olaraq tipli sorğu və cavab alır — proqramçı yüzlərlə API çağırışı üçün interfeysləri əl ilə təsvir etməli deyil.
Kod generasiyasını layihənin ilkin mərhələlərində tətbiq edin. Mövcud layihəni generatorlara köçürmək sıfırdan layihələşdirmədən daha çətindir. Layihə artıq yazılıbsa — ən ağrılı nöqtədən başlayın: Java → Kotlin (data class), əl adapterləri → DiffUtil ilə ListAdapter, əl JSON xəritələməsi → Moshi / Kotlin Serialization.
Tez-tez verilən suallar
Boilerplate borc deyil, artıqlıqdır: kod düzgündür, lakin onun çoxluğu var. Texniki borc — sonra düzəliş tələb edəcək şürlu kompromis qərarıdır. Boilerplate düzəliş tələb etmir — o, avtomatlaşdırma tələb edir.
Xeyr, kiçik layihələrdə boilerplate sadəliyi ilə əsaslandırıla bilər: dərhal görünür və dəyişdirmək asandır. Problem miqyasda yaranır — eyni tipli modulların sayı ondan çox olduqda, əl ilə kopyalama səmərəsiz olur və generasiyanı tətbiq etmək vaxtıdır.
Qeyri-standart məntiqli xarici xidmətlərdən asılı kod (fərdi SDK-lar, müəllif protokolları) generasiya üçün çətindir. Belə hallarda boilerplate əl ilə yazılır, lakin layihə üzrə yayılmanı minimuma endirmək üçün ayrı modullara ayrılır.
Yeni layihələr üçün dərhal Kotlin-ə keçmək daha yaxşıdır, burada data class eyni tapşırıqları dil səviyyəsində həll edir. Layihə Java-da qalırsa — Lombok de-fakto standart olaraq qalır, lakin onun IDE üçün plagin tələb etdiyini və Java-nın yeni versiyaları ilə ziddiyyət yarada biləcəyini nəzərə alın.
Bəli, kod generasiyası quraşdırma vaxtına vaxt əlavə edir. KSP KAPT-dən daha sürətli işləyir, lakin yenə də tam quraşdırmaya saniyələr və ya dəqiqələr əlavə edir. Optimallaşdırma: inkremental quraşdırma və generasiya nəticələrinin quraşdırmalar arasında keşlənməsindən istifadə edin.
Yekun
Açar təslim mobil tətbiq hazırlayacağıq
IT Sectr 2017-ci ildən startaplar və bizneslər üçün iOS və Android tətbiqləri yaradır. Sizə məsləhət verəcəyik və ən yaxşı həlli təklif edəcəyik.
Həm də oxuyun