Na-ede koodu mgbanwe site na iji SOLID

Na-ede koodu mgbanwe site na iji SOLID

Site na onye ntụgharị okwu: ebipụtara gị akụkọ sitere na Severin Perez gbasara iji ụkpụrụ SOLID na mmemme. Ozi sitere na isiokwu ahụ ga-aba uru ma ndị mbido na ndị mmemme nwere ahụmahụ.

Ọ bụrụ na ị na-amalite, o yikarịrị ka ị nụla maka ụkpụrụ SOLID. Ha na-enyere onye mmemme aka ide koodu dị ọcha, ahaziri nke ọma na nke a na-echekwa ngwa ngwa. Ọ dị mma ịmara na na mmemme enwere ọtụtụ ụzọ esi arụ otu ọrụ n'ụzọ ziri ezi. Ndị ọkachamara dị iche iche nwere echiche dị iche iche na nghọta nke "ụzọ ziri ezi"; ihe niile dabere na ahụmahụ onye ọ bụla. Agbanyeghị, echiche ndị a kpọsara na SOLID na-anabata ihe fọrọ nke nta ka ọ bụrụ ndị nnọchi anya obodo IT niile. Ha ghọrọ mmalite mmalite na mmepe nke ọtụtụ usoro nlekọta mmepe dị mma.

Ka anyị ghọta ihe ụkpụrụ SOLID bụ yana otu ha si enyere anyị aka.

Skillbox na-atụ aro: Usoro bara uru "Mobile Developer PRO".

Anyị na -echetara: maka ndị na-agụ Habr niile - ego 10 ruble mgbe ị na-edebanye aha na nkuzi Skillbox ọ bụla site na iji koodu mgbasa ozi Habr.

Kedu ihe bụ SOLID?

Okwu a bụ mbiri, mkpụrụedemede ọ bụla nke okwu ahụ bụ mmalite nke aha otu ụkpụrụ:

  • SỤkpụrụ Ọrụ Ingle. Modul nwere ike inwe otu na naanị otu ihe kpatara mgbanwe.
  • The Oụkpụrụ pen/mechiri emechi (ụkpụrụ mepere emepe/emechi). Klas na ihe ndị ọzọ kwesịrị imeghe maka ndọtị, mana mechie maka mgbanwe.
  •  The Liskov ngbanwe ụkpụrụ (Liskov nnọchi ụkpụrụ). Ọrụ ndị na-eji ụdị ntọala kwesịrị inwe ike iji subtypes nke ụdị isi n'amaghị ya.
  • The IỤkpụrụ nkewa nke Interface  (ụkpụrụ nkewa interface). Ngwa ngwanrọ ekwesịghị ịdabere na usoro ha anaghị eji.
  • The DỤkpụrụ Mgbanwe Ependency (ụkpụrụ nke ntụgharị dabere). Modul na ọkwa dị elu ekwesịghị ịdabere na modul na ọkwa dị ala.

Ụkpụrụ Ọrụ Otu


Ụkpụrụ Nanị Ọrụ (SRP) na-ekwu na klaasị ọ bụla ma ọ bụ modul ọ bụla na mmemme kwesịrị ịbụ maka naanị otu akụkụ nke ọrụ mmemme ahụ. Na mgbakwunye, ekwesịrị inyefe akụkụ nke ọrụ a na klaasị nke ha, kama ịgbasa na klaasị enweghị njikọ. Onye nrụpụta SRP na onye isi mgbasa ozi, Robert S. Martin, kọwara ajụjụ dịka ihe kpatara mgbanwe. Ọ tụpụtara na mbụ okwu a dị ka otu n'ime ihe ndị dị n'ọrụ ya bụ "Principles of Object-oriented Design". Echiche a na-agụnye ọtụtụ n'ime ụkpụrụ njikọ nke Tom DeMarco kọwapụtara na mbụ.

Echiche a tinyekwara ọtụtụ echiche David Parnas chepụtara. Ihe abụọ bụ isi bụ mkpuchi mkpuchi na nzuzo nzuzo. Parnas rụrụ ụka na ikewa usoro n'ime modul dị iche iche ekwesịghị ịdabere na nyocha nke eserese ngọngọ ma ọ bụ mkpọ ogbunigwe. Nke ọ bụla n'ime modul ga-enwerịrị ihe ngwọta akọwapụtara nke na-enye ndị ahịa ozi kacha nta.

