ПишСм Π³ΠΈΠ±ΠΊΠΈΠΉ ΠΊΠΎΠ΄, ΠΈΡΠΏΠΎΠ»ΡŒΠ·ΡƒΡ SOLID

ПишСм Π³ΠΈΠ±ΠΊΠΈΠΉ ΠΊΠΎΠ΄, ΠΈΡΠΏΠΎΠ»ΡŒΠ·ΡƒΡ SOLID

ΠžΡ‚ ΠΏΠ΅Ρ€Π΅Π²ΠΎΠ΄Ρ‡ΠΈΠΊΠ°: ΠΎΠΏΡƒΠ±Π»ΠΈΠΊΠΎΠ²Π°Π»ΠΈ для вас ΡΡ‚Π°Ρ‚ΡŒΡŽ Π‘Π΅Π²Π΅Ρ€ΠΈΠ½Π° ΠŸΠ΅Ρ€Π΅ΡΠ° ΠΎΠ± использовании ΠΏΡ€ΠΈΠ½Ρ†ΠΈΠΏΠΎΠ² SOLID Π² ΠΏΡ€ΠΎΠ³Ρ€Π°ΠΌΠΌΠΈΡ€ΠΎΠ²Π°Π½ΠΈΠΈ. Π˜Π½Ρ„ΠΎΡ€ΠΌΠ°Ρ†ΠΈΡ ΠΈΠ· ΡΡ‚Π°Ρ‚ΡŒΠΈ Π±ΡƒΠ΄Π΅Ρ‚ ΠΏΠΎΠ»Π΅Π·Π½Π° ΠΊΠ°ΠΊ Π½ΠΎΠ²ΠΈΡ‡ΠΊΠ°ΠΌ, Ρ‚Π°ΠΊ ΠΈ программистам с ΠΎΠΏΡ‹Ρ‚ΠΎΠΌ.

Если Π²Ρ‹ Π·Π°Π½ΠΈΠΌΠ°Π΅Ρ‚Π΅ΡΡŒ Ρ€Π°Π·Ρ€Π°Π±ΠΎΡ‚ΠΊΠΎΠΉ, Ρ‚ΠΎ, скорСС всСго, ΡΠ»Ρ‹ΡˆΠ°Π»ΠΈ ΠΎ ΠΏΡ€ΠΈΠ½Ρ†ΠΈΠΏΠ°Ρ… SOLID. Они Π΄Π°ΡŽΡ‚ Π²ΠΎΠ·ΠΌΠΎΠΆΠ½ΠΎΡΡ‚ΡŒ программисту ΠΏΠΈΡΠ°Ρ‚ΡŒ чистый, Ρ…ΠΎΡ€ΠΎΡˆΠΎ структурированный ΠΈ Π»Π΅Π³ΠΊΠΎ обслуТиваСмый ΠΊΠΎΠ΄. Π‘Ρ‚ΠΎΠΈΡ‚ ΠΎΡ‚ΠΌΠ΅Ρ‚ΠΈΡ‚ΡŒ, Ρ‡Ρ‚ΠΎ Π² ΠΏΡ€ΠΎΠ³Ρ€Π°ΠΌΠΌΠΈΡ€ΠΎΠ²Π°Π½ΠΈΠΈ Π΅ΡΡ‚ΡŒ нСсколько ΠΏΠΎΠ΄Ρ…ΠΎΠ΄ΠΎΠ² ΠΊ Ρ‚ΠΎΠΌΡƒ, ΠΊΠ°ΠΊ ΠΏΡ€Π°Π²ΠΈΠ»ΡŒΠ½ΠΎ Π²Ρ‹ΠΏΠΎΠ»Π½ΡΡ‚ΡŒ Ρ‚Ρƒ Π»ΠΈΠ±ΠΎ ΠΈΠ½ΡƒΡŽ Ρ€Π°Π±ΠΎΡ‚Ρƒ. Π£ Ρ€Π°Π·Π½Ρ‹Ρ… спСциалистов β€” Ρ€Π°Π·Π½Ρ‹Π΅ ΠΈΠ΄Π΅ΠΈ ΠΈ ΠΏΠΎΠ½ΠΈΠΌΠ°Π½ΠΈΠ΅ Β«ΠΏΡ€Π°Π²ΠΈΠ»ΡŒΠ½ΠΎΠ³ΠΎ ΠΏΡƒΡ‚ΠΈΒ», всС зависит ΠΎΡ‚ ΠΎΠΏΡ‹Ρ‚Π° ΠΊΠ°ΠΆΠ΄ΠΎΠ³ΠΎ. Π’Π΅ΠΌ Π½Π΅ ΠΌΠ΅Π½Π΅Π΅, ΠΈΠ΄Π΅ΠΈ, ΠΏΡ€ΠΎΠ²ΠΎΠ·Π³Π»Π°ΡˆΠ΅Π½Π½Ρ‹Π΅ Π² SOLID, ΠΏΡ€ΠΈΠ½ΠΈΠΌΠ°ΡŽΡ‚ΡΡ практичСски всСми прСдставитСлями ИВ-сообщСства. Они стали ΠΎΡ‚ΠΏΡ€Π°Π²Π½ΠΎΠΉ Ρ‚ΠΎΡ‡ΠΊΠΎΠΉ для появлСния ΠΈ развития мноТСства Ρ…ΠΎΡ€ΠΎΡˆΠΈΡ… ΠΌΠ΅Ρ‚ΠΎΠ΄ΠΎΠ² управлСния Ρ€Π°Π·Ρ€Π°Π±ΠΎΡ‚ΠΊΠΎΠΉ.

Π”Π°Π²Π°ΠΉΡ‚Π΅ разбСрСмся с Ρ‚Π΅ΠΌ, Ρ‡Ρ‚ΠΎ Ρ‚Π°ΠΊΠΎΠ΅ ΠΏΡ€ΠΈΠ½Ρ†ΠΈΠΏΡ‹ SOLID ΠΈ ΠΊΠ°ΠΊ ΠΎΠ½ΠΈ ΠΏΠΎΠΌΠΎΠ³Π°ΡŽΡ‚ Π½Π°ΠΌ.

Skillbox Ρ€Π΅ΠΊΠΎΠΌΠ΅Π½Π΄ΡƒΠ΅Ρ‚: ΠŸΡ€Π°ΠΊΡ‚ΠΈΡ‡Π΅ΡΠΊΠΈΠΉ курс Β«ΠœΠΎΠ±ΠΈΠ»ΡŒΠ½Ρ‹ΠΉ Ρ€Π°Π·Ρ€Π°Π±ΠΎΡ‚Ρ‡ΠΈΠΊ PROΒ».

НапоминаСм: для всСх Ρ‡ΠΈΡ‚Π°Ρ‚Π΅Π»Π΅ΠΉ Β«Π₯Π°Π±Ρ€Π°Β» β€” скидка 10 000 Ρ€ΡƒΠ±Π»Π΅ΠΉ ΠΏΡ€ΠΈ записи Π½Π° любой курс Skillbox ΠΏΠΎ ΠΏΡ€ΠΎΠΌΠΎΠΊΠΎΠ΄Ρƒ Β«Π₯Π°Π±Ρ€Β».

Π§Ρ‚ΠΎ Ρ‚Π°ΠΊΠΎΠ΅ SOLID?

