Ukubhala ikhodi evumelana nezimo usebenzisa i-SOLID

Ukubhala ikhodi evumelana nezimo usebenzisa i-SOLID

Kusuka kumhumushi: ishicilelwe wena isihloko sikaSeverin Perez mayelana nokusebenzisa izimiso ze-SOLID ezinhlelweni. Ulwazi oluvela esihlokweni luzoba usizo kubo bobabili abaqalayo nabahleli bezinhlelo abanolwazi.

Uma uthanda ukuthuthukiswa, kungenzeka ukuthi uzwile ngezimiso ze-SOLID. Ivumela umhleli ukuthi abhale ikhodi ehlanzekile, eyakhiwe kahle futhi elondolozeka kalula. Kuyaqapheleka ukuthi ezinhlelweni kunezindlela ezimbalwa zokwenza umsebenzi othile ngendlela efanele. Ochwepheshe abehlukene banemibono ehlukene kanye nokuqonda "indlela eyiyo"; konke kuncike kulokho umuntu abhekana nakho. Nokho, imibono emenyezelwe ku-SOLID yamukelwa cishe yibo bonke abameleli bomphakathi we-IT. Baba isiqalo sokuvela nokuthuthukiswa kwezinqubo eziningi ezinhle zokuphatha intuthuko.

Masiqonde ukuthi ithini imigomo ye-SOLID nokuthi isisiza kanjani.

I-Skillbox iyancoma: Isifundo esiwusizo "I-Mobile Developer PRO".

Siyakukhumbuza: kubo bonke abafundi be-"Habr" - isaphulelo sama-ruble angu-10 lapho ubhalisa kunoma yisiphi isifundo se-Skillbox usebenzisa ikhodi yephromoshini ethi "Habr".

Yini i-SOLID?

Leli gama liyisifinyezo, uhlamvu ngalunye lwethemu luyisiqalo segama lomgomo othize:

  • SI-ingle Responsibility Principe. Imojuli ingaba nesizathu esisodwa futhi esisodwa kuphela soshintsho.
  • The Oipeni/Isimiso Esivaliwe (isimiso esivuliwe/esivaliwe). Amakilasi nezinye izici kufanele zivulelwe ukunwetshwa, kodwa zivaliwe ukuze zilungiswe.
  • β€ŠThe Liskov esikhundleni Isimiso (Isimiso sokushintshwa kwe-Liskov). Imisebenzi esebenzisa uhlobo lwesisekelo kufanele ikwazi ukusebenzisa izinhlobo ezingaphansi zohlobo lwesisekelo ngaphandle kokwazi.
  • The IIsimiso Sokuhlukaniswa Kwe-interfaceβ€Š (umgomo wokuhlukanisa isixhumi esibonakalayo). Izinkampani zesofthiwe akufanele zincike ezindleleni ezingasebenzisi.
  • The DI-ependency Inversion Principle (isimiso sokuncika kokuncika). Amamojula emazingeni aphezulu akufanele ancike kumamojula asezingeni eliphansi.

Isimiso Sokuzibophezela Okukodwa

β€Š
I-Single Responsibility Principle (SRP) ithi ikilasi ngalinye noma imojuli yohlelo kufanele ibe nesibopho ngengxenye eyodwa kuphela yokusebenza kwalolo hlelo. Ukwengeza, izici zalo mthwalo wemfanelo kufanele zinikezwe ikilasi labo, kunokuba zihlakazeke kuwo wonke amakilasi angahlobene. Umthuthukisi nomshumayeli omkhulu we-SRP, uRobert S. Martin, uchaza ukuziphendulela njengesizathu soshintsho. Ekuqaleni wayehlongoze leli gama njengelinye lamaciko omsebenzi wakhe othi "Izimiso Zomklamo Ogxile Entweni". Umqondo uhlanganisa iningi lephethini yokuxhumana eyachazwa ngaphambilini ngu-Tom DeMarco.