Site n'ụzọ, Martin nyere ihe atụ na-adọrọ mmasị na ndị isi njikwa nke ụlọ ọrụ (COO, CTO, CFO), onye ọ bụla n'ime ha na-eji ngwanrọ azụmahịa kpọmkwem maka ebumnuche dị iche iche. N'ihi ya, onye ọ bụla n'ime ha nwere ike mejuputa mgbanwe na ngwanrọ na-emetụtaghị ọdịmma nke ndị njikwa ndị ọzọ.

Ihe dị nsọ

Dị ka oge niile, ụzọ kacha mma isi mụta SRP bụ ịhụ ya ka ọ na-eme. Ka anyị leba anya n'otu akụkụ nke mmemme ahụ na-adịghị agbaso ụkpụrụ otu onye ọrụ. Nke a bụ koodu Ruby na-akọwa omume na njirimara nke ọdụ oghere.

Nyochaa ihe atụ ma gbalịa chọpụta ihe ndị a:
Ọrụ nke ihe ndị ahụ ekwuputara na klaasị SpaceStation.
Ndị nwere ike ịmasị ọrụ nke ọdụ oghere.

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

N'ezie, ọdụ oghere anyị adịghị arụ ọrụ (Echeghị m na a ga-akpọ m NASA oku n'oge na-adịghị anya), mana enwere ihe anyị ga-enyocha ebe a.

Ya mere, klaasị SpaceStation nwere ọtụtụ ọrụ dị iche iche (ma ọ bụ ọrụ). Enwere ike kewaa ha niile n'ụdị:

  • sensọ;
  • ihe eji eme ihe (ihe eji eme ihe);
  • mmanụ ụgbọala;
  • accelerators.

Ọ bụ ezie na ọ dịghị onye ọ bụla n'ime ndị ọrụ ọdụ ụgbọ mmiri a na-ekenye klas, anyị nwere ike iche n'echiche onye na-ahụ maka ihe ahụ. O yikarịrị ka onye ọkà mmụta sayensị na-achịkwa sensọ, onye na-ahụ maka mgbakasị ahụ na-ahụ maka ịnye ihe onwunwe, onye injinia na-ahụ maka inye mmanụ, onye na-anya ụgbọelu na-ejikwa ihe ndị na-ebuli elu.

Anyị nwere ike ịsị na mmemme a akwadoghị SRP? Ee, n'ezie. Mana klaasị SpaceStation bụ “ihe chi” nke maara ihe niile na-eme ihe niile. Nke a bụ nnukwu ihe mgbochi na mmemme gbadoro ụkwụ na ihe. Maka onye mbido, ihe ndị dị otú ahụ siri ezigbo ike idobe. Ruo ugbu a usoro ihe omume ahụ dị nnọọ mfe, ee, ma chee ihe ga-eme ma ọ bụrụ na anyị gbakwunye atụmatụ ọhụrụ. Ikekwe ọdụ ụgbọ elu anyị ga-achọ ọdụ ụlọ ọgwụ ma ọ bụ ụlọ nzukọ. Na ka ọrụ dị na ya, ka SpaceStation ga-etowanye. Ọfọn, ebe ọ bụ na a ga-ejikọta ihe owuwu a na ndị ọzọ, ịrụ ọrụ ụlọ ahụ dum ga-esikwu ike karị. N'ihi ya, anyị nwere ike imebi ọrụ nke ihe atụ, accelerators. Ọ bụrụ na onye nyocha arịọ maka mgbanwe na sensọ, nke a nwere ike imetụta sistemụ nkwukọrịta ọdụ nke ọma.

Ịmebi ụkpụrụ SRP nwere ike inye mmeri aghụghọ dị mkpirikpi, ma n'ikpeazụ anyị "ga-efunahụ agha", ọ ga-esikwa ike ịnọgide na-enwe ụdị anụ ọhịa dị otú ahụ n'ọdịnihu. Ọ kacha mma kewaa mmemme ahụ n'ime akụkụ dị iche iche nke koodu, nke ọ bụla n'ime ha na-ahụ maka ịrụ otu ọrụ. N'ịghọta nke a, ka anyị gbanwee klas SpaceStation.

Ka anyị kesaa ọrụ

