ПишСм гъвкав код, използвайки SOLID

ПишСм гъвкав код, използвайки SOLID

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

Ако сС Π·Π°Π½ΠΈΠΌΠ°Π²Π°Ρ‚Π΅ с Ρ€Π°Π·Ρ€Π°Π±ΠΎΡ‚ΠΊΠ°, вСроятно стС Ρ‡ΡƒΠ²Π°Π»ΠΈ Π·Π° ΠΏΡ€ΠΈΠ½Ρ†ΠΈΠΏΠΈΡ‚Π΅ SOLID. Π’Π΅ Π΄Π°Π²Π°Ρ‚ Π²ΡŠΠ·ΠΌΠΎΠΆΠ½ΠΎΡΡ‚ Π½Π° програмиститС Π΄Π° ΠΏΠΈΡˆΠ°Ρ‚ чист, Π΄ΠΎΠ±Ρ€Π΅ структуриран ΠΈ лСсно ΠΏΠΎΠ΄Π΄ΡŠΡ€ΠΆΠ°Π½ ΠΊΠΎΠ΄. Π‘Ρ‚Ρ€ΡƒΠ²Π° си Π΄Π° сС ΠΎΡ‚Π±Π΅Π»Π΅ΠΆΠΈ, Ρ‡Π΅ Π² ΠΏΡ€ΠΎΠ³Ρ€Π°ΠΌΠΈΡ€Π°Π½Π΅Ρ‚ΠΎ ΠΈΠΌΠ° Ρ€Π°Π·Π»ΠΈΡ‡Π½ΠΈ ΠΏΠΎΠ΄Ρ…ΠΎΠ΄ΠΈ към Ρ‚ΠΎΠ²Π° ΠΊΠ°ΠΊ ΠΏΡ€Π°Π²ΠΈΠ»Π½ΠΎ Π΄Π° сС ΠΈΠ·Π²ΡŠΡ€ΡˆΠ²Π° всяка Ρ€Π°Π±ΠΎΡ‚Π°. Π Π°Π·Π»ΠΈΡ‡Π½ΠΈΡ‚Π΅ спСциалисти ΠΈΠΌΠ°Ρ‚ Ρ€Π°Π·Π»ΠΈΡ‡Π½ΠΈ ΠΈΠ΄Π΅ΠΈ ΠΈ разбирания Π·Π° "правилния ΠΏΡŠΡ‚", всичко зависи ΠΎΡ‚ ΠΎΠΏΠΈΡ‚Π° Π½Π° всСки. Π’ΡŠΠΏΡ€Π΅ΠΊΠΈ Ρ‚ΠΎΠ²Π°, ΠΈΠ΄Π΅ΠΈΡ‚Π΅, ΠΏΡ€ΠΎΠ²ΡŠΠ·Π³Π»Π°ΡΠ΅Π½ΠΈ Π² SOLID, сС ΠΏΡ€ΠΈΠ΅ΠΌΠ°Ρ‚ ΠΏΠΎΡ‡Ρ‚ΠΈ ΠΎΡ‚ всички прСдставитСли Π½Π° ИВ общСството. Π’Π΅ станаха ΠΎΡ‚ΠΏΡ€Π°Π²Π½Π° Ρ‚ΠΎΡ‡ΠΊΠ° Π·Π° ΡΡŠΠ·Π΄Π°Π²Π°Π½Π΅Ρ‚ΠΎ ΠΈ Ρ€Π°Π·Π²ΠΈΡ‚ΠΈΠ΅Ρ‚ΠΎ Π½Π° ΠΌΠ½ΠΎΠ³ΠΎ Π΄ΠΎΠ±Ρ€ΠΈ ΠΌΠ΅Ρ‚ΠΎΠ΄ΠΈ Π·Π° ΡƒΠΏΡ€Π°Π²Π»Π΅Π½ΠΈΠ΅ Π½Π° Ρ€Π°Π·Ρ€Π°Π±ΠΎΡ‚ΠΊΠΈΡ‚Π΅.

НСка Ρ€Π°Π·Π³Π»Π΅Π΄Π°ΠΌΠ΅ ΠΊΠ°ΠΊΠ²ΠΎ прСдставляват ΠΏΡ€ΠΈΠ½Ρ†ΠΈΠΏΠΈΡ‚Π΅ SOLID ΠΈ ΠΊΠ°ΠΊ Ρ‚Π΅ Π½ΠΈ ΠΏΠΎΠΌΠ°Π³Π°Ρ‚.

Skillbox ΠΏΡ€Π΅ΠΏΠΎΡ€ΡŠΡ‡Π²Π°: ΠŸΡ€Π°ΠΊΡ‚ΠΈΡ‡Π΅ΡΠΊΠΈ курс «МобилСн Ρ€Π°Π·Ρ€Π°Π±ΠΎΡ‚Ρ‡ΠΈΠΊ PROΒ».

НапомнямС: Π·Π° всички Ρ‡ΠΈΡ‚Π°Ρ‚Π΅Π»ΠΈ Π½Π° "Π₯Π°Π±Ρ€Π°" β€” ΠΎΡ‚ΡΡ‚ΡŠΠΏΠΊΠ° ΠΎΡ‚ 10 000 Ρ€ΡƒΠ±Π»ΠΈ ΠΏΡ€ΠΈ записванС Π½Π° всякакъв курс Π½Π° Skillbox с ΠΏΡ€ΠΎΠΌΠΎΠΊΠΎΠ΄ "Π₯Π°Π±Ρ€".

Какво С SOLID?

