O'zbek

TypeScript dekoratorlarini o'rganing: kod tuzilishini, qayta foydalanish imkoniyatini va qo'llab-quvvatlanuvchanlikni yaxshilash uchun kuchli metadasturlash xususiyati. Amaliy misollar yordamida ulardan samarali foydalanishni o'rganing.

TypeScript Dekoratorlari: Metadasturlash Kuchini Ochish

TypeScript dekoratorlari metadasturlash imkoniyatlari bilan kodingizni kengaytirishning kuchli va nafis usulini taqdim etadi. Ular dizayn vaqtida sinflar, metodlar, xususiyatlar va parametrlarni o'zgartirish va kengaytirish mexanizmini taklif etib, kodingizning asosiy mantig'ini o'zgartirmasdan xatti-harakatlar va annotatsiyalarni qo'shish imkonini beradi. Ushbu blog posti TypeScript dekoratorlarining nozik jihatlariga chuqur kirib boradi va barcha darajadagi dasturchilar uchun keng qamrovli qo'llanmani taqdim etadi. Biz dekoratorlarning nima ekanligini, ular qanday ishlashini, mavjud turlarini, amaliy misollarni va ulardan samarali foydalanish uchun eng yaxshi amaliyotlarni o'rganamiz. Siz TypeScript-ga yangi kirgan bo'lasizmi yoki tajribali dasturchimisiz, ushbu qo'llanma sizni toza, qo'llab-quvvatlanadigan va ifodali kod uchun dekoratorlardan foydalanish bilimiga ega qiladi.

TypeScript Dekoratorlari nima?

Aslida, TypeScript dekoratorlari metadasturlashning bir shaklidir. Ular mohiyatan bir yoki bir nechta argumentlarni (odatda bezatilayotgan narsa, masalan, sinf, metod, xususiyat yoki parametr) qabul qiladigan va uni o'zgartirishi yoki yangi funksionallik qo'shishi mumkin bo'lgan funksiyalardir. Ularni kodingizga biriktiradigan annotatsiyalar yoki atributlar deb o'ylang. Ushbu annotatsiyalar keyinchalik kod haqida metama'lumotlar taqdim etish yoki uning xatti-harakatini o'zgartirish uchun ishlatilishi mumkin.

Dekoratorlar `@` belgisi va undan keyin keladigan funksiya chaqiruvi (masalan, `@dekoratorNomi()`) yordamida aniqlanadi. Dekorator funksiyasi keyin ilovangizning dizayn vaqti bosqichida bajariladi.

Dekoratorlar Java, C# va Python kabi tillardagi shunga o'xshash xususiyatlardan ilhomlangan. Ular asosiy mantig'ingizni toza saqlash va metama'lumotlaringiz yoki o'zgartirish jihatlaringizni maxsus joyda jamlash orqali vazifalarni ajratish va kodni qayta ishlatishni rag'batlantirish usulini taklif qiladi.

Dekoratorlar qanday ishlaydi

TypeScript kompilyatori dekoratorlarni dizayn vaqtida chaqiriladigan funksiyalarga aylantiradi. Dekorator funksiyasiga uzatiladigan aniq argumentlar ishlatilayotgan dekorator turiga (sinf, metod, xususiyat yoki parametr) bog'liq. Keling, har xil turdagi dekoratorlarni va ularning tegishli argumentlarini ko'rib chiqamiz:

Samarali dekoratorlar yozish uchun ushbu argument imzolarini tushunish juda muhimdir.

Dekorator Turlari

TypeScript har biri o'ziga xos maqsadga xizmat qiladigan bir nechta turdagi dekoratorlarni qo'llab-quvvatlaydi:

Amaliy Misollar

TypeScript-da dekoratorlardan qanday foydalanishni ko'rsatish uchun ba'zi amaliy misollarni ko'rib chiqamiz.

Sinf Dekoratori Misoli: Vaqt Belgisini Qo'shish

Tasavvur qiling, siz sinfning har bir nusxasiga vaqt belgisini qo'shmoqchisiz. Bunga erishish uchun sinf dekoratoridan foydalanishingiz mumkin:


function addTimestamp<T extends { new(...args: any[]): {} }>(constructor: T) {
  return class extends constructor {
    timestamp = Date.now();
  };
}

@addTimestamp
class MyClass {
  constructor() {
    console.log('MyClass yaratildi');
  }
}

const instance = new MyClass();
console.log(instance.timestamp); // Natija: vaqt belgisi

Ushbu misolda `addTimestamp` dekoratori sinf nusxasiga `timestamp` xususiyatini qo'shadi. Bu asl sinf ta'rifini to'g'ridan-to'g'ri o'zgartirmasdan qimmatli disk raskadrovka yoki audit izi ma'lumotlarini taqdim etadi.

Metod Dekoratori Misoli: Metod Chaqiruvlarini Loglash

Metod chaqiruvlarini va ularning argumentlarini loglash uchun metod dekoratoridan foydalanishingiz mumkin:


function logMethod(target: any, key: string, descriptor: PropertyDescriptor) {
  const originalMethod = descriptor.value;

  descriptor.value = function (...args: any[]) {
    console.log(`[LOG] ${key} metodi chaqirildi, argumentlar:`, args);
    const result = originalMethod.apply(this, args);
    console.log(`[LOG] ${key} metodi qaytardi:`, result);
    return result;
  };

  return descriptor;
}

class Greeter {
  @logMethod
  greet(message: string): string {
    return `Salom, ${message}!`;
  }
}

const greeter = new Greeter();
greeter.greet('Dunyo');
// Natija:
// [LOG] greet metodi chaqirildi, argumentlar: [ 'Dunyo' ]
// [LOG] greet metodi qaytardi: Salom, Dunyo!

Ushbu misol `greet` metodi har safar chaqirilganda, uning argumentlari va qaytarilgan qiymati bilan birga log yozadi. Bu murakkabroq ilovalarda disk raskadrovka va monitoring uchun juda foydali.

Xususiyat Dekoratori Misoli: Validatsiya Qo'shish

Quyida asosiy validatsiyani qo'shadigan xususiyat dekoratori misoli keltirilgan:


function validate(target: any, key: string) {
  let value: any;

  const getter = function () {
    return value;
  };

  const setter = function (newValue: any) {
    if (typeof newValue !== 'number') {
      console.warn(`[OGOHLANTIRISH] Noto'g'ri xususiyat qiymati: ${key}. Raqam kutilgan edi.`);
      return;
    }
    value = newValue;
  };

  Object.defineProperty(target, key, {
    get: getter,
    set: setter,
    enumerable: true,
    configurable: true,
  });
}

class Person {
  @validate
  age: number; //  <- Validatsiyali xususiyat
}

const person = new Person();
person.age = 'abc'; // Ogohlantirishni loglaydi
person.age = 30;   // Qiymatni o'rnatadi
console.log(person.age); // Natija: 30

Ushbu `validate` dekoratorida biz tayinlangan qiymatning raqam ekanligini tekshiramiz. Agar bo'lmasa, ogohlantirishni loglaymiz. Bu oddiy misol, lekin u dekoratorlarning ma'lumotlar yaxlitligini ta'minlash uchun qanday ishlatilishini ko'rsatadi.

Parametr Dekoratori Misoli: Bog'liqlik Inyeksiyasi (Soddalashtirilgan)

To'liq bog'liqlik inyeksiyasi freymvorklari ko'pincha murakkabroq mexanizmlardan foydalansa-da, dekoratorlar ham inyektsiya uchun parametrlarni belgilash uchun ishlatilishi mumkin. Ushbu misol soddalashtirilgan ko'rinishdir:


// Bu soddalashtirish va haqiqiy inyeksiyani bajarmaydi. Haqiqiy DI murakkabroq.
function Inject(service: any) {
  return function (target: any, propertyKey: string | symbol, parameterIndex: number) {
    // Servisni biror joyda saqlash (masalan, statik xususiyatda yoki xaritada)
    if (!target.injectedServices) {
      target.injectedServices = {};
    }
    target.injectedServices[parameterIndex] = service;
  };
}

class MyService {
  doSomething() { /* ... */ }
}

class MyComponent {
  constructor(@Inject(MyService) private myService: MyService) {
    // Haqiqiy tizimda DI konteyneri bu yerda 'myService'ni hal qilgan bo'lardi.
    console.log('MyComponent quyidagi bilan tuzildi:', myService.constructor.name); //Misol
  }
}

const component = new MyComponent(new MyService());  // Servisni inyektsiya qilish (soddalashtirilgan).

`Inject` dekoratori parametrni servis talab qiladigan deb belgilaydi. Ushbu misol dekoratorning bog'liqlik inyeksiyasini talab qiladigan parametrlarni qanday aniqlashini ko'rsatadi (lekin haqiqiy freymvork servisni hal qilishni boshqarishi kerak).

Dekoratorlardan Foydalanishning Afzalliklari

Dekoratorlardan Foydalanishning Eng Yaxshi Amaliyotlari

Murakkab Tushunchalar

Dekorator Fabrikalari

Dekorator fabrikalari dekorator funksiyalarini qaytaradigan funksiyalardir. Bu sizga dekoratorlaringizga argumentlar uzatish imkonini beradi, bu ularni yanada moslashuvchan va sozlanuvchan qiladi. Masalan, siz validatsiya qoidalarini belgilash imkonini beradigan validatsiya dekorator fabrikasini yaratishingiz mumkin:


function validate(minLength: number) {
  return function (target: any, key: string) {
    let value: string;

    const getter = function () {
      return value;
    };

    const setter = function (newValue: string) {
      if (typeof newValue !== 'string') {
        console.warn(`[OGOHLANTIRISH] Noto'g'ri xususiyat qiymati: ${key}. Satr kutilgan edi.`);
        return;
      }
      if (newValue.length < minLength) {
        console.warn(`[OGOHLANTIRISH] ${key} kamida ${minLength} belgidan iborat bo'lishi kerak.`);
        return;
      }
      value = newValue;
    };

    Object.defineProperty(target, key, {
      get: getter,
      set: setter,
      enumerable: true,
      configurable: true,
    });
  };
}

