Te tuhi waehere ngawari ma te whakamahi SOLID

Te tuhi waehere ngawari ma te whakamahi SOLID

Mai i te kaiwhakamaori: i whakaputaina mo koe tuhinga na Severin Perez e pā ana ki te whakamahi i ngā mātāpono SOLID i te hōtaka. Ko nga korero mai i te tuhinga ka whai hua ki te hunga timata me nga kaiwhakatakoto kaupapa mohio.

Mena kei te haere koe ki te whakawhanaketanga, kua rongo pea koe mo nga kaupapa SOLID. Ka taea e te kaihōtaka te tuhi i nga waehere ma, he pai te hanganga me te ngawari ki te pupuri. He mea tika kia mohio kei roto i te kaupapa he maha nga huarahi ki te mahi tika i tetahi mahi. He rereke nga whakaaro me te mohio o nga tohunga rereke ki te "ara tika"; ka whakawhirinaki katoa ki nga wheako o ia tangata. Heoi, ko nga whakaaro kua panuitia i roto i te SOLID ka whakaaetia e te nuinga o nga mema o te hapori IT. I noho hei timatanga mo te puta me te whanaketanga o te maha o nga tikanga whakahaere whanaketanga pai.

Kia mohio tatou he aha nga maapono SOLID me pehea te awhina i a tatou.

Ka tūtohu a Skillbox: Akoranga mahi "Whakawhanake Waea PRO".

Ka whakamahara matou: mo nga kaipānui katoa o "Habr" - he utu mo te 10 rubles i te wa e whakauru ana ki tetahi akoranga Skillbox ma te whakamahi i te waehere whakatairanga "Habr".

He aha te SOLID?

He whakapototanga tenei kupu, ko ia reta o te kupu te timatanga o te ingoa o tetahi maapono motuhake:

  • SIngle Kaupapa Kawenga. Ka taea e te kōwae te kotahi anake te take mo te whakarereke.
  • te Opene/Maapono Kati (maataapono tuwhera/kati). Ko nga karaehe me etahi atu huānga me tuwhera mo te toronga, engari ka kati mo te whakarereke.
  •  te Liskov Kaupapa Whakakapi (Te parau tumu whakakapi Liskov). Ko nga mahi e whakamahi ana i te momo turanga me kaha ki te whakamahi i nga momo iti o te momo turanga me te kore e mohio.
  • te IKaupapa Whakawehe Atanga  (matapono wehewehe atanga). Kaua nga hinonga rorohiko e whakawhirinaki ki nga tikanga kaore e whakamahia e ratou.
  • te Dependency Inversion Principle (te kaupapa o te hurihanga whakawhirinaki). Ko nga waahanga kei nga taumata teitei kia kaua e whakawhirinaki ki nga waahanga kei nga taumata iti.

Tikanga Haepapa Takitahi


E kii ana te Maapono Haepapa Takitahi (SRP) ko ia karaehe, kowae ranei i roto i te hotaka, me kawe te kawenga mo tetahi waahanga noa o te mahinga o taua papatono. I tua atu, ko nga waahanga o tenei kawenga me tuku ki o raatau ake karaehe, kaua ki te marara ki nga akomanga kore. Ko te kaiwhakawhanake me te kaikauwhau matua o SRP, a Robert S. Martin, e kii ana ko te kawenga takohanga te take o te whakarereketanga. I whakaarohia e ia tenei kupu ko tetahi o nga waahanga o tana mahi "Principles of Object-Oriented Design". Kei roto i te ariā te nuinga o te tauira honohono i tautuhia e Tom DeMarco i mua.

I roto ano i te ariā etahi ariā i hangaia e David Parnas. Ko nga mea matua e rua ko te whakauru me te huna korero. I tohe a Parnas ko te wehewehe i te punaha ki nga waahanga motuhake, kaua e hangai i runga i te tātaritanga o nga hoahoa poraka me nga rerenga mahi. Ko tetahi o nga waahanga me whakauru he otinga motuhake e whakarato ana i nga korero iti ki nga kaihoko.

I te ara, i hoatu e Martin tetahi tauira whakamere me nga kaiwhakahaere matua o tetahi kamupene (COO, CTO, CFO), ka whakamahia e ia o raatau rorohiko motuhake mo nga kaupapa rereke. Ko te mutunga, ka taea e tetahi o ratou te whakatinana i nga huringa i roto i te rorohiko me te kore e pa ki nga hiahia o etahi atu kaiwhakahaere.

Ahanoa atua

I nga wa katoa, ko te huarahi pai ki te ako SRP ko te kite i te mahi. Kia titiro tatou ki tetahi wahanga o te hotaka KORE e whai ana i te Tikanga Haepapa Takitahi. Ko te waehere Ruby tenei e whakaatu ana i te whanonga me nga huanga o te teihana mokowhiti.

Arotakehia te tauira ka ngana ki te whakatau i nga mea e whai ake nei:
Ko nga kawenga o aua taonga e whakapuakihia ana i roto i te akomanga SpaceStation.
Ko te hunga e aro nui ana ki nga mahi o te teihana mokowhiti.

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

Inaa, he kino to maatau teihana mokowhiti (kare au e kii ka waea atu ahau mai i te NASA i nga wa e tata ana), engari he mea hei tātari i konei.

No reira, he maha nga kawenga rereke o te akomanga SpaceStation (he mahi ranei). Ka taea te wehea katoa ki nga momo:

  • pūoko;
  • taonga (mea pau);
  • wahie;
  • kaiwhakatere.