Π’Π΅Ρ€ΠΌΡŠΡ‚ Π΅ Π°Π±Ρ€Π΅Π²ΠΈΠ°Ρ‚ΡƒΡ€Π°, всяка Π±ΡƒΠΊΠ²Π° ΠΎΡ‚ Ρ‚Π΅Ρ€ΠΌΠΈΠ½Π° Π΅ Π½Π°Ρ‡Π°Π»ΠΎΡ‚ΠΎ Π½Π° ΠΈΠΌΠ΅Ρ‚ΠΎ Π½Π° ΠΎΠΏΡ€Π΅Π΄Π΅Π»Π΅Π½ ΠΏΡ€ΠΈΠ½Ρ†ΠΈΠΏ:

  • SSingle Responsibility Principle (ΠΏΡ€ΠΈΠ½Ρ†ΠΈΠΏ Π½Π° СдинствСната отговорност). ΠœΠΎΠ΄ΡƒΠ»ΡŠΡ‚ ΠΌΠΎΠΆΠ΅ Π΄Π° ΠΈΠΌΠ° само Π΅Π΄Π½Π° ΠΏΡ€ΠΈΡ‡ΠΈΠ½Π° Π·Π° промяна.
  • The OOpen/Closed Principle (ΠΏΡ€ΠΈΠ½Ρ†ΠΈΠΏ Π½Π° отворСност/затворСност). ΠšΠ»Π°ΡΠΎΠ²Π΅Ρ‚Π΅ ΠΈ Π΄Ρ€ΡƒΠ³ΠΈΡ‚Π΅ Π΅Π»Π΅ΠΌΠ΅Π½Ρ‚ΠΈ трябва Π΄Π° са ΠΎΡ‚Π²ΠΎΡ€Π΅Π½ΠΈ Π·Π° Ρ€Π°Π·ΡˆΠΈΡ€Π΅Π½ΠΈΠ΅, Π½ΠΎ Π·Π°Ρ‚Π²ΠΎΡ€Π΅Π½ΠΈ Π·Π° модификация.
  • β€ŠThe LLiskov Substitution Principle (ΠΏΡ€ΠΈΠ½Ρ†ΠΈΠΏ Π½Π° подмяна Π½Π° Лисков). Π€ΡƒΠ½ΠΊΡ†ΠΈΠΈΡ‚Π΅, ΠΊΠΎΠΈΡ‚ΠΎ ΠΈΠ·ΠΏΠΎΠ»Π·Π²Π°Ρ‚ Π±Π°Π·ΠΎΠ² Ρ‚ΠΈΠΏ, трябва Π΄Π° ΠΌΠΎΠ³Π°Ρ‚ Π΄Π° ΠΈΠ·ΠΏΠΎΠ»Π·Π²Π°Ρ‚ ΠΏΠΎΠ΄Ρ‚ΠΈΠΏΠΎΠ²Π΅ Π½Π° базовия Ρ‚ΠΈΠΏ, Π±Π΅Π· Π΄Π° знаят Π·Π° Ρ‚ΠΎΠ²Π°.
  • The IInterface Segregation Principleβ€Š(ΠΏΡ€ΠΈΠ½Ρ†ΠΈΠΏ Π½Π° раздСлянС Π½Π° интСрфСйса). ΠŸΡ€ΠΎΠ³Ρ€Π°ΠΌΠ½ΠΈΡ‚Π΅ Π΅Π΄ΠΈΠ½ΠΈΡ†ΠΈ Π½Π΅ трябва Π΄Π° зависят ΠΎΡ‚ ΠΌΠ΅Ρ‚ΠΎΠ΄ΠΈ, ΠΊΠΎΠΈΡ‚ΠΎ Π½Π΅ ΠΈΠ·ΠΏΠΎΠ»Π·Π²Π°Ρ‚.
  • The DDependency Inversion Principle (ΠΏΡ€ΠΈΠ½Ρ†ΠΈΠΏ Π½Π° инвСрсия Π½Π° зависимоститС). ΠœΠΎΠ΄ΡƒΠ»ΠΈΡ‚Π΅ ΠΎΡ‚ ΠΏΠΎ-високитС Π½ΠΈΠ²Π° Π½Π΅ трябва Π΄Π° зависят ΠΎΡ‚ ΠΌΠΎΠ΄ΡƒΠ»ΠΈΡ‚Π΅ ΠΎΡ‚ ΠΏΠΎ-нискитС Π½ΠΈΠ²Π°.

ΠŸΡ€ΠΈΠ½Ρ†ΠΈΠΏ Π½Π° СдинствСната отговорност

