Найти Π² Π”Π·Π΅Π½Π΅

🧠 ΠŸΡ€ΠΎΡΡ‚Π°Ρ сила чистого ΠΊΠΎΠ΄Π°: философия β€œΠ€ΡƒΠ½ΠΊΡ†ΠΈΠΎΠ½Π°Π»ΡŒΠ½ΠΎΠ΅ ядро, импСративная оболочка” ΠΎΡ‚ Google

Компания Google снова Π½Π°ΠΏΠΎΠΌΠΈΠ½Π°Π΅Ρ‚ Ρ€Π°Π·Ρ€Π°Π±ΠΎΡ‚Ρ‡ΠΈΠΊΠ°ΠΌ ΠΎ старом, Π½ΠΎ Π²Π΅Ρ‡Π½ΠΎ Π°ΠΊΡ‚ΡƒΠ°Π»ΡŒΠ½ΠΎΠΌ ΠΏΡ€ΠΈΠ½Ρ†ΠΈΠΏΠ΅ β€” раздСляй ΠΈ властвуй. На этот Ρ€Π°Π· Π² контСкстС Π°Ρ€Ρ…ΠΈΡ‚Π΅ΠΊΡ‚ΡƒΡ€Ρ‹ ΠΊΠΎΠ΄Π°: Ρ„ΡƒΠ½ΠΊΡ†ΠΈΠΎΠ½Π°Π»ΡŒΠ½ΠΎΠ΅ ядро ΠΈ импСративная ΠΎΠ±ΠΎΠ»ΠΎΡ‡ΠΊΠ°.
На ΠΏΠ΅Ρ€Π²Ρ‹ΠΉ взгляд β€” Π·Π²ΡƒΡ‡ΠΈΡ‚ Π°ΠΊΠ°Π΄Π΅ΠΌΠΈΡ‡Π½ΠΎ. Но Π½Π° ΠΏΡ€Π°ΠΊΡ‚ΠΈΠΊΠ΅ это ΠΎΠ΄ΠΈΠ½ ΠΈΠ· Ρ‚Π΅Ρ… ΠΏΡ€ΠΈΡ‘ΠΌΠΎΠ², ΠΊΠΎΡ‚ΠΎΡ€Ρ‹ΠΉ Π΄Π΅Π»Π°Π΅Ρ‚ ΠΊΠΎΠ΄ понятным, тСстируСмым ΠΈ Π΄ΠΎΠ»Π³ΠΎΠ²Π΅Ρ‡Π½Ρ‹ΠΌ. Google Testing Blog ΠΏΡ€Π΅Π΄Π»Π°Π³Π°Π΅Ρ‚ Π΄Π΅Π»ΠΈΡ‚ΡŒ ΠΊΠΎΠ΄ Π½Π° Π΄Π²Π΅ части: πŸ’‘ Π€ΡƒΠ½ΠΊΡ†ΠΈΠΎΠ½Π°Π»ΡŒΠ½ΠΎΠ΅ ядро (Functional Core) β€”
чистыС Ρ„ΡƒΠ½ΠΊΡ†ΠΈΠΈ Π±Π΅Π· ΠΏΠΎΠ±ΠΎΡ‡Π½Ρ‹Ρ… эффСктов. Они Ρ€Π°Π±ΠΎΡ‚Π°ΡŽΡ‚ Ρ‚ΠΎΠ»ΡŒΠΊΠΎ с ΠΏΠ΅Ρ€Π΅Π΄Π°Π½Π½Ρ‹ΠΌΠΈ Π΄Π°Π½Π½Ρ‹ΠΌΠΈ ΠΈ Π½ΠΈΡ‡Π΅Π³ΠΎ Π½Π΅ ΠΌΠ΅Π½ΡΡŽΡ‚ Π²Π½Π΅ своСй области видимости. Ни Π‘Π”, Π½ΠΈ ΡΠ΅Ρ‚ΡŒ, Π½ΠΈ Π³Π»ΠΎΠ±Π°Π»ΡŒΠ½Ρ‹Π΅ ΠΏΠ΅Ρ€Π΅ΠΌΠ΅Π½Π½Ρ‹Π΅ β€” Ρ‚ΠΎΠ»ΡŒΠΊΠΎ Π»ΠΎΠ³ΠΈΠΊΠ° ΠΈ Π΄Π°Π½Π½Ρ‹Π΅. ⚑️ Π˜ΠΌΠΏΠ΅Ρ€Π°Ρ‚ΠΈΠ²Π½Π°Ρ ΠΎΠ±ΠΎΠ»ΠΎΡ‡ΠΊΠ° (Imperative Shell) β€”
всё, Ρ‡Ρ‚ΠΎ связано с Π²Π²ΠΎΠ΄ΠΎΠΌ-Π²Ρ‹Π²ΠΎΠ΄ΠΎΠΌ, API, Π±Π°Π·Π°ΠΌΠΈ Π΄Π°Π½Π½Ρ‹Ρ…, Ρ„Π°ΠΉΠ»Π°ΠΌΠΈ, ΠΏΠΎΠ»ΡŒΠ·ΠΎΠ²Π°Ρ‚Π΅Π»ΡΠΌΠΈ. Она β€œΠΎΠ±ΠΎΡ€Π°Ρ‡ΠΈΠ²Π°Π΅Ρ‚β€ ядро, вызывая Π΅Π³ΠΎ Ρ„ΡƒΠ½ΠΊΡ†ΠΈΠΈ ΠΈ управляя взаимодСйствиСм с внСшним ΠΌΠΈΡ€ΠΎΠΌ. Рассмотрим ΠΏΡ€ΠΈΠΌΠ΅Ρ€ ΠΈΠ· Π±Π»ΠΎΠ³Π° Google. Π‘Ρ‹Π» ΠΊΠΎΠ΄, ΠΊΠΎΡ‚ΠΎΡ€Ρ‹ΠΉ отправлял письма ΠΎ просрочСнной подпискС: // ΠŸΠ»ΠΎΡ…ΠΎΠΉ ΠΏΡ€ΠΈΠΌΠ΅Ρ€
function sendUserExpiryEmail() {
for (const user
ОглавлСниС

Компания Google снова Π½Π°ΠΏΠΎΠΌΠΈΠ½Π°Π΅Ρ‚ Ρ€Π°Π·Ρ€Π°Π±ΠΎΡ‚Ρ‡ΠΈΠΊΠ°ΠΌ ΠΎ старом, Π½ΠΎ Π²Π΅Ρ‡Π½ΠΎ Π°ΠΊΡ‚ΡƒΠ°Π»ΡŒΠ½ΠΎΠΌ ΠΏΡ€ΠΈΠ½Ρ†ΠΈΠΏΠ΅ β€” раздСляй ΠΈ властвуй. На этот Ρ€Π°Π· Π² контСкстС Π°Ρ€Ρ…ΠΈΡ‚Π΅ΠΊΡ‚ΡƒΡ€Ρ‹ ΠΊΠΎΠ΄Π°: Ρ„ΡƒΠ½ΠΊΡ†ΠΈΠΎΠ½Π°Π»ΡŒΠ½ΠΎΠ΅ ядро ΠΈ импСративная ΠΎΠ±ΠΎΠ»ΠΎΡ‡ΠΊΠ°.
На ΠΏΠ΅Ρ€Π²Ρ‹ΠΉ взгляд β€” Π·Π²ΡƒΡ‡ΠΈΡ‚ Π°ΠΊΠ°Π΄Π΅ΠΌΠΈΡ‡Π½ΠΎ. Но Π½Π° ΠΏΡ€Π°ΠΊΡ‚ΠΈΠΊΠ΅ это ΠΎΠ΄ΠΈΠ½ ΠΈΠ· Ρ‚Π΅Ρ… ΠΏΡ€ΠΈΡ‘ΠΌΠΎΠ², ΠΊΠΎΡ‚ΠΎΡ€Ρ‹ΠΉ Π΄Π΅Π»Π°Π΅Ρ‚ ΠΊΠΎΠ΄
понятным, тСстируСмым ΠΈ Π΄ΠΎΠ»Π³ΠΎΠ²Π΅Ρ‡Π½Ρ‹ΠΌ.

βš™οΈ Π§Ρ‚ΠΎ это Π·Π½Π°Ρ‡ΠΈΡ‚

Google Testing Blog ΠΏΡ€Π΅Π΄Π»Π°Π³Π°Π΅Ρ‚ Π΄Π΅Π»ΠΈΡ‚ΡŒ ΠΊΠΎΠ΄ Π½Π° Π΄Π²Π΅ части:

πŸ’‘ Π€ΡƒΠ½ΠΊΡ†ΠΈΠΎΠ½Π°Π»ΡŒΠ½ΠΎΠ΅ ядро (Functional Core) β€”
чистыС Ρ„ΡƒΠ½ΠΊΡ†ΠΈΠΈ Π±Π΅Π· ΠΏΠΎΠ±ΠΎΡ‡Π½Ρ‹Ρ… эффСктов. Они Ρ€Π°Π±ΠΎΡ‚Π°ΡŽΡ‚ Ρ‚ΠΎΠ»ΡŒΠΊΠΎ с ΠΏΠ΅Ρ€Π΅Π΄Π°Π½Π½Ρ‹ΠΌΠΈ Π΄Π°Π½Π½Ρ‹ΠΌΠΈ ΠΈ Π½ΠΈΡ‡Π΅Π³ΠΎ Π½Π΅ ΠΌΠ΅Π½ΡΡŽΡ‚ Π²Π½Π΅ своСй области видимости. Ни Π‘Π”, Π½ΠΈ ΡΠ΅Ρ‚ΡŒ, Π½ΠΈ Π³Π»ΠΎΠ±Π°Π»ΡŒΠ½Ρ‹Π΅ ΠΏΠ΅Ρ€Π΅ΠΌΠ΅Π½Π½Ρ‹Π΅ β€” Ρ‚ΠΎΠ»ΡŒΠΊΠΎ Π»ΠΎΠ³ΠΈΠΊΠ° ΠΈ Π΄Π°Π½Π½Ρ‹Π΅.

⚑️ Π˜ΠΌΠΏΠ΅Ρ€Π°Ρ‚ΠΈΠ²Π½Π°Ρ ΠΎΠ±ΠΎΠ»ΠΎΡ‡ΠΊΠ° (Imperative Shell) β€”
всё, Ρ‡Ρ‚ΠΎ связано с Π²Π²ΠΎΠ΄ΠΎΠΌ-Π²Ρ‹Π²ΠΎΠ΄ΠΎΠΌ, API, Π±Π°Π·Π°ΠΌΠΈ Π΄Π°Π½Π½Ρ‹Ρ…, Ρ„Π°ΠΉΠ»Π°ΠΌΠΈ, ΠΏΠΎΠ»ΡŒΠ·ΠΎΠ²Π°Ρ‚Π΅Π»ΡΠΌΠΈ. Она β€œΠΎΠ±ΠΎΡ€Π°Ρ‡ΠΈΠ²Π°Π΅Ρ‚β€ ядро, вызывая Π΅Π³ΠΎ Ρ„ΡƒΠ½ΠΊΡ†ΠΈΠΈ ΠΈ управляя взаимодСйствиСм с внСшним ΠΌΠΈΡ€ΠΎΠΌ.

πŸ’Œ ΠŸΡ€ΠΈΠΌΠ΅Ρ€ ΠΈΠ· ΠΆΠΈΠ·Π½ΠΈ: рассылка писСм

Рассмотрим ΠΏΡ€ΠΈΠΌΠ΅Ρ€ ΠΈΠ· Π±Π»ΠΎΠ³Π° Google. Π‘Ρ‹Π» ΠΊΠΎΠ΄, ΠΊΠΎΡ‚ΠΎΡ€Ρ‹ΠΉ отправлял письма ΠΎ просрочСнной подпискС:

// ΠŸΠ»ΠΎΡ…ΠΎΠΉ ΠΏΡ€ΠΈΠΌΠ΅Ρ€
function sendUserExpiryEmail() {
for (const user of db.getUsers()) {
if (user.subscriptionEndDate > Date.now()) continue;
if (user.isFreeTrial) continue;
email.send(user.email, "Your account has expired " + user.name + ".");
}
}

Π—Π΄Π΅ΡΡŒ смСшано всё: бизнСс-Π»ΠΎΠ³ΠΈΠΊΠ°, Ρ„ΠΈΠ»ΡŒΡ‚Ρ€Π°Ρ†ΠΈΡ ΠΏΠΎΠ»ΡŒΠ·ΠΎΠ²Π°Ρ‚Π΅Π»Π΅ΠΉ ΠΈ ΠΏΠΎΠ±ΠΎΡ‡Π½Ρ‹Π΅ эффСкты (запрос ΠΊ Π‘Π”, ΠΎΡ‚ΠΏΡ€Π°Π²ΠΊΠ° писСм).
Π’Π΅ΡΡ‚ΠΈΡ€ΠΎΠ²Π°Ρ‚ΡŒ это Π½Π΅Π²ΠΎΠ·ΠΌΠΎΠΆΠ½ΠΎ Π±Π΅Π· ΠΌΠΎΠΊΠΎΠ². ΠœΠ΅Π½ΡΡ‚ΡŒ β€” боль.

βœ… Π’Π°Ρ€ΠΈΠ°Π½Ρ‚ с Ρ€Π°Π·Π΄Π΅Π»Π΅Π½ΠΈΠ΅ΠΌ:

// Π€ΡƒΠ½ΠΊΡ†ΠΈΠΎΠ½Π°Π»ΡŒΠ½ΠΎΠ΅ ядро
function getExpiredUsers(users, cutoff) {
return users.filter(u => u.subscriptionEndDate <= cutoff && !u.isFreeTrial);
}
function generateExpiryEmails(users) {
return users.map(u => [u.email, `Your account has expired ${u.name}.`]);
}

// Π˜ΠΌΠΏΠ΅Ρ€Π°Ρ‚ΠΈΠ²Π½Π°Ρ ΠΎΠ±ΠΎΠ»ΠΎΡ‡ΠΊΠ°
email.bulkSend(generateExpiryEmails(getExpiredUsers(db.getUsers(), Date.now())));

Π’Π΅ΠΏΠ΅Ρ€ΡŒ ядро ΠΌΠΎΠΆΠ½ΠΎ ΠΏΡ€ΠΎΡ‚Π΅ΡΡ‚ΠΈΡ€ΠΎΠ²Π°Ρ‚ΡŒ ΠΈΠ·ΠΎΠ»ΠΈΡ€ΠΎΠ²Π°Π½Π½ΠΎ, Π±Π΅Π· Π‘Π” ΠΈ Π±Π΅Π· SMTP-сСрвСра. А Ссли Π·Π°Π²Ρ‚Ρ€Π° Π²Ρ‹ Ρ€Π΅ΡˆΠΈΡ‚Π΅ Π·Π°ΠΌΠ΅Π½ΠΈΡ‚ΡŒ email-сСрвис Π½Π° Kafka ΠΈΠ»ΠΈ push-увСдомлСния β€” просто ΠΏΠ΅Ρ€Π΅ΠΏΠΈΡˆΠ΅Ρ‚Π΅ ΠΎΠ±ΠΎΠ»ΠΎΡ‡ΠΊΡƒ, Π½Π΅ трогая бизнСс-Π»ΠΎΠ³ΠΈΠΊΡƒ.

🧩 ΠŸΠΎΡ‡Π΅ΠΌΡƒ это Π²Π°ΠΆΠ½ΠΎ

  • πŸ§ͺ Π’Π΅ΡΡ‚ΠΈΡ€ΡƒΠ΅ΠΌΠΎΡΡ‚ΡŒ β€” чистыС Ρ„ΡƒΠ½ΠΊΡ†ΠΈΠΈ Π»Π΅Π³ΠΊΠΎ ΠΏΠΎΠΊΡ€Ρ‹Ρ‚ΡŒ ΡŽΠ½ΠΈΡ‚-тСстами Π±Π΅Π· ΠΌΠΎΠΊΠΎΠ² ΠΈ слоТных зависимостСй.
  • πŸ” ΠŸΠΎΠ²Ρ‚ΠΎΡ€Π½ΠΎΠ΅ использованиС β€” ядро ΠΌΠΎΠΆΠ½ΠΎ ΠΏΡ€ΠΈΠΌΠ΅Π½ΡΡ‚ΡŒ Π² CLI-инструмСнтС, Π²Π΅Π±-сСрвисС, Π΄Π°ΠΆΠ΅ Π² сСрвСрлСс-Ρ„ΡƒΠ½ΠΊΡ†ΠΈΠΈ.
  • 🧱 Π“ΠΈΠ±ΠΊΠΎΡΡ‚ΡŒ Π°Ρ€Ρ…ΠΈΡ‚Π΅ΠΊΡ‚ΡƒΡ€Ρ‹ β€” ΠΎΠ±ΠΎΠ»ΠΎΡ‡ΠΊΡƒ ΠΌΠΎΠΆΠ½ΠΎ Π·Π°ΠΌΠ΅Π½ΠΈΡ‚ΡŒ: ΠΈΠ· REST ΡΠ΄Π΅Π»Π°Ρ‚ΡŒ gRPC, ΠΈΠ· SMTP ΠΏΠ΅Ρ€Π΅ΠΉΡ‚ΠΈ Π½Π° SQS.
  • πŸš€ ΠŸΡ€ΠΎΡΡ‚ΠΎΡ‚Π° ΡΠ²ΠΎΠ»ΡŽΡ†ΠΈΠΈ β€” Π½ΠΎΠ²Ρ‹Π΅ Ρ‚ΠΈΠΏΡ‹ ΡƒΠ²Π΅Π΄ΠΎΠΌΠ»Π΅Π½ΠΈΠΉ Π΄ΠΎΠ±Π°Π²Π»ΡΡŽΡ‚ΡΡ созданиСм ΠΎΠ΄Π½ΠΎΠΉ Π½ΠΎΠ²ΠΎΠΉ Ρ„ΡƒΠ½ΠΊΡ†ΠΈΠΈ, Π° Π½Π΅ ΠΏΡ€Π°Π²ΠΊΠ°ΠΌΠΈ Π² дСсятках мСст.

πŸ” ВСхничСскиС Π΄Π΅Ρ‚Π°Π»ΠΈ

Π‘ Π°Ρ€Ρ…ΠΈΡ‚Π΅ΠΊΡ‚ΡƒΡ€Π½ΠΎΠΉ Ρ‚ΠΎΡ‡ΠΊΠΈ зрСния, ΠΏΠ°Ρ‚Ρ‚Π΅Ρ€Π½ β€œΠ€ΡƒΠ½ΠΊΡ†ΠΈΠΎΠ½Π°Π»ΡŒΠ½ΠΎΠ΅ ядро, импСративная оболочка” Π±Π»ΠΈΠ·ΠΎΠΊ ΠΊ идСям Π“Π΅ΠΊΡΠ°Π³ΠΎΠ½Π°Π»ΡŒΠ½Π°Ρ Π°Ρ€Ρ…ΠΈΡ‚Π΅ΠΊΡ‚ΡƒΡ€Π° ΠΈ Чистая Π°Ρ€Ρ…ΠΈΡ‚Π΅ΠΊΡ‚ΡƒΡ€Π°:

  • πŸ’Ύ Π―Π΄Ρ€ΠΎ ΠΈΠ·ΠΎΠ»ΠΈΡ€ΠΎΠ²Π°Π½ΠΎ ΠΎΡ‚ инфраструктуры.
  • 🧩 ΠžΠ±ΠΎΠ»ΠΎΡ‡ΠΊΠ° β€” Π°Π΄Π°ΠΏΡ‚Π΅Ρ€, ΠΊΠΎΡ‚ΠΎΡ€Ρ‹ΠΉ Π·Π½Π°Π΅Ρ‚, ΠΊΠ°ΠΊ ΠΏΡ€ΠΈΠΌΠ΅Π½ΠΈΡ‚ΡŒ Π»ΠΎΠ³ΠΈΠΊΡƒ.
  • 🧠 Зависимости Π½Π°ΠΏΡ€Π°Π²Π»Π΅Π½Ρ‹ Π²Π½ΡƒΡ‚Ρ€ΡŒ β€” ΠΎΡ‚ внСшнСго слоя ΠΊ Π²Π½ΡƒΡ‚Ρ€Π΅Π½Π½Π΅ΠΌΡƒ.

Π­Ρ‚ΠΎ ΡƒΠΏΡ€ΠΎΡ‰Π°Π΅Ρ‚ Π²Π½Π΅Π΄Ρ€Π΅Π½ΠΈΠ΅ зависимостСй (dependency injection) ΠΈ сниТаСт ΠΊΠΎΠ³Π½ΠΈΡ‚ΠΈΠ²Π½ΡƒΡŽ Π½Π°Π³Ρ€ΡƒΠ·ΠΊΡƒ Π½Π° Ρ€Π°Π·Ρ€Π°Π±ΠΎΡ‚Ρ‡ΠΈΠΊΠ°.

πŸ’¬ Мой взгляд

МнС каТСтся, этот ΠΏΠΎΠ΄Ρ…ΠΎΠ΄ особСнно Π²Π°ΠΆΠ΅Π½ Π² эпоху LLM-инструмСнтов ΠΈ Π°Π²Ρ‚ΠΎΠ³Π΅Π½Π΅Ρ€Π°Ρ†ΠΈΠΈ ΠΊΠΎΠ΄Π°. Когда Ρ‡Π°ΡΡ‚ΡŒ Π»ΠΎΠ³ΠΈΠΊΠΈ ΠΏΠΈΡˆΠ΅Ρ‚ ИИ, Π²Π°ΠΆΠ½ΠΎ, Ρ‡Ρ‚ΠΎΠ±Ρ‹ систСма ΠΎΡΡ‚Π°Π²Π°Π»Π°ΡΡŒ Ρ‡Π΅Π»ΠΎΠ²Π΅ΠΊΠΎ-понятной ΠΈ Π΄Π΅Ρ‚Π΅Ρ€ΠΌΠΈΠ½ΠΈΡ€ΠΎΠ²Π°Π½Π½ΠΎΠΉ.
Π€ΡƒΠ½ΠΊΡ†ΠΈΠΎΠ½Π°Π»ΡŒΠ½ΠΎΠ΅ ядро обСспСчиваСт ΠΈΠΌΠ΅Π½Π½ΠΎ это β€” ΠΏΡ€ΠΎΠ·Ρ€Π°Ρ‡Π½ΠΎΡΡ‚ΡŒ, ΠΏΠΎΠ²Ρ‚ΠΎΡ€ΡΠ΅ΠΌΠΎΡΡ‚ΡŒ, ΠΊΠΎΠ½Ρ‚Ρ€ΠΎΠ»ΡŒ.

Π― ΠΏΡ€ΠΈΠΌΠ΅Π½ΡΡŽ Ρ‚Π°ΠΊΠΎΠΉ ΠΏΠΎΠ΄Ρ…ΠΎΠ΄ Π² своих ΠΏΡ€ΠΎΠ΅ΠΊΡ‚Π°Ρ… Π½Π° Python ΠΈ Go:
Π² микросСрвисах ядро Ρ€Π΅Π°Π»ΠΈΠ·ΠΎΠ²Π°Π½ΠΎ ΠΊΠ°ΠΊ чистыС Ρ„ΡƒΠ½ΠΊΡ†ΠΈΠΈ (бизнСс-ΠΏΡ€Π°Π²ΠΈΠ»Π°),
Π° ΠΎΠ±ΠΎΠ»ΠΎΡ‡ΠΊΠ° β€” ΠΊΠ°ΠΊ слой FastAPI, Kafka-Π²ΠΎΡ€ΠΊΠ΅Ρ€Ρ‹ ΠΈΠ»ΠΈ CLI-ΠΎΠ±Ρ€Π°Π±ΠΎΡ‚Ρ‡ΠΈΠΊΠΈ.
Π’Π°ΠΊ тСсты Π·Π°ΠΏΡƒΡΠΊΠ°ΡŽΡ‚ΡΡ ΠΌΠ³Π½ΠΎΠ²Π΅Π½Π½ΠΎ, Π° бизнСс-Π»ΠΎΠ³ΠΈΠΊΠ° Π½Π΅ зависит ΠΎΡ‚ сСтСвого стСка.

πŸ”— Π˜ΡΡ‚ΠΎΡ‡Π½ΠΈΠΊ