Π­Ρ‚ΠΎΡ‚ Ρ‚Π΅Ρ€ΠΌΠΈΠ½ β€” Π°Π±Π±Ρ€Π΅Π²ΠΈΠ°Ρ‚ΡƒΡ€Π°, каТдая Π±ΡƒΠΊΠ²Π° Ρ‚Π΅Ρ€ΠΌΠΈΠ½Π° β€” Π½Π°Ρ‡Π°Π»ΠΎ названия ΠΎΠΏΡ€Π΅Π΄Π΅Π»Π΅Π½Π½ΠΎΠ³ΠΎ ΠΏΡ€ΠΈΠ½Ρ†ΠΈΠΏΠ°:

  • Single Responsibility Principle (ΠΏΡ€ΠΈΠ½Ρ†ΠΈΠΏ СдинствСнной отвСтствСнности). ΠœΠΎΠ΄ΡƒΠ»ΡŒ ΠΌΠΎΠΆΠ΅Ρ‚ ΠΈΠΌΠ΅Ρ‚ΡŒ ΠΎΠ΄Π½Ρƒ ΠΈ Ρ‚ΠΎΠ»ΡŒΠΊΠΎ ΠΎΠ΄Π½Ρƒ ΠΏΡ€ΠΈΡ‡ΠΈΠ½Ρƒ для измСнСния.
  • The Open/Closed Principle (ΠΏΡ€ΠΈΠ½Ρ†ΠΈΠΏ открытости/закрытости). ΠšΠ»Π°ΡΡΡ‹ ΠΈ Π΄Ρ€ΡƒΠ³ΠΈΠ΅ элСмСнты Π΄ΠΎΠ»ΠΆΠ½Ρ‹ Π±Ρ‹Ρ‚ΡŒ ΠΎΡ‚ΠΊΡ€Ρ‹Ρ‚Ρ‹ для Ρ€Π°ΡΡˆΠΈΡ€Π΅Π½ΠΈΡ, Π½ΠΎ Π·Π°ΠΊΡ€Ρ‹Ρ‚Ρ‹ для ΠΌΠΎΠ΄ΠΈΡ„ΠΈΠΊΠ°Ρ†ΠΈΠΈ.
  • β€ŠThe Liskov Substitution Principle (ΠΏΡ€ΠΈΠ½Ρ†ΠΈΠΏ подстановки Лисков). Π€ΡƒΠ½ΠΊΡ†ΠΈΠΈ, ΠΊΠΎΡ‚ΠΎΡ€Ρ‹Π΅ ΠΈΡΠΏΠΎΠ»ΡŒΠ·ΡƒΡŽΡ‚ Π±Π°Π·ΠΎΠ²Ρ‹ΠΉ Ρ‚ΠΈΠΏ, Π΄ΠΎΠ»ΠΆΠ½Ρ‹ ΠΈΠΌΠ΅Ρ‚ΡŒ Π²ΠΎΠ·ΠΌΠΎΠΆΠ½ΠΎΡΡ‚ΡŒ ΠΈΡΠΏΠΎΠ»ΡŒΠ·ΠΎΠ²Π°Ρ‚ΡŒ ΠΏΠΎΠ΄Ρ‚ΠΈΠΏΡ‹ Π±Π°Π·ΠΎΠ²ΠΎΠ³ΠΎ Ρ‚ΠΈΠΏΠ°, Π½Π΅ зная ΠΎΠ± этом.
  • The Interface Segregation Principleβ€Š (ΠΏΡ€ΠΈΠ½Ρ†ΠΈΠΏ раздСлСния интСрфСйса). ΠŸΡ€ΠΎΠ³Ρ€Π°ΠΌΠΌΠ½Ρ‹Π΅ сущности Π½Π΅ Π΄ΠΎΠ»ΠΆΠ½Ρ‹ Π·Π°Π²ΠΈΡΠ΅Ρ‚ΡŒ ΠΎΡ‚ ΠΌΠ΅Ρ‚ΠΎΠ΄ΠΎΠ², ΠΊΠΎΡ‚ΠΎΡ€Ρ‹Π΅ ΠΎΠ½ΠΈ Π½Π΅ ΠΈΡΠΏΠΎΠ»ΡŒΠ·ΡƒΡŽΡ‚.
  • The Dependency Inversion Principle (ΠΏΡ€ΠΈΠ½Ρ†ΠΈΠΏ инвСрсии зависимостСй). ΠœΠΎΠ΄ΡƒΠ»ΠΈ Π²Π΅Ρ€Ρ…Π½ΠΈΡ… ΡƒΡ€ΠΎΠ²Π½Π΅ΠΉ Π½Π΅ Π΄ΠΎΠ»ΠΆΠ½Ρ‹ Π·Π°Π²ΠΈΡΠ΅Ρ‚ΡŒ ΠΎΡ‚ ΠΌΠΎΠ΄ΡƒΠ»Π΅ΠΉ Π½ΠΈΠΆΠ½ΠΈΡ… ΡƒΡ€ΠΎΠ²Π½Π΅ΠΉ.

ΠŸΡ€ΠΈΠ½Ρ†ΠΈΠΏ СдинствСнной отвСтствСнности

β€Š
ΠŸΡ€ΠΈΠ½Ρ†ΠΈΠΏ Π΅Π΄ΠΈΠ½ΠΎΠΉ отвСтствСнности (SRP) гласит, Ρ‡Ρ‚ΠΎ ΠΊΠ°ΠΆΠ΄Ρ‹ΠΉ класс ΠΈΠ»ΠΈ ΠΌΠΎΠ΄ΡƒΠ»ΡŒ Π² ΠΏΡ€ΠΎΠ³Ρ€Π°ΠΌΠΌΠ΅ Π΄ΠΎΠ»ΠΆΠ΅Π½ нСсти ΠΎΡ‚Π²Π΅Ρ‚ΡΡ‚Π²Π΅Π½Π½ΠΎΡΡ‚ΡŒ Ρ‚ΠΎΠ»ΡŒΠΊΠΎ Π·Π° ΠΎΠ΄Π½Ρƒ Ρ‡Π°ΡΡ‚ΡŒ Ρ„ΡƒΠ½ΠΊΡ†ΠΈΠΎΠ½Π°Π»ΡŒΠ½ΠΎΡΡ‚ΠΈ этой ΠΏΡ€ΠΎΠ³Ρ€Π°ΠΌΠΌΡ‹. ΠšΡ€ΠΎΠΌΠ΅ Ρ‚ΠΎΠ³ΠΎ, элСмСнты этой отвСтствСнности Π΄ΠΎΠ»ΠΆΠ½Ρ‹ Π±Ρ‹Ρ‚ΡŒ Π·Π°ΠΊΡ€Π΅ΠΏΠ»Π΅Π½Ρ‹ Π·Π° своим классом, Π° Π½Π΅ распрСдСлСны ΠΏΠΎ нСсвязанным классам. Π Π°Π·Ρ€Π°Π±ΠΎΡ‚Ρ‡ΠΈΠΊ ΠΈ Π³Π»Π°Π²Π½Ρ‹ΠΉ СвангСлист SRP, Π ΠΎΠ±Π΅Ρ€Ρ‚ Π‘. ΠœΠ°Ρ€Ρ‚ΠΈΠ½, описываСт ΠΎΡ‚Π²Π΅Ρ‚ΡΡ‚Π²Π΅Π½Π½ΠΎΡΡ‚ΡŒ ΠΊΠ°ΠΊ ΠΏΡ€ΠΈΡ‡ΠΈΠ½Ρƒ ΠΏΠ΅Ρ€Π΅ΠΌΠ΅Π½. Π˜Π·Π½Π°Ρ‡Π°Π»ΡŒΠ½ΠΎ ΠΎΠ½ ΠΏΡ€Π΅Π΄Π»ΠΎΠΆΠΈΠ» этот Ρ‚Π΅Ρ€ΠΌΠΈΠ½ Π² качСствС ΠΎΠ΄Π½ΠΎΠ³ΠΎ ΠΈΠ· элСмСнтов своСй Ρ€Π°Π±ΠΎΡ‚Ρ‹ Β«ΠŸΡ€ΠΈΠ½Ρ†ΠΈΠΏΡ‹ ΠΎΠ±ΡŠΠ΅ΠΊΡ‚Π½ΠΎ-ΠΎΡ€ΠΈΠ΅Π½Ρ‚ΠΈΡ€ΠΎΠ²Π°Π½Π½ΠΎΠ³ΠΎ проСктирования». Π’ ΠΊΠΎΠ½Ρ†Π΅ΠΏΡ†ΠΈΡŽ вошло ΠΌΠ½ΠΎΠ³ΠΎΠ΅ ΠΈΠ· закономСрности связности, которая Π±Ρ‹Π»Π° ΠΎΠΏΡ€Π΅Π΄Π΅Π»Π΅Π½Π° Ρ€Π°Π½Π΅Π΅ Π’ΠΎΠΌΠΎΠΌ Π”Π΅ΠΌΠ°Ρ€ΠΊΠΎ.

