O'zbek

TypeScript abstrakt sinflarini, ularning afzalliklarini va qisman amalga oshirish patternlarini o'rganing. Kodni qayta ishlatish va moslashuvchanlikni oshirish uchun amaliy misollar.

TypeScript Abstrakt sinflari: Qisman amalga oshirish patternlarini o'zlashtirish

Abstrakt sinflar obyektga yo'naltirilgan dasturlashning (OYD) asosiy tushunchasi bo'lib, boshqa sinflar uchun andoza vazifasini o'taydi. TypeScript'da abstrakt sinflar umumiy funksionallikni belgilash bilan birga, merosxo'r sinflarga ma'lum bir amalga oshirish talablarini qo'yish uchun kuchli mexanizmni taqdim etadi. Ushbu maqola TypeScript abstrakt sinflarining nozikliklarini, qisman amalga oshirish uchun amaliy patternlarni va ularning loyihalaringizda kodni qayta ishlatish, saqlash va moslashuvchanlikni qanday sezilarli darajada oshirishi mumkinligini chuqur o'rganadi.

Abstrakt sinflar nima?

TypeScript'dagi abstrakt sinf — bu to'g'ridan-to'g'ri namuna (instance) olinmaydigan sinfdir. U boshqa sinflar uchun asos sinf bo'lib xizmat qiladi va merosxo'r sinflar amalga oshirishi (yoki qayta yozishi) kerak bo'lgan xususiyatlar va metodlar to'plamini belgilaydi. Abstrakt sinflar abstract kalit so'zi yordamida e'lon qilinadi.

Asosiy xususiyatlari:

Nima uchun abstrakt sinflardan foydalanish kerak?

Abstrakt sinflar dasturiy ta'minotni ishlab chiqishda bir qancha afzalliklarga ega:

Abstrakt sinfning oddiy misoli

TypeScript'dagi abstrakt sinfning asosiy sintaksisini ko'rsatish uchun oddiy misoldan boshlaymiz:


abstract class Animal {
 abstract makeSound(): string;

 move(): void {
 console.log("Moving...");
 }
}

class Dog extends Animal {
 makeSound(): string {
 return "Woof!";
 }
}

class Cat extends Animal {
 makeSound(): string {
 return "Meow!";
 }
}

//const animal = new Animal(); // Xato: Abstrakt sinfdan namuna yaratib bo'lmaydi.

const dog = new Dog();
console.log(dog.makeSound()); // Natija: Woof!
dog.move(); // Natija: Moving...

const cat = new Cat();
console.log(cat.makeSound()); // Natija: Meow!
cat.move(); // Natija: Moving...

Ushbu misolda, Animal — bu makeSound() abstrakt metodi va move() konkret metodiga ega bo'lgan abstrakt sinfdir. Dog va Cat sinflari Animal sinfidan meros oladi va makeSound() metodi uchun konkret amalga oshirishni taqdim etadi. E'tibor bering, Animal sinfidan to'g'ridan-to'g'ri namuna olishga urinish xatolikka olib keladi.

Qisman amalga oshirish patternlari

Abstrakt sinflarning kuchli jihatlaridan biri qisman amalga oshirish imkoniyatidir. Bu sizga ba'zi metodlar uchun standart amalga oshirishni ta'minlashga imkon beradi, shu bilan birga merosxo'r sinflardan boshqalarini amalga oshirishni talab qiladi. Bu kodni qayta ishlatish va moslashuvchanlik o'rtasidagi muvozanatni saqlaydi.

1. Merosxo'r sinflarda amalga oshirilishi shart bo'lgan abstrakt metodlar

Ushbu patternda abstrakt sinf merosxo'r sinflar tomonidan *amalga oshirilishi shart* bo'lgan abstrakt metodni e'lon qiladi, lekin asosiy amalga oshirishni taklif etmaydi. Bu merosxo'r sinflarni o'z mantig'ini taqdim etishga majbur qiladi.


abstract class DataProcessor {
 abstract fetchData(): Promise;
 abstract processData(data: any): any;
 abstract saveData(processedData: any): Promise;