Lo mqondo wawuhlanganisa nemiqondo eminingana eyakhiwe nguDavid Parnas. Okubili okuyinhloko yi-encapsulation kanye nokufihla ulwazi. U-Parnas wagomela ngokuthi ukuhlukanisa isistimu ibe amamojula ahlukene akufanele kusekelwe ekuhlaziyweni kwemidwebo yebhulokhi noma ukugeleza kokukhishwa. Noma yimaphi amamojula kufanele aqukathe isixazululo esithile esinikeza ubuncane bolwazi kumakhasimende.

Ngendlela, uMartin wanikeza isibonelo esithakazelisayo nabaphathi abakhulu benkampani (i-COO, i-CTO, i-CFO), ngamunye wabo esebenzisa isofthiwe yebhizinisi elithile ngezinhloso ezahlukene. Ngenxa yalokho, noma iyiphi yazo ingasebenzisa izinguquko kusofthiwe ngaphandle kokuthinta izintshisekelo zabanye abaphathi.

Into yaphezulu

Njengenjwayelo, indlela engcono kakhulu yokufunda i-SRP ukuyibona isebenza. Ake sibheke ingxenye yohlelo ENGALANDELI Umgomo Wesibopho Esiwodwa. Lena ikhodi yeRuby echaza ukuziphatha nezibaluli zesiteshi sasemkhathini.

Buyekeza isibonelo bese uzama ukunquma okulandelayo:
Izibopho zalezo zinto ezimenyezelwe esigabeni se-SpaceStation.
Labo abangaba nentshisekelo ekusebenzeni kwesiteshi sasemkhathini.

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

Empeleni, isiteshi sethu sasemkhathini asisebenzi (angicabangi ukuthi ngizoke ngithole ucingo oluvela ku-NASA noma nini maduze), kodwa kukhona okumele sikuhlaziye lapha.

Ngakho-ke, ikilasi le-SpaceStation linemithwalo yemfanelo eminingana (noma imisebenzi). Zonke zingahlukaniswa zibe izinhlobo:

  • izinzwa;
  • izinto ezisetshenziswayo (izinto ezisetshenziswayo);
  • uphethiloli;
  • ama-accelerator.

Noma kungekho namunye wabasebenzi besiteshi owabelwe ikilasi, singacabanga kalula ukuthi ubani onesibopho salokho. Ngokunokwenzeka, usosayensi ulawula izinzwa, i-logistician inesibopho sokuhlinzeka ngezinsiza, unjiniyela unesibopho sokuphakelwa kukaphethiloli, futhi umshayeli ulawula ama-booster.

Singasho ukuthi lolu hlelo aluhambisani ne-SRP? Yebo, impela. Kodwa isigaba se-SpaceStation "into kankulunkulu" ejwayelekile ewazi yonke into futhi eyenza yonke into. Lena iphethini enkulu emelene nezinhlelo ezigxile ezintweni. Kosaqalayo, izinto ezinjalo zinzima kakhulu ukuzinakekela. Kuze kube manje uhlelo lulula kakhulu, yebo, kodwa cabanga ukuthi kuzokwenzekani uma sengeza izici ezintsha. Mhlawumbe isiteshi sethu sasemkhathini sizodinga isiteshi sezokwelapha noma igumbi lokuhlangana. Futhi uma kunemisebenzi eyengeziwe, i-SpaceStation izokhula. Nokho, njengoba lesi sikhungo sizoxhunywa kwezinye, ukusevisa yonke indawo kuzoba nzima nakakhulu. Ngenxa yalokho, singaphazamisa ukusebenza, isibonelo, ama-accelerator. Uma umcwaningi ecela izinguquko kuzinzwa, lokhu kungase kuthinte kakhulu izinhlelo zokuxhumana zesiteshi.

Ukwephula isimiso se-SRP kungase kunikeze ukunqoba kwesikhashana esifushane, kodwa ekugcineni "sizolahlekelwa impi", futhi kuyoba nzima kakhulu ukugcina i-monster enjalo esikhathini esizayo. Kungcono ukuhlukanisa uhlelo zibe izingxenye ezihlukene zekhodi, ngayinye enesibopho sokwenza umsebenzi othile. Ngokuqonda lokhu, masishintshe isigaba se-SpaceStation.