β€Š
ΠŸΡ€ΠΈΠ½Ρ†ΠΈΠΏ Π½Π° СдинствСна отговорност (SRP) гласи, Ρ‡Π΅ всСки клас ΠΈΠ»ΠΈ ΠΌΠΎΠ΄ΡƒΠ» Π² ΠΏΡ€ΠΎΠ³Ρ€Π°ΠΌΠ°Ρ‚Π° трябва Π΄Π° носи отговорност само Π·Π° Π΅Π΄Π½Π° част ΠΎΡ‚ функционалността Π½Π° Ρ‚Π°Π·ΠΈ ΠΏΡ€ΠΎΠ³Ρ€Π°ΠΌΠ°. ОсвСн Ρ‚ΠΎΠ²Π°, Π΅Π»Π΅ΠΌΠ΅Π½Ρ‚ΠΈΡ‚Π΅ Π½Π° Ρ‚Π°Π·ΠΈ отговорност трябва Π΄Π° са ΡΠ²ΡŠΡ€Π·Π°Π½ΠΈ с тСхния клас, Π° Π½Π΅ Ρ€Π°Π·ΠΏΡ€Π΅Π΄Π΅Π»Π΅Π½ΠΈ ΠΌΠ΅ΠΆΠ΄Ρƒ Π½Π΅ΡΠ²ΡŠΡ€Π·Π°Π½ΠΈ класовС. Π Π°Π·Ρ€Π°Π±ΠΎΡ‚Ρ‡ΠΈΠΊΡŠΡ‚ ΠΈ Π³Π»Π°Π²Π΅Π½ СвангСлист Π½Π° SRP, Π ΠΎΠ±ΡŠΡ€Ρ‚ Π‘. ΠœΠ°Ρ€Ρ‚ΠΈΠ½, описва отговорността ΠΊΠ°Ρ‚ΠΎ ΠΏΡ€ΠΈΡ‡ΠΈΠ½Π° Π·Π° ΠΏΡ€ΠΎΠΌΠ΅Π½ΠΈ. Π’ΠΎΠΉ ΠΏΡŠΡ€Π²ΠΎΠ½Π°Ρ‡Π°Π»Π½ΠΎ ΠΏΡ€Π΅Π΄Π»Π°Π³Π° Ρ‚ΠΎΠ·ΠΈ Ρ‚Π΅Ρ€ΠΌΠΈΠ½ ΠΊΠ°Ρ‚ΠΎ Π΅Π΄ΠΈΠ½ ΠΎΡ‚ Π΅Π»Π΅ΠΌΠ΅Π½Ρ‚ΠΈΡ‚Π΅ Π½Π° своята Ρ€Π°Π±ΠΎΡ‚Π° β€žΠŸΡ€ΠΈΠ½Ρ†ΠΈΠΏΠΈ Π½Π° ΠΎΠ±Π΅ΠΊΡ‚Π½ΠΎ-ΠΎΡ€ΠΈΠ΅Π½Ρ‚ΠΈΡ€Π°Π½ΠΎ ΠΏΡ€ΠΎΠ΅ΠΊΡ‚ΠΈΡ€Π°Π½Π΅β€œ. Π’ концСпцията Π΅ Π²ΠΊΠ»ΡŽΡ‡Π΅Π½ΠΎ ΠΌΠ½ΠΎΠ³ΠΎ ΠΎΡ‚ закономСрността Π½Π° ΡΠ²ΡŠΡ€Π·Π°Π½ΠΎΡΡ‚Ρ‚Π°, която ΠΏΠΎ-Ρ€Π°Π½ΠΎ Π΅ ΠΎΠΏΡ€Π΅Π΄Π΅Π»Π΅Π½Π° ΠΎΡ‚ Π’ΠΎΠΌ Π”Π΅ΠΌΠ°Ρ€ΠΊΠΎ.

Π’ концСпцията са Π²ΠΊΠ»ΡŽΡ‡Π΅Π½ΠΈ ΠΈ няколко понятия, Ρ„ΠΎΡ€ΠΌΡƒΠ»ΠΈΡ€Π°Π½ΠΈ ΠΎΡ‚ Π”Π΅ΠΉΠ²ΠΈΠ΄ ΠŸΠ°Ρ€Π½Π°Ρ. Π”Π²Π° основни β€” инкапсулация ΠΈ скриванС Π½Π° информация. ΠŸΠ°Ρ€Π½Π°Ρ Ρ‚Π²ΡŠΡ€Π΄ΠΈ, Ρ‡Π΅ раздСлянСто Π½Π° систСмата Π½Π° ΠΎΡ‚Π΄Π΅Π»Π½ΠΈ ΠΌΠΎΠ΄ΡƒΠ»ΠΈ Π½Π΅ трябва Π΄Π° сС Π±Π°Π·ΠΈΡ€Π° Π½Π° Π°Π½Π°Π»ΠΈΠ· Π½Π° Π±Π»ΠΎΠΊ-схСми ΠΈΠ»ΠΈ ΠΏΠΎΡ‚ΠΎΡ†ΠΈ Π½Π° изпълнСниС. ВсСки ΠΌΠΎΠ΄ΡƒΠ» трябва Π΄Π° ΡΡŠΠ΄ΡŠΡ€ΠΆΠ° ΠΎΠΏΡ€Π΅Π΄Π΅Π»Π΅Π½ΠΎ Ρ€Π΅ΡˆΠ΅Π½ΠΈΠ΅, ΠΊΠΎΠ΅Ρ‚ΠΎ прСдоставя ΠΌΠΈΠ½ΠΈΠΌΠ°Π»Π½ΠΎ количСство информация Π½Π° ΠΊΠ»ΠΈΠ΅Π½Ρ‚ΠΈΡ‚Π΅.

ΠœΠ°Ρ€Ρ‚ΠΈΠ½ Π΄Π°Π²Π° интСрСсСн ΠΏΡ€ΠΈΠΌΠ΅Ρ€ с Π²ΠΈΡΡˆΠΈΡ‚Π΅ ΠΌΠ΅Π½ΠΈΠ΄ΠΆΡŠΡ€ΠΈ Π½Π° компанията (COO, CTO, CFO), всСки ΠΎΡ‚ ΠΊΠΎΠΈΡ‚ΠΎ ΠΈΠ·ΠΏΠΎΠ»Π·Π²Π° спСцифичСн софтуСр Π·Π° бизнСса с Ρ€Π°Π·Π»ΠΈΡ‡Π½Π° Ρ†Π΅Π». Π’ ΠΊΡ€Π°ΠΉΠ½Π° смСтка, всСки ΠΎΡ‚ тях ΠΌΠΎΠΆΠ΅ Π΄Π° внСдрява ΠΏΡ€ΠΎΠΌΠ΅Π½ΠΈ Π² софтуСра, Π±Π΅Π· Π΄Π° засяга интСрСситС Π½Π° Π΄Ρ€ΡƒΠ³ΠΈΡ‚Π΅ ΠΌΠ΅Π½ΠΈΠ΄ΠΆΡŠΡ€ΠΈ.

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