N'elu anyị kọwara ụdị ọrụ anọ nke klaasị SpaceStation na-achịkwa. Anyị ga-eburu ha n'uche mgbe a na-emegharị ihe. Koodu emelitere dabara na SRP nke ọma.

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

E nwere ọtụtụ mgbanwe, usoro ihe omume maa anya mma ugbu a. Ugbu a klaasị SpaceStation abụrụla nke akpa ebe a na-amalite ịrụ ọrụ maka akụkụ ndị dabere, gụnyere setịpụ sensọ, sistemu ihe eji eri nri, tankị mmanụ, na ihe nkwalite.

Maka nke ọ bụla n'ime mgbanwe ndị ahụ enwere ugbu a otu klaasị: Sensọ; Nkwanye; Tank mmanụ; Ndị na-eme ihe ike.

Enwere ọtụtụ mgbanwe dị mkpa na ụdị koodu a. Isi ihe bụ na ọ bụghị nanị na a na-etinye ọrụ ndị mmadụ n'otu n'otu na klaasị nke ha, a haziri ha n'ụzọ ga-eme ka ọ bụrụ amụma na-agbanwe agbanwe. Anyị na-ejikọta ihe ndị nwere ọrụ yiri ya iji soro ụkpụrụ nke ịdị n'otu. Ugbu a, ọ bụrụ na anyị kwesịrị ịgbanwe ka usoro ahụ si arụ ọrụ, na-esi na nhazi hash gaa n'usoro, jiri klas SupplyHold; anyị ekwesịghị imetụ modul ndị ọzọ aka. N'ụzọ dị otú a, ọ bụrụ na onye na-ahụ maka logistics na-agbanwe ihe dị na ngalaba ya, ndị ọzọ ọdụ ga-anọgide na-adịghị. N'okwu a, klaasị SpaceStation agaghị ama mgbanwe ndị ahụ.

Ndị ọrụ anyị na-arụ ọrụ na ọdụ ụgbọ elu nwere ike inwe obi ụtọ maka mgbanwe ndị a n'ihi na ha nwere ike ịrịọ ndị ha chọrọ. Rịba ama na koodu ahụ nwere ụzọ dị ka report_supplies na report_fuel dị na klaasị SupplyHold na FuelTank. Gịnị ga-eme ma ọ bụrụ na Ụwa jụrụ ịgbanwe otú ọ na-akọ? Klas abụọ a, SupplyHold na FuelTank, ga-achọ ka ịgbanwee. Gịnị ma ọ bụrụ na ọ dị mkpa ka ị gbanwee otú e si ebu mmanụ na ihe oriri? Eleghị anya ị ga-agbanwerịrị otu klaasị ọzọ. Na nke a abụrụlarị mmebi nke ụkpụrụ SRP. Ka anyị dozie nke a.

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.

Na ụdị mmemme a kachasị ọhụrụ, ekewala ọrụ ndị ahụ ụzọ abụọ ọhụrụ, FuelReporter na SupplyReporter. Ha abụọ bụ ụmụ klas Reporter. Na mgbakwunye, anyị gbakwunyere mgbanwe atụ na klaasị SpaceStation ka enwere ike ibido subclass achọrọ ma ọ dị mkpa. Ugbu a, ọ bụrụ na Ụwa kpebiri ịgbanwe ihe ọzọ, mgbe ahụ, anyị ga-eme mgbanwe na subclasses, ọ bụghị na isi klas.

N'ezie, ụfọdụ klas anyị ka na-adabere na ibe anyị. Ya mere, ihe SupplyReporter dabere na SupplyHold, na FuelReporter dabere na FuelTank. N'ezie, a ga-ejikọta ndị na-ebuli elu na tank mmanụ. Mana ebe a, ihe niile adịlarị ka ezi uche dị na ya, na ịme mgbanwe agaghị esiri ike - idezi koodu nke otu ihe agaghị emetụta ọzọ.

Ya mere, anyị ekepụtala koodu modular ebe a na-akọwapụta ọrụ nke ọ bụla n'ime ihe / klaasị nke ọma. Ịrụ ọrụ na koodu dị otú ahụ abụghị nsogbu, idobe ya ga-abụ ọrụ dị mfe. Anyị agbanweela “ihe dị nsọ” niile ka ọ bụrụ SRP.

Skillbox na-atụ aro:

isi: www.habr.com

Tinye a comment