Ho ngola khoutu e feto-fetohang u sebelisa SOLID

Ho ngola khoutu e feto-fetohang u sebelisa SOLID

Ho tsoa ho mofetoleli: e hatisitsoeng bakeng sa hau sengoloa sa Severin Perez mabapi le ho sebelisa melao-motheo ea SOLID lenaneong. Lintlha tse tsoang ho sengoloa li tla ba molemo ho ba qalang le ba nang le boiphihlelo ba mananeo.

Haeba u nts'etsopele, mohlomong u kile oa utloela ka melao-motheo ea SOLID. Li thusa moqapi oa lenaneo ho ngola khoutu e hloekileng, e hlophisitsoeng hantle le e ka hlokomeloa habonolo. Ke habohlokoa ho hlokomela hore lenaneong ho na le mekhoa e mengata ea ho etsa mosebetsi o itseng ka nepo. Litsebi tse fapaneng li na le maikutlo a fapaneng le kutloisiso ea "tsela e nepahetseng"; tsohle li ipapisitse le boiphihlelo ba motho ka mong. Leha ho le joalo, mehopolo e phatlalalitsoeng ho SOLID e amoheloa ke hoo e batlang e le baemeli bohle ba sechaba sa IT. E ile ea e-ba qalo ea ho hlaha le nts'etsopele ea mekhoa e mengata e metle ea tsamaiso ea tsoelo-pele.

Ha re utloisise hore na melao-motheo ea SOLID ke eng le hore na e re thusa joang.

Skillbox e khothaletsa: Tsela e sebetsang "Mobile Developer PRO".

Re hopotsa: bakeng sa babali bohle ba "Habr" - theolelo ea li-ruble tse 10 ha u ngolisa thupelong efe kapa efe ea Skillbox u sebelisa khoutu ea papatso ea "Habr".

SOLID ke eng?

Lentsoe lena ke khutsufatso, lengolo le leng le le leng la lentsoe ke tšimoloho ea lebitso la molao-motheo o itseng:

  • Sengle Boikarabello Molao-motheo. Mojule o ka ba le lebaka le le leng feela la phetoho.
  • The Opene/Molao-motheo o kwetsweng (molao-motheo o bulehileng/o koetsoeng). Litlelase le likarolo tse ling li lokela ho buloa bakeng sa ho atolosoa, empa li koetsoe bakeng sa ho fetoloa.
  •  The Liskov Substitution Principle (Molao-motheo oa ho fetola Liskov). Mesebetsi e sebelisang mofuta oa motheo e lokela ho khona ho sebelisa subtypes ea mofuta oa motheo ntle le ho e tseba.
  • The IMolao-motheo oa Karohano ea Sebopeho  (molao-motheo oa karohano ea sefahleho). Mekhatlo ea software ha ea lokela ho itšetleha ka mekhoa eo e sa e sebeliseng.
  • The Dependency Inversion Principle (molao-motheo oa inversion ea ho itšetleha). Li-module tse maemong a holimo ha lia lokela ho itšetleha ka li-module tse maemong a tlase.

Molao-motheo oa Boikarabello bo le Mong


The Single Responsibility Principle (SRP) e bolela hore sehlopha se seng le se seng kapa mojule oa lenaneo le lokela ho ikarabella bakeng sa karolo e le 'ngoe feela ea tšebetso ea lenaneo leo. Ho feta moo, likarolo tsa boikarabello bona li lokela ho abeloa sehlopha sa bona, ho fapana le ho hasana lihlopheng tse sa amaneng. Moqapi le moevangeli ea ka sehloohong oa SRP, Robert S. Martin, o hlalosa boikarabello e le lebaka la phetoho. Qalong o ile a etsa tlhahiso ea hore lentsoe lena e be e 'ngoe ea likarolo tsa mosebetsi oa hae "Melao-motheo ea Moqapi o Lebisitsoeng ho Ntho". Mohopolo o kenyelletsa boholo ba mokhoa oa khokahanyo o neng o hlalosoa pele ke Tom DeMarco.