Asisabe isibopho

Ngenhla sichaze izinhlobo ezine zokusebenza ezilawulwa isigaba se-SpaceStation. Sizobakhumbula lapho senza kabusha. Ikhodi ebuyekeziwe ifana kangcono ne-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

Ziningi izinguquko, uhlelo lubukeka lungcono impela manje. Manje ikilasi lethu le-SpaceStation seliyisitsha lapho kuqaliswa ukusebenza kwezingxenye ezincikile, okuhlanganisa isethi yezinzwa, isistimu yokuhlinzeka ngezinto ezisebenzisekayo, ithangi likaphethiloli, nama-booster.

Kunoma yikuphi okuguquguqukayo manje sekunesigaba esihambisanayo: Izinzwa; SupplyHold; I-FuelTank; Ama-thrusters.

Kunezinguquko ezimbalwa ezibalulekile kule nguqulo yekhodi. Iphuzu liwukuthi imisebenzi ngayinye ayigcini nje ngokuhlanganisa izigaba zayo, ihlelwa ngendlela yokuthi ikwazi ukubikezelwa futhi ingaguquki. Sihlanganisa izakhi ezinomsebenzi ofanayo ukuze silandele isimiso sokuhambisana. Manje, uma sidinga ukushintsha indlela uhlelo olusebenza ngayo, sisuka esakhiweni se-hashi siye ohlwini, vele sisebenzise isigaba se-SupplyHold; akudingekile ukuthi sithinte amanye amamojula. Ngale ndlela, uma isikhulu sezokuthutha sishintsha okuthile esigabeni saso, sonke isiteshi sizohlala sinjalo. Kulokhu, ikilasi le-SpaceStation ngeke lize lizazi izinguquko.

Amaphoyisa ethu asebenza esiteshini sasemkhathini cishe ajabule ngezinguquko ngoba angakwazi ukucela lawo awadingayo. Qaphela ukuthi ikhodi inezindlela ezifana ne-report_supplies kanye ne-report_fuel equkethwe kumakilasi e-SupplyHold ne-FuelTank. Bekuzokwenzekani uma uMhlaba ucela ukushintsha indlela obika ngayo? Womabili amakilasi, i-SupplyHold ne-FuelTank, azodinga ukushintshwa. Kuthiwani uma udinga ukushintsha indlela uphethiloli nezinto ezisetshenziswayo ezilethwa ngayo? Kuzodingeka ukuthi uguqule wonke amakilasi afanayo futhi. Futhi lokhu kakade kuwukwephula isimiso se-SRP. Asilungise lokhu.

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.

Kule nguqulo yakamuva yohlelo, izibopho zihlukaniswe ngamakilasi amabili amasha, i-FuelReporter kanye ne-SupplyReporter. Bobabili bangabantwana besigaba samaReporter. Ngaphezu kwalokho, sengeze izibonelo eziguquguqukayo ekilasini le-SpaceStation ukuze i-subclass efiselekayo iqaliswe uma kunesidingo. Manje, uma uMhlaba unquma ukushintsha enye into, khona-ke sizokwenza izinguquko kuma-subclasses, hhayi ekilasini elikhulu.

Yebo, amanye amakilasi ethu asancike kwelinye. Ngakho, into ye-SupplyReporter incike ku-SupplyHold, futhi i-FuelReporter incike ku-FuelTank. Yiqiniso, ama-booster kufanele axhunywe ku-tank fuel. Kodwa lapha konke kakade kubukeka kunengqondo, futhi ukwenza izinguquko ngeke kube nzima kakhulu - ukuhlela ikhodi yento eyodwa ngeke kuthinte kakhulu enye.

Ngakho-ke, senze ikhodi ye-modular lapho izibopho zento ngayinye/amakilasi zichazwa ngokunembile. Ukusebenza ngekhodi enjalo akuyona inkinga, ukuyigcina kuyoba umsebenzi olula. Siguqule yonke "into yaphezulu" yaba yi-SRP.

I-Skillbox iyancoma:

Source: www.habr.com

Engeza amazwana