Π•Ρ‰Π΅ Π² ΠΊΠΎΠ½Ρ†Π΅ΠΏΡ†ΠΈΡŽ вошли нСсколько понятий, сформулированных Дэвидом ΠŸΠ°Ρ€Π½Π°ΡΠΎΠΌ. Π”Π²Π° основных β€” инкапсуляция ΠΈ сокрытиС ΠΈΠ½Ρ„ΠΎΡ€ΠΌΠ°Ρ†ΠΈΠΈ. ΠŸΠ°Ρ€Π½Π°Ρ ΡƒΡ‚Π²Π΅Ρ€ΠΆΠ΄Π°Π», Ρ‡Ρ‚ΠΎ Ρ€Π°Π·Π΄Π΅Π»Π΅Π½ΠΈΠ΅ систСмы Π½Π° ΠΎΡ‚Π΄Π΅Π»ΡŒΠ½Ρ‹Π΅ ΠΌΠΎΠ΄ΡƒΠ»ΠΈ Π½Π΅ Π΄ΠΎΠ»ΠΆΠ½ΠΎ Π±Π°Π·ΠΈΡ€ΠΎΠ²Π°Ρ‚ΡŒΡΡ Π½Π° Π°Π½Π°Π»ΠΈΠ·Π΅ Π±Π»ΠΎΠΊ-схСм Π»ΠΈΠ±ΠΎ ΠΏΠΎΡ‚ΠΎΠΊΠΎΠ² исполнСния. Π›ΡŽΠ±ΠΎΠΉ ΠΈΠ· ΠΌΠΎΠ΄ΡƒΠ»Π΅ΠΉ Π΄ΠΎΠ»ΠΆΠ΅Π½ ΡΠΎΠ΄Π΅Ρ€ΠΆΠ°Ρ‚ΡŒ ΠΎΠΏΡ€Π΅Π΄Π΅Π»Π΅Π½Π½ΠΎΠ΅ Ρ€Π΅ΡˆΠ΅Π½ΠΈΠ΅, ΠΊΠΎΡ‚ΠΎΡ€ΠΎΠ΅ прСдоставляСт ΠΌΠΈΠ½ΠΈΠΌΡƒΠΌ ΠΈΠ½Ρ„ΠΎΡ€ΠΌΠ°Ρ†ΠΈΠΈ ΠΊΠ»ΠΈΠ΅Π½Ρ‚Π°ΠΌ.

ΠšΡΡ‚Π°Ρ‚ΠΈ, ΠœΠ°Ρ€Ρ‚ΠΈΠ½ ΠΏΡ€ΠΈΠ²ΠΎΠ΄ΠΈΠ» интСрСсный ΠΏΡ€ΠΈΠΌΠ΅Ρ€ с Π²Ρ‹ΡΡˆΠΈΠΌΠΈ ΠΌΠ΅Π½Π΅Π΄ΠΆΠ΅Ρ€Π°ΠΌΠΈ ΠΊΠΎΠΌΠΏΠ°Π½ΠΈΠΈ (COO, CTO, CFO), ΠΊΠ°ΠΆΠ΄Ρ‹ΠΉ ΠΈΠ· ΠΊΠΎΡ‚ΠΎΡ€Ρ‹Ρ… примСняСт спСцифичСскоС ΠΏΡ€ΠΎΠ³Ρ€Π°ΠΌΠΌΠ½ΠΎΠ΅ обСспСчСниС для бизнСса с Ρ€Π°Π·Π½ΠΎΠΉ Ρ†Π΅Π»ΡŒΡŽ. Π’ ΠΈΡ‚ΠΎΠ³Π΅ любой ΠΈΠ· Π½ΠΈΡ… ΠΌΠΎΠΆΠ΅Ρ‚ Π²Π½Π΅Π΄Ρ€ΡΡ‚ΡŒ измСнСния Π² ПО, Π½Π΅ затрагивая интСрСсы Π΄Ρ€ΡƒΠ³ΠΈΡ… ΠΌΠ΅Π½Π΅Π΄ΠΆΠ΅Ρ€ΠΎΠ².

БоТСствСнный ΠΎΠ±ΡŠΠ΅ΠΊΡ‚

Как ΠΎΠ±Ρ‹Ρ‡Π½ΠΎ, Π»ΡƒΡ‡ΡˆΠΈΠΉ способ ΠΈΠ·ΡƒΡ‡ΠΈΡ‚ΡŒ SRP β€” это ΡƒΠ²ΠΈΠ΄Π΅Ρ‚ΡŒ всС Π² дСйствии. Π”Π°Π²Π°ΠΉΡ‚Π΅ посмотрим Π½Π° участок ΠΏΡ€ΠΎΠ³Ρ€Π°ΠΌΠΌΡ‹, которая НЕ соотвСтствуСт ΠΏΡ€ΠΈΠ½Ρ†ΠΈΠΏΡƒ Π΅Π΄ΠΈΠ½ΠΎΠΉ отвСтствСнности. Π­Ρ‚ΠΎ Ruby-ΠΊΠΎΠ΄, ΠΎΠΏΠΈΡΡ‹Π²Π°ΡŽΡ‰ΠΈΠΉ ΠΏΠΎΠ²Π΅Π΄Π΅Π½ΠΈΠ΅ ΠΈ Π°Ρ‚Ρ€ΠΈΠ±ΡƒΡ‚Ρ‹ космичСской станции.