Khopolo ena e ne e boetse e kenyelletsa likhopolo tse 'maloa tse entsoeng ke David Parnas. Tse peli tse ka sehloohong ke encapsulation le ho pata tlhahisoleseding. Parnas o ile a pheha khang ea hore ho arola tsamaiso ka li-modules tse arohaneng ha hoa lokela ho thehoa ho hlahloba litšoantšo tsa li-block kapa phallo ea ts'ebetso. E 'ngoe le e' ngoe ea li-module e tlameha ho ba le tharollo e khethehileng e fanang ka bonyane ba tlhahisoleseding ho bareki.

Ka tsela, Martin o ile a fana ka mohlala o thahasellisang le batsamaisi ba phahameng ba k'hamphani (COO, CTO, CFO), bao e mong le e mong oa bona a sebelisang software e itseng ea khoebo bakeng sa merero e fapaneng. Ka lebaka leo, mang kapa mang oa bona a ka kenya ts'ebetsong liphetoho ho software ntle le ho ama lithahasello tsa batsamaisi ba bang.

Ntho e halalelang

Joalo ka mehla, tsela e molemohali ea ho ithuta SRP ke ho e bona e sebetsa. Ha re shebeng karolo ea lenaneo e SA lateleng Molao-motheo oa Boikarabello bo le Mong. Ena ke khoutu ea Ruby e hlalosang boitšoaro le litšobotsi tsa seteishene sa sebaka.

Hlahloba mohlala 'me u leke ho tseba tse latelang:
Boikarabello ba lintho tse phatlalalitsoeng sehlopheng sa SpaceStation.
Ba ka 'nang ba thahasella ts'ebetso ea seteishene sa sebaka.

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

Haele hantle, seteishene sa rona sa sepakapaka ha se sebetse hantle (ha ke nahane hore ke tla fumana mohala o tsoang ho NASA haufinyane), empa ho na le seo re lokelang ho se sekaseka mona.

Kahoo, sehlopha sa SpaceStation se na le mesebetsi e mengata e fapaneng (kapa mesebetsi). Kaofela ha tsona li ka aroloa ka mefuta:

  • lisensara;
  • lisebelisoa (lisebelisoa);
  • mafura;
  • li-accelerator.

Leha ho se le ea mong oa basebetsi ba seteisheneng ba abetsoeng sehlopha, re ka inahanela hore na ke mang ea ikarabellang bakeng sa eng. Ho ka etsahala hore ebe rasaense o laola li-sensor, setsebi sa thepa se ikarabella bakeng sa ho fana ka lisebelisoa, moenjiniere o ikarabella bakeng sa phepelo ea mafura, 'me mofofisi o laola li-booster.

Na re ka re lenaneo lee ha le lumellane le SRP? E, ehlile. Empa sehlopha sa SpaceStation ke "ntho ea molimo" e tloaelehileng e tsebang tsohle ebile e etsa tsohle. Ena ke mokhoa o ka sehloohong o khahlanong le mokhoa oa ho etsa mananeo a shebaneng le lintho. Ho motho ea qalang, ho thata haholo ho boloka lintho tse joalo. Ho fihlela joale lenaneo le bonolo haholo, e, empa nahana hore na ho tla etsahala'ng haeba re eketsa likarolo tse ncha. Mohlomong seteishene sa rona sa sepakapaka se tla hloka seteishene sa bongaka kapa kamore ea liboka. 'Me ha mesebetsi e ntse e eketseha, SpaceStation e tla hola le ho feta. Joale, kaha setsi sena se tla hokahanngoa le tse ling, ho sebeletsa moaho oohle ho tla rarahana le ho feta. Ka lebaka leo, re ka senya ts'ebetso ea, mohlala, li-accelerator. Haeba mofuputsi a kopa liphetoho ho li-sensor, sena se ka ama mekhoa ea puisano ea seteishene hantle.

Ho tlōla molao-motheo oa SRP ho ka fana ka tlhōlo ea nako e khutšoanyane ea maqheka, empa qetellong re tla "lahleheloa ke ntoa", 'me ho tla ba thata haholo ho boloka monster e joalo nakong e tlang. Ho molemo ho arola lenaneo ka likarolo tse arohaneng tsa khoutu, e 'ngoe le e' ngoe e ikarabellang bakeng sa ho etsa ts'ebetso e itseng. Ka ho utloisisa sena, ha re fetoleng sehlopha sa SpaceStation.

Ha re abeng boikarabelo