Ahakoa karekau tetahi o nga kaimahi o te teihana i whakawhiwhia ki tetahi karaehe, he maamaa te whakaaro ko wai te kawenga mo te aha. Ko te nuinga pea, ko te kaiputaiao te whakahaere i nga pukoro, ko te kaitoi te kawenga mo te tuku rauemi, ko te miihini te kawenga mo nga taonga hinu, ko te kaiurungi te whakahaere i nga kaiwhakatairanga.

Ka taea e tatou te kii kaore tenei kaupapa i te ture SRP? Ae, pono. Engari ko te akomanga SpaceStation he "mea atua" e mohio ana ki nga mea katoa me te mahi i nga mea katoa. He tauira anti-tauira nui tenei i roto i nga kaupapa-a-ahanoa. Mo te hunga timata, he tino uaua ki te pupuri i aua taonga. I tenei wa he tino ngawari te kaupapa, ae, engari whakaarohia ka aha mena ka taapirihia nga waahanga hou. Akene ka hiahia to tatou teihana mokowhiti ki te whare hauora, ki tetahi ruma hui ranei. A, ka nui ake nga mahi, ka tipu ake te SpaceStation. Ana, i te mea ka honoa tenei whare ki etahi atu, ka nui ake te uaua o te mahi i te katoa. Ko te mutunga, ka taea e tatou te whakararuraru i te mahi o, hei tauira, nga whakatere. Mena ka tono tetahi kairangahau ki nga huringa ki nga pukoro, ka tino pa ki nga punaha korero a te teihana.

Ko te takahi i te kaupapa SRP ka puta he wikitoria rauhanga mo te wa poto, engari i te mutunga ka "ngaro tatou i te pakanga", ka tino uaua ki te pupuri i taua taniwha a muri ake nei. He pai ake te wehewehe i te papatono ki nga waahanga motuhake o te waehere, kei ia tangata te kawenga mo te mahi i tetahi mahi motuhake. Ma te mohio ki tenei, me whakarereke te akomanga SpaceStation.

Kia tohatoha tatou i te kawenga

I runga ake i tautuhia e matou nga momo mahi e wha e whakahaerehia ana e te akomanga SpaceStation. Ka mau tonu tatou ki a raatau i te wa e whakahou ana. Ko te waehere kua whakahoutia he pai ake ki te 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

He maha nga huringa, he pai ake te ahua o te kaupapa inaianei. Inaianei kua nui ake ta maatau akomanga SpaceStation hei ipu ka timatahia nga mahi mo nga waahanga whakawhirinaki, tae atu ki te huinga o nga pūoko, he punaha tuku pau, he taika wahie, me nga kaiwhakatairanga.

Mo tetahi o nga taurangi he karaehe e rite ana inaianei: Pūoko; SupplyHolding; Tank wahie; Nga Kaipupuri.

He maha nga huringa nui i tenei putanga o te waehere. Ko te kaupapa ko nga mahi a te tangata takitahi ehara i te mea kookiri noa i roto i o raatau ake karaehe, kua whakaritea kia rite ki te maarama me te rite tonu. Ka whakarōpūhia e matou nga huānga he rite te mahi ki te whai i te kaupapa o te whakakotahitanga. Inaianei, ki te hiahia taatau ki te whakarereke i te mahi a te punaha, neke mai i te anga hash ki te huinga, whakamahia noa te akomanga SupplyHold; kaore matou e pa ki etahi atu waahanga. Ma tenei mahi, ki te whakarereketia e te apiha logistics tetahi mea i roto i tana waahanga, ka noho tonu te toenga o te teihana. I tenei keehi, kaore te akomanga SpaceStation e mohio ki nga huringa.

Kei te harikoa pea a matou apiha e mahi ana i te teihana mokowhiti mo nga huringa na te mea ka taea e ratou te tono i nga mea e hiahiatia ana e ratou. Kia mahara he tikanga kei te waehere penei i te report_supplies me te report_fuel kei roto i nga akomanga SupplyHold me FuelTank. Ka aha mena ka tono a Ao ki te whakarereke i te ahua o ana korero? Ko nga karaehe e rua, SupplyHold me FuelTank, me whakarereke. Ka aha mena ka hiahia koe ki te whakarereke i te huarahi tuku wahie me nga taonga pau? Me huri ano koe i nga karaehe kotahi ano. A kua takahia tenei i te kaupapa SRP. Me whakatika tenei.

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.

I tenei putanga hou o te hotaka, kua wehea nga kawenga kia rua nga karaehe hou, FuelReporter me SupplyReporter. He tamariki raua no te akomanga Kairipoata. I tua atu, i taapirihia e matou nga taurangi tauira ki te akomanga SpaceStation kia arawhiti ai te karaehe iti e hiahiatia ana mena e tika ana. Inaianei, ki te whakatau a te Ao ki te whakarereke i tetahi atu mea, katahi ka whakarereketia e matou nga karaehe iti, kaua ki te akomanga matua.

Ko te tikanga, ko etahi o a maatau akomanga kei te whakawhirinaki tonu tetahi ki tetahi. No reira, ka whakawhirinaki te ahanoa SupplyReporter ki te SupplyHold, ka whakawhirinaki te FuelReporter ki te FuelTank. Ko te tikanga, me hono nga kaiwhaiwhai ki te tank hinu. Engari i konei kua ahua arorau nga mea katoa, a ko te whakarereketanga kaore e tino uaua - ko te whakarereke i te waehere o tetahi mea kaore e pa ki tetahi atu.

No reira, kua hangahia e matou he waehere modular e tautuhia ana nga kawenga o ia taonga/akomanga. Ko te mahi me taua waehere ehara i te raru, he mahi ngawari te pupuri. Kua hurihia e matou te "mea atua" katoa ki te SRP.

Ka tūtohu a Skillbox:

Source: will.com

Tāpiri i te kōrero