ΠŸΡ€ΠΎΡΠΌΠΎΡ‚Ρ€ΠΈΡ‚Π΅ ΠΏΡ€ΠΈΠΌΠ΅Ρ€ ΠΈ ΠΏΠΎΠΏΡ€ΠΎΠ±ΡƒΠΉΡ‚Π΅ ΠΎΠΏΡ€Π΅Π΄Π΅Π»ΠΈΡ‚ΡŒ ΡΠ»Π΅Π΄ΡƒΡŽΡ‰Π΅Π΅:
ΠžΠ±ΡΠ·Π°Π½Π½ΠΎΡΡ‚ΠΈ Ρ‚Π΅Ρ… ΠΎΠ±ΡŠΠ΅ΠΊΡ‚ΠΎΠ², ΠΊΠΎΡ‚ΠΎΡ€Ρ‹Π΅ ΠΏΡ€ΠΎΠ²ΠΎΠ·Π³Π»Π°ΡˆΠ΅Π½Ρ‹ Π² классС SpaceStation.
Π’Π΅Ρ…, ΠΊΡ‚ΠΎ ΠΌΠΎΠΆΠ΅Ρ‚ Π±Ρ‹Ρ‚ΡŒ заинтСрСсован Π² Ρ€Π°Π±ΠΎΡ‚Π΅ космичСской станции.

class SpaceStation
  def initialize
    @supplies = {}
    @fuel = 0
  end
 
  def run_sensors
    puts "----- Sensor Action -----"
    puts "Running sensors!"
  end
 
  def load_supplies(type, quantity)
    puts "----- Supply Action -----"
    puts "Loading #{quantity} units of #{type} in the supply hold."
    
    if @supplies[type]
      @supplies[type] += quantity
    else
      @supplies[type] = quantity
    end
  end
 
  def use_supplies(type, quantity)
    puts "----- Supply Action -----"
    if @supplies[type] != nil && @supplies[type] > quantity
      puts "Using #{quantity} of #{type} from the supply hold."
      @supplies[type] -= quantity
    else
      puts "Supply Error: Insufficient #{type} in the supply hold."
    end
  end
 
  def report_supplies
    puts "----- Supply Report -----"
    if @supplies.keys.length > 0
      @supplies.each do |type, quantity|
        puts "#{type} avalilable: #{quantity} units"
      end
    else
      puts "Supply hold is empty."
    end
  end
 
  def load_fuel(quantity)
    puts "----- Fuel Action -----"
    puts "Loading #{quantity} units of fuel in the tank."
    @fuel += quantity
  end
 
  def report_fuel
    puts "----- Fuel Report -----"
    puts "#{@fuel} units of fuel available."
  end
 
  def activate_thrusters
    puts "----- Thruster Action -----"
    if @fuel >= 10
      puts "Thrusting action successful."
      @fuel -= 10
    else
      puts "Thruster Error: Insufficient fuel available."
    end
  end
end

БобствСнно, наша космичСская станция Π½Π΅Ρ„ΡƒΠ½ΠΊΡ†ΠΈΠΎΠ½Π°Π»ΡŒΠ½Π° (Π΄ΡƒΠΌΠ°ΡŽ, Ρ‡Ρ‚ΠΎ Π½Π΅ ΠΏΠΎΠ»ΡƒΡ‡Ρƒ Π·Π²ΠΎΠ½ΠΎΠΊ ΠΎΡ‚ НАБА Π² блиТайшСм ΠΎΠ±ΠΎΠ·Ρ€ΠΈΠΌΠΎΠΌ Π±ΡƒΠ΄ΡƒΡ‰Π΅ΠΌ), Π½ΠΎ здСсь Π΅ΡΡ‚ΡŒ Ρ‡Ρ‚ΠΎ ΠΏΡ€ΠΎΠ°Π½Π°Π»ΠΈΠ·ΠΈΡ€ΠΎΠ°Ρ‚ΡŒ.

Π’Π°ΠΊ, Ρƒ класса SpaceStation Π΅ΡΡ‚ΡŒ нСсколько Ρ€Π°Π·Π»ΠΈΡ‡Π½Ρ‹Ρ… отвСтствСнностСй (ΠΈΠ»ΠΈ Π·Π°Π΄Π°Ρ‡). ВсС ΠΎΠ½ΠΈ ΠΌΠΎΠ³ΡƒΡ‚ Π±Ρ‹Ρ‚ΡŒ Ρ€Π°Π·Π±ΠΈΡ‚Ρ‹ ΠΏΠΎ Ρ‚ΠΈΠΏΠ°ΠΌ:

  • сСнсоры;
  • снабТСниС (расходники);
  • Π³ΠΎΡ€ΡŽΡ‡Π΅Π΅;
  • ускоритСли.

НСсмотря Π½Π° Ρ‚ΠΎ, Ρ‡Ρ‚ΠΎ Π½ΠΈΠΊΡ‚ΠΎ ΠΈΠ· сотрудников станции Π½Π΅ ΠΎΠΏΡ€Π΅Π΄Π΅Π»Π΅Π½ Π² классС, ΠΌΡ‹ ΠΌΠΎΠΆΠ΅ΠΌ с Π»Π΅Π³ΠΊΠΎΡΡ‚ΡŒΡŽ ΠΏΡ€Π΅Π΄ΡΡ‚Π°Π²ΠΈΡ‚ΡŒ, ΠΊΡ‚ΠΎ Π·Π° Ρ‡Ρ‚ΠΎ ΠΎΡ‚Π²Π΅Ρ‡Π°Π΅Ρ‚. Π‘ΠΊΠΎΡ€Π΅Π΅ всСго, Π½Π°ΡƒΡ‡Π½Ρ‹ΠΉ Ρ€Π°Π±ΠΎΡ‚Π½ΠΈΠΊ ΠΊΠΎΠ½Ρ‚Ρ€ΠΎΠ»ΠΈΡ€ΡƒΠ΅Ρ‚ сСнсоры, логист ΠΎΡ‚Π²Π΅Ρ‡Π°Π΅Ρ‚ Π·Π° снабТСниС рСсурсами, ΠΈΠ½ΠΆΠ΅Π½Π΅Ρ€ ΠΎΡ‚Π²Π΅Ρ‡Π°Π΅Ρ‚ Π·Π° запасы Ρ‚ΠΎΠΏΠ»ΠΈΠ²Π°, Π° ΠΏΠΈΠ»ΠΎΡ‚ ΠΊΠΎΠ½Ρ‚Ρ€ΠΎΠ»ΠΈΡ€ΡƒΠ΅Ρ‚ ускоритСли.

