Kunyora kodhi inoshanduka uchishandisa SOLID

Kunyora kodhi inoshanduka uchishandisa SOLID

Kubva kumushanduri: yakatsikiswa iwe chinyorwa naSeverin Perez nezve kushandisa SOLID nheyo mukuronga. Ruzivo kubva muchinyorwa ruchabatsira kune vese vanotanga uye vane ruzivo programmers.

Kana iwe uri mubudiriro, iwe unogona kunge wakanzwa nezve SOLID nheyo. Vanogonesa mugadziri kunyora yakachena, yakanyatsorongeka uye inochengeteka nyore kodhi. Zvakakosha kuziva kuti mukuronga kune nzira dzinoverengeka dzekuita nemazvo rimwe basa. Nyanzvi dzakasiyana dzine mazano akasiyana uye kunzwisisa kwe "nzira chaiyo"; zvese zvinoenderana neruzivo rwemunhu wega. Nekudaro, pfungwa dzakaziviswa muSOLID dzinogamuchirwa nevanenge vese vamiriri venharaunda yeIT. Vakave nzvimbo yekutanga yekubuda uye kuvandudzwa kweakawanda akanaka ebudiriro manejimendi maitiro.

Ngatinzwisise kuti misimboti yeSOLID chii uye kuti inotibatsira sei.

Skillbox inokurudzira: Nzira inoshanda "Mobile Developer PRO".

Tinoyeuchidza: kune vese vaverengi veHabr - a 10 ruble mutengo paunenge uchinyoresa mune chero Skillbox kosi uchishandisa iyo Habr promo kodhi.

Chii chinonzi SOLID?

Iri izwi chidimbu, vara rega rega retemu ndiko kutanga kwezita reimwe musimboti:

  • Single Responsibility Principle. A module inogona kuva nechikonzero chimwe chete chekuchinja.
  • The Open/Yakavharwa Musimboti (yakavhurika/yakavharwa musimboti). Makirasi uye zvimwe zvinhu zvinofanirwa kuvhurwa kuti zviwedzere, asi zvakavharwa kuti zvigadziriswe.
  • β€ŠThe Liskov Substitution Principle (Liskov kutsiva musimboti). Mabasa anoshandisa base type anofanirwa kukwanisa kushandisa subtypes emhando yepasi asingazvizive.
  • The IInterface Segregation Principleβ€Š (interface separation musimboti). Software masangano haafanire kutsamira panzira dzavasingashandise.
  • The Dependency Inversion Principle (musimboti wekutsamira inversion). Mamodule pamazinga epamusoro haafaniri kutsamira pamamodule pamazinga akaderera.

Single Responsibility Principle

β€Š
Iyo Single Responsibility Principle (SRP) inotaura kuti kirasi yega yega kana module muchirongwa inofanirwa kuve nehanya nechikamu chimwe chete chekushanda kwechirongwa ichocho. Pamusoro pezvo, zvinhu zvebasa iri zvinofanirwa kupihwa kukirasi yavo, pane kupararira mumakirasi asina hukama. Mugadziri weSRP uye muevhangeri mukuru, Robert S. Martin, anotsanangura kuzvidavirira sechikonzero cheshanduko. Pakutanga akakurudzira izwi iri sechimwe chezvinhu zvebasa rake "Misimboti yeObject-Oriented Design". Iyo pfungwa inosanganisira yakawanda yekubatanidza maitiro iyo yakambotsanangurwa naTom DeMarco.

Pfungwa iyi yaisanganisira akati wandei akaumbwa naDavid Parnas. Iwo maviri makuru ari encapsulation uye ruzivo kuvanza. Parnas akapokana kuti kupatsanura sisitimu kuita mamodule akaparadzana hakufanirwe kubva pakuongorora kwe block diagram kana kuuraya kuyerera. Chero yemamodule anofanira kunge aine chaiyo mhinduro inopa hushoma ruzivo kune vatengi.

Nenzira, Martin akapa muenzaniso unonakidza nevatungamiriri vakuru vekambani (COO, CTO, CFO), mumwe nemumwe wavo anoshandisa chaiyo bhizinesi software kune zvinangwa zvakasiyana. Nekuda kweizvozvo, chero ipi zvayo inogona kuita shanduko musoftware pasina kukanganisa zvido zvevamwe mamaneja.

Chinhu chaMwari

Senguva dzose, nzira yakanakisa yekudzidza SRP ndeyekuiona ichiita. Ngatitarisei chikamu chechirongwa chisingateveri Single Responsibility Principle. Iyi iRuby kodhi inotsanangura maitiro uye hunhu hwenzvimbo chiteshi.

Ongorora muenzaniso uye edza kuona zvinotevera:
Basa rezvinhu izvo zvinoziviswa mukirasi yeSpaceStation.
Avo vangave vachifarira kushanda kwechiteshi chemuchadenga.

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

Chaizvoizvo, chiteshi chedu chemuchadenga hachishande (ini handifunge kuti ndichave ndichiwana runhare kubva kuNASA chero nguva munguva pfupi), asi pane chimwe chinhu chekuongorora pano.

Nekudaro, iyo SpaceStation kirasi ine akati wandei akasiyana mabasa (kana mabasa). Zvose zvavo zvinogona kugoverwa mumhando:

  • sensors;
  • zvigadzirwa (zvinodyiwa);
  • fuel;
  • accelerators.

Kunyangwe pasina kana mumwe wevashandi vechiteshi anopihwa kirasi, isu tinogona kufungidzira zviri nyore kuti ndiani ane mhosva yei. Zvingangodaro, sainzi anodzora masensa, iyo logistician ine basa rekupa zviwanikwa, injinjiniya ine basa rekupa mafuta, uye mutyairi anodzora anosimudzira.