ΠšΠ°ΠΊΡ‚ΠΎ ΠΎΠ±ΠΈΠΊΠ½ΠΎΠ²Π΅Π½ΠΎ, Π½Π°ΠΉ-добрият Π½Π°Ρ‡ΠΈΠ½ Π΄Π° ΠΈΠ·ΡƒΡ‡ΠΈΡ‚Π΅ SRP Π΅ Π΄Π° Π²ΠΈΠ΄ΠΈΡ‚Π΅ всичко Π² дСйствиС. НСка Ρ€Π°Π·Π³Π»Π΅Π΄Π°ΠΌΠ΅ ΡƒΡ‡Π°ΡΡ‚ΡŠΠΊ ΠΎΡ‚ ΠΏΡ€ΠΎΠ³Ρ€Π°ΠΌΠ°, ΠΊΠΎΠΉΡ‚ΠΎ НЕ отговаря Π½Π° ΠΏΡ€ΠΈΠ½Ρ†ΠΈΠΏΠ° Π½Π° СдинствСна отговорност. Π’ΠΎΠ²Π° Π΅ Ruby ΠΊΠΎΠ΄, описващ ΠΏΠΎΠ²Π΅Π΄Π΅Π½ΠΈΠ΅Ρ‚ΠΎ ΠΈ Π°Ρ‚Ρ€ΠΈΠ±ΡƒΡ‚ΠΈΡ‚Π΅ Π½Π° космичСска станция.

ΠŸΡ€Π΅Π³Π»Π΅Π΄Π°ΠΉΡ‚Π΅ ΠΏΡ€ΠΈΠΌΠ΅Ρ€Π° ΠΈ сС ΠΎΠΏΠΈΡ‚Π°ΠΉΡ‚Π΅ Π΄Π° ΠΎΠΏΡ€Π΅Π΄Π΅Π»ΠΈΡ‚Π΅ слСдното:
ΠžΡ‚Π³ΠΎΠ²ΠΎΡ€Π½ΠΎΡΡ‚ΠΈΡ‚Π΅ Π½Π° ΠΎΠ±Π΅ΠΊΡ‚ΠΈΡ‚Π΅, ΠΊΠΎΠΈΡ‚ΠΎ са обявСни Π² класа SpaceStation.
Π’Π΅Π·ΠΈ, ΠΊΠΎΠΈΡ‚ΠΎ ΠΌΠΎΠ³Π°Ρ‚ Π΄Π° сС интСрСсуват ΠΎΡ‚ Ρ€Π°Π±ΠΎΡ‚Π°Ρ‚Π° Π½Π° космичСската станция.