Ka holimo re hlalositse mefuta e mene ea ts'ebetso e laoloang ke sehlopha sa SpaceStation. Re tla li hopola ha re etsa refactoring. Khoutu e ntlafalitsoeng e lumellana hantle le 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

Ho na le liphetoho tse ngata, lenaneo le shebahala le le betere hona joale. Hona joale sehlopha sa rona sa SpaceStation se fetohile sejana seo ho sona ho qalisoang ts'ebetso bakeng sa likarolo tse itšetlehileng ka eona, ho kenyeletsoa sete ea li-sensor, sistimi ea phepelo e ka sebelisoang, tanka ea mafura le li-booster.

Bakeng sa leha e le efe ea mefuta-futa hona joale ho na le sehlopha se lumellanang: Sensors; SupplyHold; Tanka ea Mafura; Li-thrusters.

Ho na le liphetoho tse 'maloa tsa bohlokoa phetolelong ena ea khoutu. Taba ke hore mesebetsi ea motho ka mong ha e kenyellelitsoe feela lihlopheng tsa bona, empa e hlophisitsoe ka tsela eo e ka tsebang esale pele le ho tsitsa. Re kopanya likarolo tse nang le ts'ebetso e ts'oanang ho latela molao-motheo oa momahano. Hona joale, haeba re hloka ho fetola tsela eo tsamaiso e sebetsang ka eona, ho tloha mohahong oa hash ho ea ho sehlopha, sebelisa feela sehlopha sa SupplyHold; ha rea ​​​​tlameha ho ama li-module tse ling. Ka tsela ena, haeba ofisiri ea tsamaiso e fetola ntho e itseng karolong ea hae, seteishene se seng se tla lula se le joalo. Tabeng ena, sehlopha sa SpaceStation se ke ke sa tseba le liphetoho.

Liofisiri tsa rona tse sebetsang setsing sa sepaka-paka mohlomong li thabetse liphetoho tsena hobane li ka kopa tseo li li hlokang. Hlokomela hore khoutu e na le mekhoa e joalo ka report_supplies le report_fuel e leng ho lihlopha tsa SupplyHold le FuelTank. Ho ne ho tla etsahala’ng haeba Lefatše le ne le ka kōpa ho fetola tsela eo le tlalehang ka eona? Lihlopha tsena ka bobeli, SupplyHold le FuelTank, li tla hloka ho fetoloa. Ho thoe'ng haeba u hloka ho fetola tsela eo mafura le lintho tse sebelisoang li tsamaisoang ka eona? Mohlomong u tla tlameha ho fetola litlelase tse tšoanang hape. 'Me sena se se se ntse se le tlōlo ea molao-motheo oa SRP. Ha re lokiseng taba ena.

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.

Phetolelong ena ea morao-rao ea lenaneo, boikarabello bo arotsoe ka lihlopha tse peli tse ncha, FuelReporter le SupplyReporter. Ka bobeli ke bana ba sehlopha sa Moqolotsi. Ntle le moo, re kentse mefuta e fapaneng ea mohlala sehlopheng sa SpaceStation e le hore sehlopha se lakatsehang se ka qalisoa ha ho hlokahala. Joale, haeba Lefatše le etsa qeto ea ho fetola ntho e 'ngoe, joale re tla etsa liphetoho ho li-subclass, eseng ho sehlopha se seholo.

Ke ’nete hore tse ling tsa litlelase tsa rōna li ntse li itšetlehile ka tse ling. Kahoo, ntho ea SupplyReporter e itšetlehile ka SupplyHold, 'me FuelReporter e itšetlehile ka FuelTank. Ehlile, li-booster li tlameha ho hokahanngoa le tanka ea mafura. Empa mona ntho e 'ngoe le e' ngoe e se e shebahala e utloahala, 'me ho etsa liphetoho ho ke ke ha e-ba thata ka ho khetheha - ho hlophisa khoutu ea ntho e le' ngoe ho ke ke ha ama e 'ngoe haholo.

Kahoo, re thehile khoutu ea modular moo boikarabello ba ntho e 'ngoe le e' ngoe / lihlopha li hlalosoang hantle. Ho sebetsa ka khoutu e joalo ha se bothata, ho e boloka e tla ba mosebetsi o bonolo. Re fetotse "ntho ea bomolimo" kaofela hore e be SRP.

Skillbox e khothaletsa:

Source: www.habr.com

Eketsa ka tlhaloso