МоТСм Π»ΠΈ ΠΌΡ‹ ΡΠΊΠ°Π·Π°Ρ‚ΡŒ, Ρ‡Ρ‚ΠΎ эта ΠΏΡ€ΠΎΠ³Ρ€Π°ΠΌΠΌΠ° Π½Π΅ соотвСтствуСт SRP? Π”Π°, ΠΊΠΎΠ½Π΅Ρ‡Π½ΠΎ. Но класс SpaceStation являСтся Ρ‚ΠΈΠΏΠΈΡ‡Π½Ρ‹ΠΌ «боТСствСнным ΠΎΠ±ΡŠΠ΅ΠΊΡ‚ΠΎΠΌΒ», ΠΊΠΎΡ‚ΠΎΡ€Ρ‹ΠΉ Π·Π½Π°Π΅Ρ‚ ΠΎΠ±ΠΎ всСм ΠΈ Π΄Π΅Π»Π°Π΅Ρ‚ всС. Π­Ρ‚ΠΎ основной Π°Π½Ρ‚ΠΈΡˆΠ°Π±Π»ΠΎΠ½ Π² ΠΎΠ±ΡŠΠ΅ΠΊΡ‚Π½ΠΎ-ΠΎΡ€ΠΈΠ΅Π½Ρ‚ΠΈΡ€ΠΎΠ²Π°Π½Π½ΠΎΠΌ ΠΏΡ€ΠΎΠ³Ρ€Π°ΠΌΠΌΠΈΡ€ΠΎΠ²Π°Π½ΠΈΠΈ. Для Π½ΠΎΠ²ΠΈΡ‡ΠΊΠ° Ρ‚Π°ΠΊΠΈΠ΅ ΠΎΠ±ΡŠΠ΅ΠΊΡ‚Ρ‹ Ρ‡Ρ€Π΅Π·Π²Ρ‹Ρ‡Π°ΠΉΠ½ΠΎ слоТны Π² обслуТивании. Пока Ρ‡Ρ‚ΠΎ ΠΏΡ€ΠΎΠ³Ρ€Π°ΠΌΠΌΠ° ΠΎΡ‡Π΅Π½ΡŒ простая, Π΄Π°, Π½ΠΎ ΠΏΡ€Π΅Π΄ΡΡ‚Π°Π²ΡŒΡ‚Π΅, Ρ‡Ρ‚ΠΎ ΠΏΡ€ΠΎΠΈΠ·ΠΎΠΉΠ΄Π΅Ρ‚, Ссли ΠΌΡ‹ Π΄ΠΎΠ±Π°Π²ΠΈΠΌ Π½ΠΎΠ²Ρ‹Π΅ Ρ„ΡƒΠ½ΠΊΡ†ΠΈΠΈ. Π’ΠΎΠ·ΠΌΠΎΠΆΠ½ΠΎ, нашСй космичСской станции понадобится ΠΌΠ΅Π΄ΠΏΡƒΠ½ΠΊΡ‚ ΠΈΠ»ΠΈ пСрСговорная ΠΊΠΎΠΌΠ½Π°Ρ‚Π°. И Ρ‡Π΅ΠΌ большС Π±ΡƒΠ΄Π΅Ρ‚ Ρ„ΡƒΠ½ΠΊΡ†ΠΈΠΉ, Ρ‚Π΅ΠΌ сильнСС вырастСт SpaceStation. Ну Π° ΠΏΠΎΡΠΊΠΎΠ»ΡŒΠΊΡƒ этот ΠΎΠ±ΡŠΠ΅ΠΊΡ‚ Π±ΡƒΠ΄Π΅Ρ‚ связан с Π΄Ρ€ΡƒΠ³ΠΈΠΌΠΈ, Ρ‚ΠΎ обслуТиваниС всСго комплСкса станСт Π΅Ρ‰Π΅ Π±ΠΎΠ»Π΅Π΅ слоТным. Π’ ΠΈΡ‚ΠΎΠ³Π΅ ΠΌΡ‹ ΠΌΠΎΠΆΠ΅ΠΌ Π½Π°Ρ€ΡƒΡˆΠΈΡ‚ΡŒ Ρ€Π°Π±ΠΎΡ‚Ρƒ, ΠΊ ΠΏΡ€ΠΈΠΌΠ΅Ρ€Ρƒ, ускоритСлСй. Если Π½Π°ΡƒΡ‡Π½Ρ‹ΠΉ сотрудник запросит ΠΈΠ·ΠΌΠ΅Π½Π΅Π½ΠΈΠΉ Π² Ρ€Π°Π±ΠΎΡ‚Π΅ с сСнсорами, Ρ‚ΠΎ это Π²ΠΏΠΎΠ»Π½Π΅ ΠΌΠΎΠΆΠ΅Ρ‚ ΠΏΠΎΠ²Π»ΠΈΡΡ‚ΡŒ Π½Π° систСмы связи станции.

ΠΠ°Ρ€ΡƒΡˆΠ΅Π½ΠΈΠ΅ SRP-ΠΏΡ€ΠΈΠ½Ρ†ΠΈΠΏΠ° ΠΌΠΎΠΆΠ΅Ρ‚ Π΄Π°Ρ‚ΡŒ ΠΊΡ€Π°Ρ‚ΠΊΠΎΠ²Ρ€Π΅ΠΌΠ΅Π½Π½ΡƒΡŽ Ρ‚Π°ΠΊΡ‚ΠΈΡ‡Π΅ΡΠΊΡƒΡŽ ΠΏΠΎΠ±Π΅Π΄Ρƒ, Π½ΠΎ Π² ΠΈΡ‚ΠΎΠ³Π΅ ΠΌΡ‹ Β«ΠΏΡ€ΠΎΠΈΠ³Ρ€Π°Π΅ΠΌ Π²ΠΎΠΉΠ½ΡƒΒ», ΠΎΠ±ΡΠ»ΡƒΠΆΠΈΠ²Π°Ρ‚ΡŒ Ρ‚Π°ΠΊΠΎΠ³ΠΎ монстра Π² Π±ΡƒΠ΄ΡƒΡ‰Π΅ΠΌ станСт вСсьма нСпросто. Π›ΡƒΡ‡ΡˆΠ΅ всСго Ρ€Π°Π·Π΄Π΅Π»ΠΈΡ‚ΡŒ ΠΏΡ€ΠΎΠ³Ρ€Π°ΠΌΠΌΡƒ Π½Π° ΠΎΡ‚Π΄Π΅Π»ΡŒΠ½Ρ‹Π΅ участки ΠΊΠΎΠ΄Π°, ΠΊΠ°ΠΆΠ΄Ρ‹ΠΉ ΠΈΠ· ΠΊΠΎΡ‚ΠΎΡ€Ρ‹Ρ… ΠΎΡ‚Π²Π΅Ρ‡Π°Π΅Ρ‚ Π·Π° Π²Ρ‹ΠΏΠΎΠ»Π½Π΅Π½ΠΈΠ΅ ΠΎΠΏΡ€Π΅Π΄Π΅Π»Π΅Π½Π½ΠΎΠΉ ΠΎΠΏΠ΅Ρ€Π°Ρ†ΠΈΠΈ. Понимая это, Π΄Π°Π²Π°ΠΉΡ‚Π΅ ΠΈΠ·ΠΌΠ΅Π½ΠΈΠΌ класс SpaceStation.

РаспрСдСлим ΠΎΡ‚Π²Π΅Ρ‚ΡΡ‚Π²Π΅Π½Π½ΠΎΡΡ‚ΡŒ

Π’Ρ‹ΡˆΠ΅ ΠΌΡ‹ ΠΎΠΏΡ€Π΅Π΄Π΅Π»ΠΈΠ»ΠΈ Ρ‡Π΅Ρ‚Ρ‹Ρ€Π΅ Ρ‚ΠΈΠΏΠ° ΠΎΠΏΠ΅Ρ€Π°Ρ†ΠΈΠΉ, ΠΊΠΎΡ‚ΠΎΡ€Ρ‹Π΅ ΠΊΠΎΠ½Ρ‚Ρ€ΠΎΠ»ΠΈΡ€ΡƒΡŽΡ‚ΡΡ классом SpaceStation. ΠŸΡ€ΠΈ Ρ€Π΅Ρ„Π°ΠΊΡ‚ΠΎΡ€ΠΈΠ½Π³Π΅ ΠΌΡ‹ Π±ΡƒΠ΄Π΅ΠΌ ΠΈΠΌΠ΅Ρ‚ΡŒ ΠΈΡ… Π² Π²ΠΈΠ΄Ρƒ. ΠžΠ±Π½ΠΎΠ²Π»Π΅Π½Π½Ρ‹ΠΉ ΠΊΠΎΠ΄ Π»ΡƒΡ‡ΡˆΠ΅ соотвСтствуСт SRP.