 async run(): Promise {
 const data = await this.fetchData();
 const processedData = this.processData(data);
 await this.saveData(processedData);
 }
}

class APIProcessor extends DataProcessor {
 async fetchData(): Promise {
 // API'dan ma'lumotlarni olish uchun implementatsiya
 console.log("Fetching data from API...");
 return { data: "API Data" }; // Soxta ma'lumotlar
 }

 processData(data: any): any {
 // API ma'lumotlariga xos bo'lgan ma'lumotlarni qayta ishlash uchun implementatsiya
 console.log("Processing API data...");
 return { processed: data.data + " - Processed" }; // Soxta qayta ishlangan ma'lumotlar
 }

 async saveData(processedData: any): Promise {
 // Qayta ishlangan ma'lumotlarni API orqali ma'lumotlar bazasiga saqlash uchun implementatsiya
 console.log("Saving processed API data...");
 console.log(processedData);
 }
}

const apiProcessor = new APIProcessor();
apiProcessor.run();

Ushbu misolda, DataProcessor abstrakt sinfi uchta abstrakt metodni belgilaydi: fetchData(), processData() va saveData(). APIProcessor sinfi DataProcessor'dan meros oladi va bu metodlarning har biri uchun konkret amalga oshirishni taqdim etadi. Abstrakt sinfda belgilangan run() metodi butun jarayonni boshqaradi va har bir qadamning to'g'ri tartibda bajarilishini ta'minlaydi.

2. Abstrakt bog'liqliklarga ega konkret metodlar

Ushbu pattern abstrakt sinfdagi konkret metodlarning muayyan vazifalarni bajarish uchun abstrakt metodlarga tayanishini o'z ichiga oladi. Bu sizga umumiy algoritmni belgilashga imkon beradi, shu bilan birga amalga oshirish tafsilotlarini merosxo'r sinflarga topshiradi.


abstract class PaymentProcessor {
 abstract validatePaymentDetails(paymentDetails: any): boolean;
 abstract chargePayment(paymentDetails: any): Promise;
 abstract sendConfirmationEmail(paymentDetails: any): Promise;

 async processPayment(paymentDetails: any): Promise {
 if (!this.validatePaymentDetails(paymentDetails)) {
 console.error("Invalid payment details.");
 return false;
 }

 const chargeSuccessful = await this.chargePayment(paymentDetails);
 if (!chargeSuccessful) {
 console.error("Payment failed.");
 return false;
 }

 await this.sendConfirmationEmail(paymentDetails);
 console.log("Payment processed successfully.");
 return true;
 }
}

class CreditCardPaymentProcessor extends PaymentProcessor {
 validatePaymentDetails(paymentDetails: any): boolean {
 // Kredit karta ma'lumotlarini tekshirish
 console.log("Validating credit card details...");
 return true; // Soxta tekshiruv
 }

 async chargePayment(paymentDetails: any): Promise {
 // Kredit kartadan pul yechish
 console.log("Charging credit card...");
 return true; // Soxta to'lov
 }

 async sendConfirmationEmail(paymentDetails: any): Promise {
 // Kredit karta to'lovi uchun tasdiqlash xatini yuborish
 console.log("Sending confirmation email for credit card payment...");
 }
}

const creditCardProcessor = new CreditCardPaymentProcessor();
creditCardProcessor.processPayment({ cardNumber: "1234-5678-9012-3456", expiryDate: "12/24", cvv: "123", amount: 100 });

Ushbu misolda, PaymentProcessor abstrakt sinfi umumiy to'lovni qayta ishlash mantig'ini boshqaradigan processPayment() metodini belgilaydi. Biroq, validatePaymentDetails(), chargePayment() va sendConfirmationEmail() metodlari abstrakt bo'lib, merosxo'r sinflardan har bir to'lov usuli (masalan, kredit karta, PayPal va boshqalar) uchun maxsus amalga oshirishni taqdim etishni talab qiladi.

3. Andoza metodi (Template Method) patterni