class SpaceStation
  def initialize
    @supplies = {}
    @fuel = 0
  end
 
  def run_sensors
    puts "----- ДСйствиС сСнсоров -----"
    puts "Запуск сСнсоров!"
  end
 
  def load_supplies(type, quantity)
    puts "----- ДСйствиС ΠΏΠΎ Π·Π°Π³Ρ€ΡƒΠ·ΠΊΠ΅ запасов -----"
    puts "Π—Π°Π³Ρ€ΡƒΠ·ΠΊΠ° #{quantity} Π΅Π΄ΠΈΠ½ΠΈΡ† #{type} Π² Ρ…Ρ€Π°Π½ΠΈΠ»ΠΈΡ‰Π΅ запасов."
    
    if @supplies[type]
      @supplies[type] += quantity
    else
      @supplies[type] = quantity
    end
  end
 
  def use_supplies(type, quantity)
    puts "----- ДСйствиС ΠΏΠΎ использованию запасов -----"
    if @supplies[type] != nil && @supplies[type] > quantity
      puts "ИспользованиС #{quantity} Π΅Π΄ΠΈΠ½ΠΈΡ† #{type} ΠΈΠ· Ρ…Ρ€Π°Π½ΠΈΠ»ΠΈΡ‰Π° запасов."
      @supplies[type] -= quantity
    else
      puts "Ошибка запаса: Π½Π΅Π΄ΠΎΡΡ‚Π°ΡŽΡ‰Π΅Π΅ количСство #{type} Π² Ρ…Ρ€Π°Π½ΠΈΠ»ΠΈΡ‰Π΅ запасов."
    end
  end
 
  def report_supplies
    puts "----- ΠžΡ‚Ρ‡Π΅Ρ‚ ΠΎ запасах -----"
    if @supplies.keys.length > 0
      @supplies.each do |type, quantity|
        puts "#{type} доступно: #{quantity} Π΅Π΄ΠΈΠ½ΠΈΡ†"
      end
    else
      puts "Π₯Ρ€Π°Π½ΠΈΠ»ΠΈΡ‰Π΅ запасов пусто."
    end
  end
 
  def load_fuel(quantity)
    puts "----- ДСйствиС ΠΏΠΎ Π·Π°Π³Ρ€ΡƒΠ·ΠΊΠ΅ Ρ‚ΠΎΠΏΠ»ΠΈΠ²Π° -----"
    puts "Π—Π°Π³Ρ€ΡƒΠ·ΠΊΠ° #{quantity} Π΅Π΄ΠΈΠ½ΠΈΡ† Ρ‚ΠΎΠΏΠ»ΠΈΠ²Π° Π² Π±Π°ΠΊ."
    @fuel += quantity
  end
 
  def report_fuel
    puts "----- ΠžΡ‚Ρ‡Π΅Ρ‚ ΠΎ Ρ‚ΠΎΠΏΠ»ΠΈΠ²Π΅ -----"
    puts "#{@fuel} Π΅Π΄ΠΈΠ½ΠΈΡ† Ρ‚ΠΎΠΏΠ»ΠΈΠ²Π° доступно."
  end
 
  def activate_thrusters
    puts "----- ДСйствиС ΠΏΠΎ Π°ΠΊΡ‚ΠΈΠ²Π°Ρ†ΠΈΠΈ ускоритСлСй -----"
    if @fuel >= 10
      puts "ДСйствиС ΠΏΠΎ ΡƒΡΠΊΠΎΡ€Π΅Π½ΠΈΡŽ ΡƒΡΠΏΠ΅ΡˆΠ½ΠΎ."
      @fuel -= 10
    else
      puts "Ошибка ускоритСля: нСдостаточно Ρ‚ΠΎΠΏΠ»ΠΈΠ²Π°."
    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} available: #{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 ΠšΠΎΡΠΌΠΈΡ‡Π΅ΡΠΊΠ°Π‘Ρ‚Π°Π½Ρ†ΠΈΡ
  attr_reader :сСнзори, :снабдитСлСн_ΠΎΡ‚Π΄Π΅Π», :снабдитСлСн_Π΄ΠΎΠΊΠ»Π°Π΄Ρ‡ΠΈΠΊ,
              :Ρ€Π΅Π·Π΅Ρ€Π²ΠΎΠ°Ρ€_с Π³ΠΎΡ€ΠΈΠ²ΠΎ, :Π΄ΠΎΠΊΠ»Π°Π΄Ρ‡ΠΈΠΊ_с_Π³ΠΎΡ€ΠΈΠ²ΠΎ, :Π΄Ρ€ΡƒΠ³ΠΈ_Π΄Π²ΠΈΠ³Π°Ρ‚Π΅Π»ΠΈ
 
  def initialize
    @сСнзори = Π‘Π΅Π½Π·ΠΎΡ€ΠΈ.new
    @снабдитСлСн_ΠΎΡ‚Π΄Π΅Π» = Π‘Π½Π°Π±Π΄ΠΈΡ‚Π΅Π»Π΅Π½ΠžΡ‚Π΄Π΅Π».new
    @снабдитСлСн_Π΄ΠΎΠΊΠ»Π°Π΄Ρ‡ΠΈΠΊ = Π‘Π½Π°Π±Π΄ΠΈΡ‚Π΅Π»Π΅Π½Π”ΠΎΠΊΠ»Π°Π΄Ρ‡ΠΈΠΊ.new(@снабдитСлСн_ΠΎΡ‚Π΄Π΅Π»)
    @Ρ€Π΅Π·Π΅Ρ€Π²ΠΎΠ°Ρ€_с_Π³ΠΎΡ€ΠΈΠ²ΠΎ = Π Π΅Π·Π΅Ρ€Π²ΠΎΠ°Ρ€Π‘Π“ΠΎΡ€ΠΈΠ²ΠΎ.new
    @Π΄ΠΎΠΊΠ»Π°Π΄Ρ‡ΠΈΠΊ_с_Π³ΠΎΡ€ΠΈΠ²ΠΎ = Π”ΠΎΠΊΠ»Π°Π΄Ρ‡ΠΈΠΊΠ‘Π“ΠΎΡ€ΠΈΠ²ΠΎ.new(@Ρ€Π΅Π·Π΅Ρ€Π²ΠΎΠ°Ρ€_с_Π³ΠΎΡ€ΠΈΠ²ΠΎ)
    @Π΄Ρ€ΡƒΠ³ΠΈ_Π΄Π²ΠΈΠ³Π°Ρ‚Π΅Π»ΠΈ = Π”Ρ€ΡƒΠ³ΠΈΠ”Π²ΠΈΠ³Π°Ρ‚Π΅Π»ΠΈ.new(@Ρ€Π΅Π·Π΅Ρ€Π²ΠΎΠ°Ρ€_с_Π³ΠΎΡ€ΠΈΠ²ΠΎ)
  end
end
 
class Π‘Π΅Π½Π·ΠΎΡ€ΠΈ
  def run_sensors
    puts "----- ДСйствиС Π½Π° сСнзоритС -----"
    puts "Π‘Π΅Π½Π·ΠΎΡ€ΠΈΡ‚Π΅ работят!"
  end
end
 
class Π‘Π½Π°Π±Π΄ΠΈΡ‚Π΅Π»Π΅Π½ΠžΡ‚Π΄Π΅Π»
  attr_accessor :снабдява
  attr_reader :Π΄ΠΎΠΊΠ»Π°Π΄Ρ‡ΠΈΠΊ
 
  def initialize
    @снабдява = {}
  end
 
  def get_supplies
    @снабдява
  end
 
  def load_supplies(type, quantity)
    puts "----- ДСйствиС Π½Π° снабдяванСто -----"
    puts "Π—Π°Ρ€Π΅ΠΆΠ΄Π°Π½Π΅ Π½Π° #{quantity} Π΅Π΄ΠΈΠ½ΠΈΡ†ΠΈ ΠΎΡ‚ #{type} Π² снабдитСлния ΠΎΡ‚Π΄Π΅Π»."
    
    if @снабдява[type]
      @снабдява[type] += quantity
    else
      @снабдява[type] = quantity
    end
  end
 
  def use_supplies(type, quantity)
    puts "----- ДСйствиС Π½Π° снабдяванСто -----"
    if @снабдява[type] != nil && @снабдява[type] > quantity
      puts "ИзползванС Π½Π° #{quantity} ΠΎΡ‚ #{type} ΠΎΡ‚ снабдитСлния ΠΎΡ‚Π΄Π΅Π»."
      @снабдява[type] -= quantity
    else
      puts "Π“Ρ€Π΅ΡˆΠΊΠ° Π² снабдяванСто: ΠΠ΅Π΄ΠΎΡΡ‚Π°Ρ‚ΡŠΡ‡Π½ΠΎ #{type} Π² снабдитСлния ΠΎΡ‚Π΄Π΅Π»."
    end
  end