class SpaceStation
  attr_reader :sensors, :supply_hold, :fuel_tank, :thrusters
 
  def initialize
    @supply_hold = SupplyHold.new
    @sensors = Sensors.new
    @fuel_tank = FuelTank.new
    @thrusters = Thrusters.new(@fuel_tank)
  end
end
 
class Sensors
  def run_sensors
    puts "----- Sensor Action -----"
    puts "Running sensors!"
  end
end
 
class SupplyHold
  attr_accessor :supplies
 
  def initialize
    @supplies = {}
  end
 
  def load_supplies(type, quantity)
    puts "----- Supply Action -----"
    puts "Loading #{quantity} units of #{type} in the supply hold."
    
    if @supplies[type]
      @supplies[type] += quantity
    else
      @supplies[type] = quantity
    end
  end
 
  def use_supplies(type, quantity)
    puts "----- Supply Action -----"
    if @supplies[type] != nil && @supplies[type] > quantity
      puts "Using #{quantity} of #{type} from the supply hold."
      @supplies[type] -= quantity
    else
      puts "Supply Error: Insufficient #{type} in the supply hold."
    end
  end
 
  def report_supplies
    puts "----- Supply Report -----"
    if @supplies.keys.length > 0
      @supplies.each do |type, quantity|
        puts "#{type} avalilable: #{quantity} units"
      end
    else
      puts "Supply hold is empty."
    end
  end
end
 
class FuelTank
  attr_accessor :fuel
 
  def initialize
    @fuel = 0
  end
 
  def get_fuel_levels
    @fuel
  end
 
  def load_fuel(quantity)
    puts "----- Fuel Action -----"
    puts "Loading #{quantity} units of fuel in the tank."
    @fuel += quantity
  end
 
  def use_fuel(quantity)
    puts "----- Fuel Action -----"
    puts "Using #{quantity} units of fuel from the tank."
    @fuel -= quantity
  end
 
  def report_fuel
    puts "----- Fuel Report -----"
    puts "#{@fuel} units of fuel available."
  end
end
 
class Thrusters
  def initialize(fuel_tank)
    @linked_fuel_tank = fuel_tank
  end
 
  def activate_thrusters
    puts "----- Thruster Action -----"
    if @linked_fuel_tank.get_fuel_levels >= 10
      puts "Thrusting action successful."
      @linked_fuel_tank.use_fuel(10)
    else
      puts "Thruster Error: Insufficient fuel available."
    end
  end
end

ИзмСнСний ΠΌΠ½ΠΎΠ³ΠΎ, ΠΏΡ€ΠΎΠ³Ρ€Π°ΠΌΠΌΠ° Ρ‚Π΅ΠΏΠ΅Ρ€ΡŒ выглядит ΠΎΠΏΡ€Π΅Π΄Π΅Π»Π΅Π½Π½ΠΎ Π»ΡƒΡ‡ΡˆΠ΅. БСйчас наш класс SpaceStation стал, скорСС, ΠΊΠΎΠ½Ρ‚Π΅ΠΉΠ½Π΅Ρ€ΠΎΠΌ, Π² ΠΊΠΎΡ‚ΠΎΡ€ΠΎΠΌ ΠΈΠ½ΠΈΡ†ΠΈΠΈΡ€ΡƒΡŽΡ‚ΡΡ ΠΎΠΏΠ΅Ρ€Π°Ρ†ΠΈΠΈ для зависимых частСй, Π²ΠΊΠ»ΡŽΡ‡Π°Ρ Π½Π°Π±ΠΎΡ€ сСнсоров, систСму ΠΏΠΎΠ΄Π°Ρ‡ΠΈ расходных ΠΌΠ°Ρ‚Π΅Ρ€ΠΈΠ°Π»ΠΎΠ², Ρ‚ΠΎΠΏΠ»ΠΈΠ²Π½Ρ‹ΠΉ Π±Π°ΠΊ, ускоритСли.

Для любой ΠΈΠ· ΠΏΠ΅Ρ€Π΅ΠΌΠ΅Π½Π½Ρ‹Ρ… Ρ‚Π΅ΠΏΠ΅Ρ€ΡŒ Π΅ΡΡ‚ΡŒ ΡΠΎΠΎΡ‚Π²Π΅Ρ‚ΡΡ‚Π²ΡƒΡŽΡ‰ΠΈΠΉ класс: Sensors; SupplyHold; FuelTank; Thrusters.

Π’ этой вСрсии ΠΊΠΎΠ΄Π° Π΅ΡΡ‚ΡŒ нСсколько Π²Π°ΠΆΠ½Ρ‹Ρ… ΠΈΠ·ΠΌΠ΅Π½Π΅Π½ΠΈΠΉ. Π”Π΅Π»ΠΎ Π² Ρ‚ΠΎΠΌ, Ρ‡Ρ‚ΠΎ ΠΎΡ‚Π΄Π΅Π»ΡŒΠ½Ρ‹Π΅ Ρ„ΡƒΠ½ΠΊΡ†ΠΈΠΈ Π½Π΅ Ρ‚ΠΎΠ»ΡŒΠΊΠΎ инкапсулированы Π² собствСнныС классы, ΠΎΠ½ΠΈ ΠΎΡ€Π³Π°Π½ΠΈΠ·ΠΎΠ²Π°Π½Ρ‹ Ρ‚Π°ΠΊΠΈΠΌ ΠΎΠ±Ρ€Π°Π·ΠΎΠΌ, Ρ‡Ρ‚ΠΎΠ±Ρ‹ ΡΡ‚Π°Ρ‚ΡŒ прСдсказуСмыми ΠΈ ΠΏΠΎΡΠ»Π΅Π΄ΠΎΠ²Π°Ρ‚Π΅Π»ΡŒΠ½Ρ‹ΠΌΠΈ. ΠœΡ‹ Π³Ρ€ΡƒΠΏΠΏΠΈΡ€ΡƒΠ΅ΠΌ сходныС ΠΏΠΎ Ρ„ΡƒΠ½ΠΊΡ†ΠΈΠΎΠ½Π°Π»ΡŒΠ½ΠΎΡΡ‚ΠΈ элСмСнты для слСдования ΠΏΡ€ΠΈΠ½Ρ†ΠΈΠΏΠ° связности. Π’Π΅ΠΏΠ΅Ρ€ΡŒ, Ссли Π½Π°ΠΌ понадобится ΠΈΠ·ΠΌΠ΅Π½ΠΈΡ‚ΡŒ ΠΏΡ€ΠΈΠ½Ρ†ΠΈΠΏ Ρ€Π°Π±ΠΎΡ‚Ρ‹ систСмы, пСрСйдя с Ρ…ΡΡˆ-структуры Π½Π° массив, просто Π²ΠΎΡΠΏΠΎΠ»ΡŒΠ·ΡƒΠΉΡ‚Π΅ΡΡŒ классом SupplyHold, Π·Π°Ρ‚Ρ€Π°Π³ΠΈΠ²Π°Ρ‚ΡŒ Π΄Ρ€ΡƒΠ³ΠΈΠ΅ ΠΌΠΎΠ΄ΡƒΠ»ΠΈ Π½Π΅ придСтся. Π’Π°ΠΊΠΈΠΌ ΠΎΠ±Ρ€Π°Π·ΠΎΠΌ, Ссли ΠΎΡ„ΠΈΡ†Π΅Ρ€, отвСтствСнный Π·Π° логистику, Ρ‡Ρ‚ΠΎ-Ρ‚ΠΎ ΠΈΠ·ΠΌΠ΅Π½ΠΈΡ‚ Π² своСй сСкции, ΠΎΡΡ‚Π°Π»ΡŒΠ½Ρ‹Π΅ элСмСнты станции останутся Π½Π΅Ρ‚Ρ€ΠΎΠ½ΡƒΡ‚Ρ‹ΠΌΠΈ. ΠŸΡ€ΠΈ этом класс SpaceStation Π΄Π°ΠΆΠ΅ Π½Π΅ Π±ΡƒΠ΄Π΅Ρ‚ Π² курсС ΠΈΠ·ΠΌΠ΅Π½Π΅Π½ΠΈΠΉ.