Andoza metodi patterni — bu abstrakt sinfda algoritmining asosiy qismini belgilaydigan, ammo quyi sinflarga uning tuzilishini o'zgartirmasdan algoritmining ma'lum qadamlarini qayta yozishga imkon beradigan xulq-atvor dizayn patternidir. Ushbu pattern, ayniqsa, ma'lum bir tartibda bajarilishi kerak bo'lgan operatsiyalar ketma-ketligiga ega bo'lganingizda, ammo ba'zi operatsiyalarning bajarilishi kontekstga qarab o'zgarishi mumkin bo'lganda foydalidir.


abstract class ReportGenerator {
 abstract generateHeader(): string;
 abstract generateBody(): string;
 abstract generateFooter(): string;

 generateReport(): string {
 const header = this.generateHeader();
 const body = this.generateBody();
 const footer = this.generateFooter();

 return `${header}\n${body}\n${footer}`;
 }
}

class PDFReportGenerator extends ReportGenerator {
 generateHeader(): string {
 return "PDF Report Header";
 }

 generateBody(): string {
 return "PDF Report Body";
 }

 generateFooter(): string {
 return "PDF Report Footer";
 }
}

class CSVReportGenerator extends ReportGenerator {
 generateHeader(): string {
 return "CSV Report Header";
 }

 generateBody(): string {
 return "CSV Report Body";
 }

 generateFooter(): string {
 return "CSV Report Footer";
 }
}

const pdfReportGenerator = new PDFReportGenerator();
console.log(pdfReportGenerator.generateReport());

const csvReportGenerator = new CSVReportGenerator();
console.log(csvReportGenerator.generateReport());

Bu yerda, `ReportGenerator` `generateReport()` metodida umumiy hisobot yaratish jarayonini belgilaydi, alohida qadamlar (sarlavha, asosiy qism, yakunlovchi qism) esa `PDFReportGenerator` va `CSVReportGenerator` kabi konkret quyi sinflarga qoldirilgan.

4. Abstrakt xususiyatlar

Abstrakt sinflar, shuningdek, merosxo'r sinflarda amalga oshirilishi shart bo'lgan abstrakt xususiyatlarni ham belgilashi mumkin. Bu merosxo'r sinflarda ma'lum ma'lumotlar elementlarining mavjudligini ta'minlash uchun foydalidir.


abstract class Configuration {
 abstract apiKey: string;
 abstract apiUrl: string;

 getFullApiUrl(): string {
 return `${this.apiUrl}/${this.apiKey}`;
 }
}

class ProductionConfiguration extends Configuration {
 apiKey: string = "prod_api_key";
 apiUrl: string = "https://api.example.com/prod";
}

class DevelopmentConfiguration extends Configuration {
 apiKey: string = "dev_api_key";
 apiUrl: string = "http://localhost:3000/dev";
}

const prodConfig = new ProductionConfiguration();
console.log(prodConfig.getFullApiUrl()); // Natija: https://api.example.com/prod/prod_api_key

const devConfig = new DevelopmentConfiguration();
console.log(devConfig.getFullApiUrl()); // Natija: http://localhost:3000/dev/dev_api_key

Ushbu misolda, Configuration abstrakt sinfi ikkita abstrakt xususiyatni belgilaydi: apiKey va apiUrl. ProductionConfiguration va DevelopmentConfiguration sinflari Configuration'dan meros oladi va bu xususiyatlar uchun konkret qiymatlarni taqdim etadi.

Ilg'or holatlar

Abstrakt sinflar bilan miksinlar (Mixins)

TypeScript sizga yanada murakkab va qayta ishlatiladigan komponentlarni yaratish uchun abstrakt sinflarni miksinlar bilan birlashtirishga imkon beradi. Miksinlar — bu kichik, qayta ishlatiladigan funksionallik qismlarini birlashtirib sinflar qurish usulidir.


// Sinf konstruktori uchun tipni aniqlash
type Constructor = new (...args: any[]) => T;