end
 
class Π Π΅Π·Π΅Ρ€Π²ΠΎΠ°Ρ€Π‘Π“ΠΎΡ€ΠΈΠ²ΠΎ
  attr_accessor :Π³ΠΎΡ€ΠΈΠ²ΠΎ
  attr_reader :Π΄ΠΎΠΊΠ»Π°Π΄Ρ‡ΠΈΠΊ
 
  def initialize
    @Π³ΠΎΡ€ΠΈΠ²ΠΎ = 0
  end
 
  def get_fuel_levels
    @Π³ΠΎΡ€ΠΈΠ²ΠΎ
  end
 
  def load_fuel(quantity)
    puts "----- ДСйствиС Π½Π° Π³ΠΎΡ€ΠΈΠ²ΠΎΡ‚ΠΎ -----"
    puts "Π—Π°Ρ€Π΅ΠΆΠ΄Π°Π½Π΅ Π½Π° #{quantity} Π΅Π΄ΠΈΠ½ΠΈΡ†ΠΈ Π³ΠΎΡ€ΠΈΠ²ΠΎ Π² Ρ€Π΅Π·Π΅Ρ€Π²ΠΎΠ°Ρ€Π°."
    @Π³ΠΎΡ€ΠΈΠ²ΠΎ += quantity
  end
 
  def use_fuel(quantity)
    puts "----- ДСйствиС Π½Π° Π³ΠΎΡ€ΠΈΠ²ΠΎΡ‚ΠΎ -----"
    puts "ИзползванС Π½Π° #{quantity} Π΅Π΄ΠΈΠ½ΠΈΡ†ΠΈ Π³ΠΎΡ€ΠΈΠ²ΠΎ ΠΎΡ‚ Ρ€Π΅Π·Π΅Ρ€Π²ΠΎΠ°Ρ€Π°."
    @Π³ΠΎΡ€ΠΈΠ²ΠΎ -= quantity
  end
end
 
class Π”Ρ€ΡƒΠ³ΠΈΠ”Π²ΠΈΠ³Π°Ρ‚Π΅Π»ΠΈ
  FUEL_PER_THRUST = 10
 
  def initialize(fuel_tank)
    @ΡΠ²ΡŠΡ€Π·Π°Π½_Ρ€Π΅Π·Π΅Ρ€Π²ΠΎΠ°Ρ€_с_Π³ΠΎΡ€ΠΈΠ²ΠΎ = fuel_tank
  end
 
  def activate_thrusters
    puts "----- ДСйствиС Π½Π° Π΄Π²ΠΈΠ³Π°Ρ‚Π΅Π»ΠΈΡ‚Π΅ -----"
    
    if @ΡΠ²ΡŠΡ€Π·Π°Π½_Ρ€Π΅Π·Π΅Ρ€Π²ΠΎΠ°Ρ€_с_Π³ΠΎΡ€ΠΈΠ²ΠΎ.get_fuel_levels >= FUEL_PER_THRUST
      puts "ДСйствиСто Π½Π° тласканСто Π΅ ΡƒΡΠΏΠ΅ΡˆΠ½ΠΎ."
      @ΡΠ²ΡŠΡ€Π·Π°Π½_Ρ€Π΅Π·Π΅Ρ€Π²ΠΎΠ°Ρ€_с_Π³ΠΎΡ€ΠΈΠ²ΠΎ.use_fuel(FUEL_PER_THRUST)
    else
      puts "Π“Ρ€Π΅ΡˆΠΊΠ° Π½Π° двигатСля: ΠΠ΅Π΄ΠΎΡΡ‚Π°Ρ‚ΡŠΡ‡Π½ΠΎ Π³ΠΎΡ€ΠΈΠ²ΠΎ."
    end
  end
end
 
class Π”ΠΎΠΊΠ»Π°Π΄Ρ‡ΠΈΠΊ
  def initialize(item, type)
    @ΡΠ²ΡŠΡ€Π·Π°Π½_Π΅Π»Π΅ΠΌΠ΅Π½Ρ‚ = item
    @type = type
  end
 
  def report
    puts "----- #{@type.capitalize} Π”ΠΎΠΊΠ»Π°Π΄ -----"
  end
end
 
class Π”ΠΎΠΊΠ»Π°Π΄Ρ‡ΠΈΠΊΠ‘Π“ΠΎΡ€ΠΈΠ²ΠΎ < Π”ΠΎΠΊΠ»Π°Π΄Ρ‡ΠΈΠΊ
  def initialize(item)
    super(item, "Π³ΠΎΡ€ΠΈΠ²ΠΎ")
  end
 
  def report
    super
    puts "#{@ΡΠ²ΡŠΡ€Π·Π°Π½_Π΅Π»Π΅ΠΌΠ΅Π½Ρ‚.get_fuel_levels} Π΅Π΄ΠΈΠ½ΠΈΡ†ΠΈ Π³ΠΎΡ€ΠΈΠ²ΠΎ Π½Π°Π»ΠΈΡ‡Π½ΠΈ."
  end
end
 