class Person {
  @validate(3) // Minimal uzunligi 3 bilan tekshirish
  name: string;
}

const person = new Person();
person.name = 'Jo';
console.log(person.name); // Ogohlantirishni loglaydi, qiymatni o'rnatadi.
person.name = 'John';
console.log(person.name); // Natija: John

Dekorator fabrikalari dekoratorlarni ancha moslashuvchan qiladi.

Dekoratorlarni Birlashtirish

Siz bir xil elementga bir nechta dekoratorlarni qo'llashingiz mumkin. Ularning qo'llanilish tartibi ba'zan muhim bo'lishi mumkin. Tartib pastdan yuqoriga (yozilganidek). Masalan:


function first() {
  console.log('first(): fabrika baholandi');
  return function (target: any, propertyKey: string, descriptor: PropertyDescriptor) {
    console.log('first(): chaqirildi');
  }
}

function second() {
  console.log('second(): fabrika baholandi');
  return function (target: any, propertyKey: string, descriptor: PropertyDescriptor) {
    console.log('second(): chaqirildi');
  }
}

class ExampleClass {
  @first()
  @second()
  method() {}
}

// Natija:
// second(): fabrika baholandi
// first(): fabrika baholandi
// second(): chaqirildi
// first(): chaqirildi

E'tibor bering, fabrika funksiyalari paydo bo'lish tartibida baholanadi, lekin dekorator funksiyalari teskari tartibda chaqiriladi. Agar dekoratorlaringiz bir-biriga bog'liq bo'lsa, ushbu tartibni tushuning.

Dekoratorlar va Metama'lumotlar Refleksiyasi

Dekoratorlar yanada dinamik xatti-harakatlarga erishish uchun metama'lumotlar refleksiyasi bilan (`reflect-metadata` kabi kutubxonalardan foydalanib) birgalikda ishlashi mumkin. Bu sizga, masalan, ish vaqtida (runtime) bezatilgan elementlar haqidagi ma'lumotlarni saqlash va olish imkonini beradi. Bu ayniqsa freymvorklar va bog'liqlik inyeksiyasi tizimlarida foydalidir. Dekoratorlar sinflarni yoki metodlarni metama'lumotlar bilan annotatsiya qilishi mumkin, va keyin refleksiya ushbu metama'lumotlarni topish va ishlatish uchun qo'llanilishi mumkin.

Ommabop Freymvork va Kutubxonalardagi Dekoratorlar

Dekoratorlar ko'plab zamonaviy JavaScript freymvorklari va kutubxonalarining ajralmas qismiga aylandi. Ularning qo'llanilishini bilish sizga freymvork arxitekturasini va uning turli vazifalarni qanday soddalashtirishini tushunishga yordam beradi.

Ushbu freymvorklar va kutubxonalar dekoratorlarning kod tashkilotini qanday yaxshilashini, umumiy vazifalarni soddalashtirishini va haqiqiy dunyo ilovalarida qo'llab-quvvatlanuvchanlikni qanday oshirishini ko'rsatadi.

Qiyinchiliklar va E'tiborga Olinadigan Jihatlar

Xulosa

TypeScript dekoratorlari kodingizning tuzilishini, qayta ishlatilishini va qo'llab-quvvatlanishini sezilarli darajada yaxshilaydigan kuchli metadasturlash xususiyatidir. Turli xil dekorator turlarini, ular qanday ishlashini va ulardan foydalanishning eng yaxshi amaliyotlarini tushunib, siz ulardan toza, ifodali va samaraliroq ilovalar yaratish uchun foydalanishingiz mumkin. Siz oddiy ilova yoki murakkab korporativ darajadagi tizim qurasizmi, dekoratorlar ishlab chiqish jarayonini yaxshilash uchun qimmatli vositani taqdim etadi. Dekoratorlarni qabul qilish kod sifatini sezilarli darajada yaxshilashga imkon beradi. Angular va NestJS kabi mashhur freymvorklar ichida dekoratorlar qanday integratsiyalashganini tushunib, dasturchilar kengaytiriladigan, qo'llab-quvvatlanadigan va mustahkam ilovalar yaratish uchun ularning to'liq salohiyatidan foydalanishlari mumkin. Asosiy narsa ularning maqsadini va ularni tegishli kontekstlarda qanday qo'llashni tushunish, afzalliklar har qanday potentsial kamchiliklardan ustun bo'lishini ta'minlashdir.

Dekoratorlarni samarali qo'llash orqali siz kodingizni yanada yaxshi tuzilish, qo'llab-quvvatlanuvchanlik va samaradorlik bilan yaxshilashingiz mumkin. Ushbu qo'llanma TypeScript dekoratorlaridan qanday foydalanish haqida keng qamrovli ma'lumot beradi. Ushbu bilim bilan siz yaxshiroq va qo'llab-quvvatlanadigan TypeScript kodi yaratish imkoniyatiga egasiz. Oldinga boring va bezang!