// Miksin funksiyasini aniqlash
function Timestamped(Base: TBase) {
 return class extends Base {
 timestamp = new Date();
 };
}

// Yana bir miksin funksiyasi
function Logged(Base: TBase) {
 return class extends Base {
 log(message: string) {
 console.log(`${this.constructor.name}: ${message}`);
 }
 };
}

abstract class BaseEntity {
 abstract id: number;
}

// Miksinlarni BaseEntity abstrakt sinfiga qo'llash
const TimestampedEntity = Timestamped(BaseEntity);
const LoggedEntity = Logged(TimestampedEntity);

class User extends LoggedEntity {
 id: number = 123;
 name: string = "John Doe";

 constructor() {
 super();
 this.log("User created");
 }
}

const user = new User();
console.log(user.id); // Natija: 123
console.log(user.timestamp); // Natija: Joriy vaqt belgisi
user.log("User updated"); // Natija: User: User updated

Ushbu misol Timestamped va Logged miksinlarini BaseEntity abstrakt sinfi bilan birlashtirib, uchalasining funksionalligini meros qilib oladigan User sinfini yaratadi.

Bog'liqliklarni kiritish (Dependency Injection)

Komponentlarni bir-biridan ajratish va test qilishni osonlashtirish uchun abstrakt sinflarni bog'liqliklarni kiritish (DI) bilan samarali ishlatish mumkin. Siz abstrakt sinflarni bog'liqliklaringiz uchun interfeys sifatida belgilashingiz va keyin konkret amalga oshirishlarni sinflaringizga kiritishingiz mumkin.


abstract class Logger {
 abstract log(message: string): void;
}

class ConsoleLogger extends Logger {
 log(message: string): void {
 console.log(`[Console]: ${message}`);
 }
}

class FileLogger extends Logger {
 log(message: string): void {
 // Faylga log yozish uchun implementatsiya
 console.log(`[File]: ${message}`);
 }
}

class AppService {
 private logger: Logger;

 constructor(logger: Logger) {
 this.logger = logger;
 }

 doSomething() {
 this.logger.log("Doing something...");
 }
}

// ConsoleLogger'ni kiritish
const consoleLogger = new ConsoleLogger();
const appService1 = new AppService(consoleLogger);
appService1.doSomething();

// FileLogger'ni kiritish
const fileLogger = new FileLogger();
const appService2 = new AppService(fileLogger);
appService2.doSomething();

Ushbu misolda, AppService sinfi Logger abstrakt sinfiga bog'liq. Konkret amalga oshirishlar (ConsoleLogger, FileLogger) ish vaqtida kiritiladi, bu sizga turli xil log yozish strategiyalari o'rtasida osongina o'tish imkonini beradi.

Eng yaxshi amaliyotlar

Xulosa

TypeScript abstrakt sinflari mustahkam va qo'llab-quvvatlanadigan ilovalarni yaratish uchun kuchli vositadir. Qisman amalga oshirish patternlarini tushunish va qo'llash orqali siz moslashuvchan, qayta ishlatiladigan va yaxshi tuzilgan kod yaratish uchun abstrakt sinflarning afzalliklaridan foydalanishingiz mumkin. Abstrakt metodlarni standart amalga oshirish bilan belgilashdan tortib, abstrakt sinflarni miksinlar va bog'liqliklarni kiritish bilan ishlatishgacha, imkoniyatlar kengdir. Eng yaxshi amaliyotlarga rioya qilish va dizayn tanlovlaringizni diqqat bilan ko'rib chiqish orqali siz TypeScript loyihalaringizning sifati va kengayish imkoniyatlarini oshirish uchun abstrakt sinflardan samarali foydalanishingiz mumkin.

Katta miqyosli korporativ ilova yoki kichik yordamchi kutubxona yaratayotgan bo'lsangiz ham, TypeScript'da abstrakt sinflarni o'zlashtirish, shubhasiz, dasturiy ta'minotni ishlab chiqish ko'nikmalaringizni yaxshilaydi va yanada murakkab va qo'llab-quvvatlanadigan yechimlar yaratishga imkon beradi.