Наши ΠΎΡ„ΠΈΡ†Π΅Ρ€Ρ‹, Ρ€Π°Π±ΠΎΡ‚Π°ΡŽΡ‰ΠΈΠ΅ Π½Π° космичСской станции, вСроятно, Ρ€Π°Π΄Ρ‹ измСнСниям, ΠΏΠΎΡΠΊΠΎΠ»ΡŒΠΊΡƒ ΠΌΠΎΠ³ΡƒΡ‚ Π·Π°ΠΏΡ€Π°ΡˆΠΈΠ²Π°Ρ‚ΡŒ Ρ‚Π΅, ΠΊΠΎΡ‚ΠΎΡ€Ρ‹Π΅ Π½Π΅ΠΎΠ±Ρ…ΠΎΠ΄ΠΈΠΌΡ‹ ΠΈΠΌΠ΅Π½Π½ΠΎ ΠΈΠΌ. ΠžΠ±Ρ€Π°Ρ‚ΠΈΡ‚Π΅ Π²Π½ΠΈΠΌΠ°Π½ΠΈΠ΅, Ρ‡Ρ‚ΠΎ Π² ΠΊΠΎΠ΄Π΅ Π΅ΡΡ‚ΡŒ Ρ‚Π°ΠΊΠΈΠ΅ ΠΌΠ΅Ρ‚ΠΎΠ΄Ρ‹, ΠΊΠ°ΠΊ report_supplies ΠΈ report_fuel, содСрТащиСся Π² классах SupplyHold ΠΈ FuelTank. Π§Ρ‚ΠΎ случится, Ссли ЗСмля попросит ΠΈΠ·ΠΌΠ΅Π½ΠΈΡ‚ΡŒ способ формирования ΠΎΡ‚Ρ‡Π΅Ρ‚ΠΎΠ²? НСобходимо Π±ΡƒΠ΄Π΅Ρ‚ ΠΈΠ·ΠΌΠ΅Π½ΠΈΡ‚ΡŒ ΠΎΠ±Π° класса, SupplyHold ΠΈ FuelTank. А Ρ‡Ρ‚ΠΎ, Ссли Π½ΡƒΠΆΠ½ΠΎ Π±ΡƒΠ΄Π΅Ρ‚ ΠΈΠ·ΠΌΠ΅Π½ΠΈΡ‚ΡŒ способ доставки Ρ‚ΠΎΠΏΠ»ΠΈΠ²Π° ΠΈ расходников? ВСроятно, придСтся снова ΠΈΠ·ΠΌΠ΅Π½ΠΈΡ‚ΡŒ всС Ρ‚Π΅ ΠΆΠ΅ классы. А это ΡƒΠΆΠ΅ Π½Π°Ρ€ΡƒΡˆΠ΅Π½ΠΈΠ΅ SRP-ΠΏΡ€ΠΈΠ½Ρ†ΠΈΠΏΠ°. Π”Π°Π²Π°ΠΉΡ‚Π΅ это исправим.

class SpaceStation
  attr_reader :sensors, :supply_hold, :supply_reporter,
              :fuel_tank, :fuel_reporter, :thrusters
 
  def initialize
    @sensors = Sensors.new
    @supply_hold = SupplyHold.new
    @supply_reporter = SupplyReporter.new(@supply_hold)
    @fuel_tank = FuelTank.new
    @fuel_reporter = FuelReporter.new(@fuel_tank)
    @thrusters = Thrusters.new(@fuel_tank)
  end
end
 
class Sensors
  def run_sensors
    puts "----- Sensor Action -----"
    puts "Running sensors!"
  end
end
 
class SupplyHold
  attr_accessor :supplies
  attr_reader :reporter
 
  def initialize
    @supplies = {}
  end
 
  def get_supplies
    @supplies
  end
 
  def load_supplies(type, quantity)
    puts "----- Supply Action -----"
    puts "Loading #{quantity} units of #{type} in the supply hold."
    
    if @supplies[type]
      @supplies[type] += quantity
    else
      @supplies[type] = quantity
    end
  end
 
  def use_supplies(type, quantity)
    puts "----- Supply Action -----"
    if @supplies[type] != nil && @supplies[type] > quantity
      puts "Using #{quantity} of #{type} from the supply hold."
      @supplies[type] -= quantity
    else
      puts "Supply Error: Insufficient #{type} in the supply hold."
    end
  end
end
 
class FuelTank
  attr_accessor :fuel
  attr_reader :reporter
 
  def initialize
    @fuel = 0
  end
 
  def get_fuel_levels
    @fuel
  end
 
  def load_fuel(quantity)
    puts "----- Fuel Action -----"
    puts "Loading #{quantity} units of fuel in the tank."
    @fuel += quantity
  end
 
  def use_fuel(quantity)
    puts "----- Fuel Action -----"
    puts "Using #{quantity} units of fuel from the tank."
    @fuel -= quantity
  end
end
 
class Thrusters
  FUEL_PER_THRUST = 10
 
  def initialize(fuel_tank)
    @linked_fuel_tank = fuel_tank
  end
 
  def activate_thrusters
    puts "----- Thruster Action -----"
    
    if @linked_fuel_tank.get_fuel_levels >= FUEL_PER_THRUST
      puts "Thrusting action successful."
      @linked_fuel_tank.use_fuel(FUEL_PER_THRUST)
    else
      puts "Thruster Error: Insufficient fuel available."
    end
  end
end
 
class Reporter
  def initialize(item, type)
    @linked_item = item
    @type = type
  end
 
  def report
    puts "----- #{@type.capitalize} Report -----"
  end
end
 
class FuelReporter < Reporter
  def initialize(item)
    super(item, "fuel")
  end
 
  def report
    super
    puts "#{@linked_item.get_fuel_levels} units of fuel available."
  end
end
 
class SupplyReporter < Reporter
  def initialize(item)
    super(item, "supply")
  end
 
  def report
    super
    if @linked_item.get_supplies.keys.length > 0
      @linked_item.get_supplies.each do |type, quantity|
        puts "#{type} avalilable: #{quantity} units"
      end
    else
      puts "Supply hold is empty."
    end
  end
