Sobes.tech
Senior

Чӣ гуна масъалаи истифодаи вобастагиҳои компонентҳои перифериро дар ядро ҳал кардан мумкин аст?

sobes.tech AI

Ҷавоб аз AI

Ҳал кардани масъалаи истифодаи вобастагиҳои компонентҳои периферӣ (адаптерҳо, интерфейсҳо) дар ядро (логикаи доменӣ) дар архитектураҳое мисли Архитектураи Тоза ё DDD, метавонад бо истифода аз принсипи Баргардонидани вобастагиҳо (Dependency Inversion Principle - DIP) ба даст ояд.

Маънии DIP:

  1. Модулҳои сатҳи болоӣ набояд аз модулҳои сатҳи поёнӣ вобаста бошанд. Ҳарду бояд ба абстраксияҳо вобаста бошанд.
  2. Абстраксияҳо набояд аз тафсилотҳо вобаста бошанд. Тафсилотҳо бояд аз абстраксияҳо вобаста бошанд.

Барномаи амал:

  • Ядро интерфейсҳоро эълон мекунад: Ядро абстраксияҳоро (интерфейсҳо ё синфҳои абстрактӣ) муайян мекунад, ки функсияҳои зарурии компонентҳои перифериро тавсиф мекунанд.
  • Компонентҳои периферӣ интерфейсҳоро иҷро мекунанд: Модулҳои хориҷӣ (адаптерҳо барои базаҳои додаҳо, муштариёни HTTP, системаҳои файлӣ ва ғайра) ин интерфейсҳоро иҷро мекунанд.
  • Вуруд кардани вобастагиҳо (Dependency Injection - DI): Компонентҳои периферӣ аз берун ба ядро ворид мешаванд, одатан дар сатҳи болоии барнома (масалан, дар решаи композиционӣ ё бо истифода аз контейнери DI). Ядро танҳо бо абстраксияҳо кор мекунад.

Масалан, истифодаи DIP дар Node.js:

Гуфта шавад, ки мо ядро дорем, ки ба дастрасӣ ба маълумот ниёз дорад.

// src/domain/interfaces/UserRepository.ts
// Ядро интерфейсро эълон мекунад
export interface UserRepository {
  getUserById(id: string): Promise<User | null>;
}
// src/domain/entities/User.ts
// Вобастагии ядро
export class User {
  constructor(public id: string, public name: string) {}
}
// src/domain/usecases/GetUserUseCase.ts
// Кейс истифодаи ядро аз абстраксияи UserRepository вобаста аст
import { UserRepository } from '../interfaces/UserRepository';
import { User } from '../entities/User';

export class GetUserUseCase {
  constructor(private userRepository: UserRepository) {}

  async execute(id: string): Promise<User | null> {
    return this.userRepository.getUserById(id);
  }
}
// src/infrastructure/database/MongoDbUserRepository.ts
// Компоненти периферӣ, ки интерфейси ядроро иҷро мекунад
import { UserRepository } from '../../domain/interfaces/UserRepository';
import { User } from '../../domain/entities/User';

export class MongoDbUserRepository implements UserRepository {
  // Ин ҷо логикаи иртибот бо MongoDB хоҳад буд

  async getUserById(id: string): Promise<User | null> {
    console.log(`Гирифтани корбар бо id ${id} аз MongoDB...`);
    // Имитацияи гирифтани маълумот
    if (id === '123') {
      return new User('123', 'John Doe');
    }
    return null;
  }
}
// src/app/CompositionRoot.ts
// Решаи композиционӣ вобастагиҳоро ҷамъ мекунад
import { GetUserUseCase } from '../domain/usecases/GetUserUseCase';
import { MongoDbUserRepository } from '../infrastructure/database/MongoDbUserRepository';

// Вуруд кардани вобастагиҳо: Ядро реализацияи MongoDbUserRepository-ро тавассути интерфейс мегирад
const userRepository = new MongoDbUserRepository();
const getUserUseCase = new GetUserUseCase(userRepository);

// Ҳоло метавонем истифода барем
async function run() {
  const user = await getUserUseCase.execute('123');
  if (user) {
    console.log(`Корифери ёфт: ${user.name}`);
  } else {
    console.log('Корифери ёфт нашуд');
  }
}

run();

Фоидаҳои ин усул:

  • Независии ядро: Ядро дар бораи реализацияҳои мушаххаси компонентҳои периферӣ хабар надорад.
  • Тестшавандагӣ: Ядро бо истифода аз моделҳои мок-реализаҳои интерфейсҳо осон тест карда мешавад.
  • Флексибилитет: Легко метавонад як реализация (масалан, базаи додаҳо)-ро бо дигаре иваз кунад, бе тағир додани коди ядро.
  • Дастгирӣ: Тавсия медиҳад, ки нигоҳдорӣ ва тағирот дар коди бароҳаттар шавад.