Tinogona here kutaura kuti chirongwa ichi hachienderane neSRP? Hongu chokwadi. Asi kirasi yeSpaceStation ndeye "mwari chinhu" chinoziva zvese uye chinoita zvese. Ichi chikuru chinopesana-pattern mune chinhu-yakatarisana hurongwa. Kune anotanga, zvinhu zvakadaro zvakaoma zvikuru kuchengetedza. Parizvino chirongwa chiri nyore kwazvo, hongu, asi fungidzira zvichaitika kana tikawedzera zvinhu zvitsva. Pamwe chiteshi chedu chemuchadenga chinoda chiteshi chekurapa kana kamuri yekusangana. Uye mamwe mabasa aripo, iyo yakawanda SpaceStation ichakura. Zvakanaka, sezvo nzvimbo iyi ichave yakabatana nevamwe, kushandira iyo yakaoma yakaoma kunowedzera kuoma. Somugumisiro, tinogona kukanganisa kushanda kwe, semuenzaniso, accelerators. Kana muongorori akakumbira shanduko kuma sensors, izvi zvinogona kunyatsokanganisa masisitimu ekutaurirana echiteshi.

Kutyora mutemo weSRP kunogona kupa kuhwina kwenguva pfupi kwehunyanzvi, asi pakupedzisira isu "ticharasikirwa nehondo", uye zvichave zvakaoma kwazvo kuchengetedza chikara chakadaro mune ramangwana. Zvakanakisisa kugovera purogiramu muzvikamu zvakasiyana zvekodhi, imwe neimwe ine basa rekuita basa rakati. Kunzwisisa izvi, ngatichinje kirasi yeSpaceStation.

Ngatigovei mutoro

Pamusoro takatsanangura mhando ina dzekushanda dzinodzorwa nekirasi yeSpaceStation. Tichavachengeta mupfungwa kana tichigadzirisa. Iyo kodhi yakagadziridzwa zvirinani inoenderana neSRP.

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

Pane zvakawanda shanduko, purogiramu yacho inotaridzika zviri nani ikozvino. Iye zvino kirasi yedu yeSpaceStation yave yakawanda yemudziyo umo mavhisi anotangwa kune zvikamu zvinotsamira, kusanganisira seti yemasensa, inobatika yekugovera system, tangi yemafuta, uye boosters.

Kune chero yemhando dzakasiyana pane ikozvino kirasi inoenderana: Sensors; SupplyHold; FuelTank; Thrusters.

Pane akati wandei akakosha shanduko mune iyi vhezheni yekodhi. Icho chiripo ndechekuti mabasa ega ega haana kungovharirwa mumakirasi avo chete, akarongeka nenzira yekuti ave anofanotaurwa uye anowirirana. Isu tinounganidza zvinhu zvine mashandiro akafanana kutevera musimboti wekubatana. Zvino, kana isu tichida kushandura nzira iyo sisitimu inoshanda, ichifamba kubva kune hashi chimiro kuenda kune array, ingoshandisa iyo SupplyHold kirasi; isu hatifanirwe kubata mamwe ma module. Nenzira iyi, kana mukuru wezvekugadzirisa zvinhu akachinja chimwe chinhu muchikamu chake, imwe chiteshi inoramba ichingomira. Muchiitiko ichi, kirasi yeSpaceStation haitomboziva nezve shanduko.

Vakuru vedu vanoshanda pachiteshi chemuchadenga vanogona kunge vari kufara nezve shanduko nekuti vanogona kukumbira iwo avanoda. Ziva kuti kodhi ine nzira dzakaita sereport_supplies uye report_fuel iri muSupplyHold neFuelTank makirasi. Chii chaizoitika kudai Nyika ikakumbira kuchinja nzira yainoshuma nayo? Makirasi ese ari maviri, SupplyHold neFuelTank, achada kuchinjwa. Ko kana iwe uchida kushandura nzira iyo mafuta uye zvinodyiwa zvinounzwa? Iwe uchafanirwa kushandura ese makirasi mamwechete zvakare. Uye izvi zvatove kutyora mutemo weSRP. Ngatigadzirise izvi.

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.

Mune iyi yazvino vhezheni yechirongwa, mabasa akakamurwa kuita makirasi maviri matsva, FuelReporter uye SupplyReporter. Vese vari vana vekirasi yeReporter. Uye zvakare, isu takawedzera muenzaniso zvinosiyana kukirasi yeSpaceStation kuitira kuti subclass inodiwa inogona kutangwa kana zvichidikanwa. Zvino, kana Nyika ikasarudza kushandura chimwe chinhu, ipapo isu tichaita shanduko kune subclass, uye kwete kukirasi huru.

Zvechokwadi, mamwe emakirasi edu achiri kutsamira pane imwe neimwe. Saka, chinhu cheSupplyReporter chinoenderana neSupplyHold, uye FuelReporter zvinoenderana neFuelTank. Ehe, maboosters anofanirwa kunge akabatanidzwa kune tangi yemafuta. Asi pano zvinhu zvose zvinoratidzika zvinonzwisisika, uye kuchinja hakuzove kwakaoma zvikuru - kugadzirisa kodhi yechinhu chimwe hakuzoiti zvakanyanya kune imwe.

Nekudaro, isu takagadzira modular kodhi apo mabasa echimwe nechimwe chezvinhu / makirasi anotsanangurwa chaizvo. Kushanda nekodhi yakadaro haisi dambudziko, kuichengeta ichava basa riri nyore. Isu takashandura iyo yose "chinhu chaMwari" kuita SRP.

Skillbox inokurudzira:

Source: www.habr.com

Voeg