end
 
iss = SpaceStation.new
 
iss.sensors.run_sensors
  # ----- Sensor Action -----
  # Running sensors!
 
iss.supply_hold.use_supplies("parts", 2)
  # ----- Supply Action -----
  # Supply Error: Insufficient parts in the supply hold.
iss.supply_hold.load_supplies("parts", 10)
  # ----- Supply Action -----
  # Loading 10 units of parts in the supply hold.
iss.supply_hold.use_supplies("parts", 2)
  # ----- Supply Action -----
  # Using 2 of parts from the supply hold.
iss.supply_reporter.report
  # ----- Supply Report -----
  # parts avalilable: 8 units
 
iss.thrusters.activate_thrusters
  # ----- Thruster Action -----
  # Thruster Error: Insufficient fuel available.
iss.fuel_tank.load_fuel(100)
  # ----- Fuel Action -----
  # Loading 100 units of fuel in the tank.
iss.thrusters.activate_thrusters
  # ----- Thruster Action -----
  # Thrusting action successful.
  # ----- Fuel Action -----
  # Using 10 units of fuel from the tank.
iss.fuel_reporter.report
  # ----- Fuel Report -----
# 90 units of fuel available.

Π’ этой, послСднСй вСрсии ΠΏΡ€ΠΎΠ³Ρ€Π°ΠΌΠΌΡ‹ обязанности Π±Ρ‹Π»ΠΈ Ρ€Π°Π·Π±ΠΈΡ‚Ρ‹ Π½Π° Π΄Π²Π° Π½ΠΎΠ²Ρ‹Ρ… класса, FuelReporter ΠΈ SupplyReporter. Они ΠΎΠ±Π° ΡΠ²Π»ΡΡŽΡ‚ΡΡ Π΄ΠΎΡ‡Π΅Ρ€Π½ΠΈΠΌΠΈ ΠΏΠΎ ΠΎΡ‚Π½ΠΎΡˆΠ΅Π½ΠΈΡŽ ΠΊ классу Reporter. ΠšΡ€ΠΎΠΌΠ΅ Ρ‚ΠΎΠ³ΠΎ, ΠΌΡ‹ Π΄ΠΎΠ±Π°Π²ΠΈΠ»ΠΈ экзСмплярныС ΠΏΠ΅Ρ€Π΅ΠΌΠ΅Π½Π½Ρ‹Π΅ ΠΊ классу SpaceStation с Ρ‚Π΅ΠΌ, Ρ‡Ρ‚ΠΎΠ±Ρ‹ ΠΏΡ€ΠΈ нСобходимости ΠΈΠ½ΠΈΡ†ΠΈΠ°Π»ΠΈΠ·ΠΈΡ€ΠΎΠ²Π°Ρ‚ΡŒ Π½ΡƒΠΆΠ½Ρ‹ΠΉ подкласс. Π’Π΅ΠΏΠ΅Ρ€ΡŒ, Ссли ЗСмля Ρ€Π΅ΡˆΠΈΡ‚ ΠΏΠΎΠΌΠ΅Π½ΡΡ‚ΡŒ Π΅Ρ‰Π΅ Ρ‡Ρ‚ΠΎ-Ρ‚ΠΎ, Ρ‚ΠΎ ΠΌΡ‹ внСсСм ΠΏΡ€Π°Π²ΠΊΠΈ Π² подклассы, Π° Π½Π΅ Π² основной класс.

ΠšΠΎΠ½Π΅Ρ‡Π½ΠΎ, Π½Π΅ΠΊΠΎΡ‚ΠΎΡ€Ρ‹Π΅ классы Ρƒ нас Π΄ΠΎ сих ΠΏΠΎΡ€ зависят Π΄Ρ€ΡƒΠ³ ΠΎΡ‚ Π΄Ρ€ΡƒΠ³Π°. Π’Π°ΠΊ, ΠΎΠ±ΡŠΠ΅ΠΊΡ‚ SupplyReporter зависит ΠΎΡ‚ SupplyHold, Π° FuelReporter зависит ΠΎΡ‚ FuelTank. Π‘Π°ΠΌΠΎ собой, ускоритСли Π΄ΠΎΠ»ΠΆΠ½Ρ‹ Π±Ρ‹Ρ‚ΡŒ связаны с Ρ‚ΠΎΠΏΠ»ΠΈΠ²Π½Ρ‹ΠΌ Π±Π°ΠΊΠΎΠΌ. Но здСсь ΡƒΠΆΠ΅ всС выглядит Π»ΠΎΠ³ΠΈΡ‡Π½Ρ‹ΠΌ, Π° внСсСниС ΠΈΠ·ΠΌΠ΅Π½Π΅Π½ΠΈΠΉ Π½Π΅ Π±ΡƒΠ΄Π΅Ρ‚ особСнно слоТным β€” Ρ€Π΅Π΄Π°ΠΊΡ‚ΠΈΡ€ΠΎΠ²Π°Π½ΠΈΠ΅ ΠΊΠΎΠ΄Π° ΠΎΠ΄Π½ΠΎΠ³ΠΎ ΠΎΠ±ΡŠΠ΅ΠΊΡ‚Π° Π½Π΅ слишком повлияСт Π½Π° Π΄Ρ€ΡƒΠ³ΠΎΠΉ.

Π’Π°ΠΊΠΈΠΌ ΠΎΠ±Ρ€Π°Π·ΠΎΠΌ, ΠΌΡ‹ создали ΠΌΠΎΠ΄ΡƒΠ»ΡŒΠ½Ρ‹ΠΉ ΠΊΠΎΠ΄, Π³Π΄Π΅ обязанности ΠΊΠ°ΠΆΠ΄ΠΎΠ³ΠΎ ΠΈΠ· ΠΎΠ±ΡŠΠ΅ΠΊΡ‚ΠΎΠ²/классов Ρ‚ΠΎΡ‡Π½ΠΎ ΠΎΠΏΡ€Π΅Π΄Π΅Π»Π΅Π½Ρ‹. Π Π°Π±ΠΎΡ‚Π°Ρ‚ΡŒ с Ρ‚Π°ΠΊΠΈΠΌ ΠΊΠΎΠ΄ΠΎΠΌ β€” Π½Π΅ ΠΏΡ€ΠΎΠ±Π»Π΅ΠΌΠ°, Π΅Π³ΠΎ обслуТиваниС Π±ΡƒΠ΄Π΅Ρ‚ простой Π·Π°Π΄Π°Ρ‡Π΅ΠΉ. Π’Π΅ΡΡŒ «боТСствСнный ΠΎΠ±ΡŠΠ΅ΠΊΡ‚Β» ΠΌΡ‹ ΠΏΡ€Π΅ΠΎΠ±Ρ€Π°Π·ΠΎΠ²Π°Π»ΠΈ Π² SRP.

Skillbox Ρ€Π΅ΠΊΠΎΠΌΠ΅Π½Π΄ΡƒΠ΅Ρ‚:

Π˜ΡΡ‚ΠΎΡ‡Π½ΠΈΠΊ: habr.com

Π”ΠΎΠ±Π°Π²ΠΈΡ‚ΡŒ ΠΊΠΎΠΌΠΌΠ΅Π½Ρ‚Π°Ρ€ΠΈΠΉ