class Π‘Π½Π°Π±Π΄ΠΈΡ‚Π΅Π»Π΅Π½Π”ΠΎΠΊΠ»Π°Π΄Ρ‡ΠΈΠΊ  0
      @ΡΠ²ΡŠΡ€Π·Π°Π½_Π΅Π»Π΅ΠΌΠ΅Π½Ρ‚.get_supplies.each do |type, quantity|
        puts "#{type} Π½Π°Π»ΠΈΡ‡Π½ΠΎ: #{quantity} Π΅Π΄ΠΈΠ½ΠΈΡ†ΠΈ"
      end
    else
      puts "БнабдитСлният ΠΎΡ‚Π΄Π΅Π» Π΅ ΠΏΡ€Π°Π·Π΅Π½."
    end
  end
end
 
iss = ΠšΠΎΡΠΌΠΈΡ‡Π΅ΡΠΊΠ°Π‘Ρ‚Π°Π½Ρ†ΠΈΡ.new
 
iss.сСнзори.run_sensors
  # ----- ДСйствиС Π½Π° сСнзоритС -----
  # Π‘Π΅Π½Π·ΠΎΡ€ΠΈΡ‚Π΅ работят!
 
iss.снабдитСлСн_ΠΎΡ‚Π΄Π΅Π».use_supplies("части", 2)
  # ----- ДСйствиС Π½Π° снабдяванСто -----
  # Π“Ρ€Π΅ΡˆΠΊΠ° Π² снабдяванСто: ΠΠ΅Π΄ΠΎΡΡ‚Π°Ρ‚ΡŠΡ‡Π½ΠΎ части Π² снабдитСлния ΠΎΡ‚Π΄Π΅Π».
iss.снабдитСлСн_ΠΎΡ‚Π΄Π΅Π».load_supplies("части", 10)
  # ----- ДСйствиС Π½Π° снабдяванСто -----
  # Π—Π°Ρ€Π΅ΠΆΠ΄Π°Π½Π΅ Π½Π° 10 Π΅Π΄ΠΈΠ½ΠΈΡ†ΠΈ части Π² снабдитСлния ΠΎΡ‚Π΄Π΅Π».
iss.снабдитСлСн_ΠΎΡ‚Π΄Π΅Π».use_supplies("части", 2)
  # ----- ДСйствиС Π½Π° снабдяванСто -----
  # ИзползванС Π½Π° 2 ΠΎΡ‚ части ΠΎΡ‚ снабдитСлния ΠΎΡ‚Π΄Π΅Π».
iss.снабдитСлСн_Π΄ΠΎΠΊΠ»Π°Π΄Ρ‡ΠΈΠΊ.report
  # ----- Π”ΠΎΠΊΠ»Π°Π΄ Π·Π° снабдяванСто -----
  # части Π½Π°Π»ΠΈΡ‡Π½ΠΈ: 8 Π΅Π΄ΠΈΠ½ΠΈΡ†ΠΈ
 
iss.Π΄Ρ€ΡƒΠ³ΠΈ_Π΄Π²ΠΈΠ³Π°Ρ‚Π΅Π»ΠΈ.activate_thrusters
  # ----- ДСйствиС Π½Π° Π΄Π²ΠΈΠ³Π°Ρ‚Π΅Π»ΠΈΡ‚Π΅ -----
  # Π“Ρ€Π΅ΡˆΠΊΠ° Π½Π° двигатСля: ΠΠ΅Π΄ΠΎΡΡ‚Π°Ρ‚ΡŠΡ‡Π½ΠΎ Π³ΠΎΡ€ΠΈΠ²ΠΎ.
iss.Ρ€Π΅Π·Π΅Ρ€Π²ΠΎΠ°Ρ€_с_Π³ΠΎΡ€ΠΈΠ²ΠΎ.load_fuel(100)
  # ----- ДСйствиС Π½Π° Π³ΠΎΡ€ΠΈΠ²ΠΎΡ‚ΠΎ -----
  # Π—Π°Ρ€Π΅ΠΆΠ΄Π°Π½Π΅ Π½Π° 100 Π΅Π΄ΠΈΠ½ΠΈΡ†ΠΈ Π³ΠΎΡ€ΠΈΠ²ΠΎ Π² Ρ€Π΅Π·Π΅Ρ€Π²ΠΎΠ°Ρ€Π°.
iss.Π΄Ρ€ΡƒΠ³ΠΈ_Π΄Π²ΠΈΠ³Π°Ρ‚Π΅Π»ΠΈ.activate_thrusters
  # ----- ДСйствиС Π½Π° Π΄Π²ΠΈΠ³Π°Ρ‚Π΅Π»ΠΈΡ‚Π΅ -----
  # ДСйствиСто Π½Π° тласканСто Π΅ ΡƒΡΠΏΠ΅ΡˆΠ½ΠΎ.
  # ----- ДСйствиС Π½Π° Π³ΠΎΡ€ΠΈΠ²ΠΎΡ‚ΠΎ -----
  # ИзползванС Π½Π° 10 Π΅Π΄ΠΈΠ½ΠΈΡ†ΠΈ Π³ΠΎΡ€ΠΈΠ²ΠΎ ΠΎΡ‚ Ρ€Π΅Π·Π΅Ρ€Π²ΠΎΠ°Ρ€Π°.
iss.Π΄ΠΎΠΊΠ»Π°Π΄Ρ‡ΠΈΠΊ_с_Π³ΠΎΡ€ΠΈΠ²ΠΎ.report
  # ----- Π”ΠΎΠΊΠ»Π°Π΄ Π·Π° Π³ΠΎΡ€ΠΈΠ²ΠΎΡ‚ΠΎ -----
# 90 Π΅Π΄ΠΈΠ½ΠΈΡ†ΠΈ Π³ΠΎΡ€ΠΈΠ²ΠΎ Π½Π°Π»ΠΈΡ‡Π½ΠΈ.

Π’ Ρ‚Π°Π·ΠΈ, послСдна вСрсия Π½Π° ΠΏΡ€ΠΎΠ³Ρ€Π°ΠΌΠ°Ρ‚Π°, отговорноститС са Ρ€Π°Π·Π΄Π΅Π»Π΅Π½ΠΈ Π½Π° Π΄Π²Π° Π½ΠΎΠ²ΠΈ класа, FuelReporter ΠΈ SupplyReporter. И Π΄Π²Π°Ρ‚Π° са наслСдници Π½Π° класа Reporter. ОсвСн Ρ‚ΠΎΠ²Π° Π΄ΠΎΠ±Π°Π²ΠΈΡ…ΠΌΠ΅ ΠΏΡ€ΠΎΠΌΠ΅Π½Π»ΠΈΠ²ΠΈ Π½Π° инстанцията към класа SpaceStation, Ρ‚Π°ΠΊΠ° Ρ‡Π΅ ΠΏΡ€ΠΈ нСобходимост Π΄Π° ΠΈΠ½ΠΈΡ†ΠΈΠ°Π»ΠΈΠ·ΠΈΡ€Π°ΠΌΠ΅ нуТния подклас. Π‘Π΅Π³Π°, Π°ΠΊΠΎ ЗСмята Ρ€Π΅ΡˆΠΈ Π΄Π° ΠΏΡ€ΠΎΠΌΠ΅Π½ΠΈ Π½Π΅Ρ‰ΠΎ Π΄Ρ€ΡƒΠ³ΠΎ, Ρ‰Π΅ Π½Π°ΠΏΡ€Π°Π²ΠΈΠΌ ΠΊΠΎΡ€Π΅ΠΊΡ†ΠΈΠΈ Π² подкласовСтС, Π° Π½Π΅ Π² основния клас.

Π Π°Π·Π±ΠΈΡ€Π° сС, някои класовС всС ΠΎΡ‰Π΅ зависят Π΅Π΄ΠΈΠ½ ΠΎΡ‚ Π΄Ρ€ΡƒΠ³. НапримСр, ΠΎΠ±Π΅ΠΊΡ‚ΡŠΡ‚ SupplyReporter зависи ΠΎΡ‚ SupplyHold, Π° FuelReporter зависи ΠΎΡ‚ FuelTank. Π‘Π°ΠΌΠΎ ΠΏΠΎ сСбС си, ускоритСлитС трябва Π΄Π° Π±ΡŠΠ΄Π°Ρ‚ ΡΠ²ΡŠΡ€Π·Π°Π½ΠΈ с бСнзиновия Ρ€Π΅Π·Π΅Ρ€Π²ΠΎΠ°Ρ€. Но Ρ‚ΡƒΠΊ всичко ΠΈΠ·Π³Π»Π΅ΠΆΠ΄Π° Π»ΠΎΠ³ΠΈΡ‡Π½ΠΎ, Π° промяната няма Π΄Π° бъдС особСно слоТна β€” Ρ€Π΅Π΄Π°ΠΊΡ‚ΠΈΡ€Π°Π½Π΅Ρ‚ΠΎ Π½Π° ΠΊΠΎΠ΄Π° Π½Π° Π΅Π΄ΠΈΠ½ ΠΎΠ±Π΅ΠΊΡ‚ няма Π΄Π° повлияС Π·Π½Π°Ρ‡ΠΈΡ‚Π΅Π»Π½ΠΎ Π½Π° Π΄Ρ€ΡƒΠ³.

Π’Π°ΠΊΠ° Π½ΠΈΠ΅ ΡΡŠΠ·Π΄Π°Π΄ΠΎΡ…ΠΌΠ΅ ΠΌΠΎΠ΄ΡƒΠ»Π΅Π½ ΠΊΠΎΠ΄, ΠΊΡŠΠ΄Π΅Ρ‚ΠΎ отговорноститС Π½Π° всСки ΠΎΡ‚ ΠΎΠ±Π΅ΠΊΡ‚ΠΈΡ‚Π΅/класовСтС са Ρ‚ΠΎΡ‡Π½ΠΎ ΠΎΠΏΡ€Π΅Π΄Π΅Π»Π΅Π½ΠΈ. Π Π°Π±ΠΎΡ‚Π°Ρ‚Π° с Ρ‚Π°ΠΊΡŠΠ² ΠΊΠΎΠ΄ Π½Π΅ Π΅ ΠΏΡ€ΠΎΠ±Π»Π΅ΠΌ, Π° обслуТванСто ΠΌΡƒ Ρ‰Π΅ бъдС лСсна Π·Π°Π΄Π°Ρ‡Π°. Всяка "боТСствСна" функция бяхмС трансформирали Π² SRP.

Skillbox ΠΏΡ€Π΅ΠΏΠΎΡ€ΡŠΡ‡Π²Π°:

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

ΠšΡƒΠΏΠ΅Ρ‚Π΅ Π½Π°Π΄Π΅ΠΆΠ΄Π΅Π½ хостинг Π·Π° сайтовС със Π·Π°Ρ‰ΠΈΡ‚Π° ΠΎΡ‚ DDoS, VPS ΠΈ VDS ΡΡŠΡ€Π²ΡŠΡ€ΠΈ πŸ”₯ ΠšΡƒΠΏΠ΅Ρ‚Π΅ Π½Π°Π΄Π΅ΠΆΠ΄Π΅Π½ хостинг Π·Π° сайтовС със Π·Π°Ρ‰ΠΈΡ‚Π° ΠΎΡ‚ DDoS, VPS ΠΈ VDS ΡΡŠΡ€Π²ΡŠΡ€ΠΈ | ProHoster