βcov Liskov Hloov Txoj Cai (Liskov hloov txoj cai). Cov haujlwm uas siv lub hauv paus hom yuav tsum siv cov subtypes ntawm lub hauv paus yam tsis paub txog.
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
Qhov tseeb, peb qhov chaw nres tsheb tsis zoo (Kuv tsis xav tias kuv yuav tau txais kev hu xovtooj los ntawm NASA txhua lub sijhawm sai sai), tab sis muaj qee yam los tshuaj xyuas ntawm no.
Yog li, chav kawm SpaceStation muaj ntau lub luag haujlwm sib txawv (lossis ua haujlwm). Tag nrho lawv tuaj yeem muab faib ua hom:
sensors;
khoom siv (consumables);
roj;
accelerators.
Txawm hais tias tsis muaj ib lub chaw nres tsheb cov neeg ua haujlwm raug xaiv ib chav kawm, peb tuaj yeem yooj yim xav txog seb leej twg yog tus lav ris rau dab tsi. Feem ntau, tus kws tshawb fawb tswj cov sensors, tus neeg tsav tsheb yog lub luag haujlwm rau kev muab cov khoom siv, tus engineer yog lub luag haujlwm rau cov khoom siv roj, thiab tus tsav tsheb tswj cov boosters.
Peb puas tuaj yeem hais tias qhov program no tsis ua raws li SRP? Yog, tseeb. Tab sis chav kawm SpaceStation yog ib qho "vajtswv khoom" uas paub txhua yam thiab ua txhua yam. Qhov no yog ib qho kev tawm tsam loj hauv cov phiaj xwm kev taw qhia. Rau ib tug beginner, xws li cov khoom yog heev nyuaj rau tswj. Txog tam sim no qhov kev pab cuam yooj yim heev, yog, tab sis xav txog yuav ua li cas yog tias peb ntxiv cov yam ntxwv tshiab. Tej zaum peb qhov chaw nres tsheb yuav xav tau chaw kho mob lossis chav sib tham. Thiab ntau lub zog muaj, ntau qhov SpaceStation yuav loj tuaj. Zoo, txij li qhov chaw no yuav txuas nrog rau lwm tus, kev pabcuam tag nrho txoj haujlwm yuav nyuaj dua. Yog li ntawd, peb tuaj yeem cuam tshuam kev ua haujlwm ntawm, piv txwv li, accelerators. Yog tias tus kws tshawb fawb thov hloov pauv cov sensors, qhov no tuaj yeem cuam tshuam zoo rau lub chaw nres tsheb cov kev sib txuas lus.
Kev ua txhaum cai ntawm SRP yuav ua rau lub sijhawm luv luv tactical yeej, tab sis thaum kawg peb yuav "poob tsov rog", thiab nws yuav nyuaj heev los tuav tus dab zoo li no yav tom ntej. Nws yog qhov zoo tshaj plaws los faib qhov kev zov me nyuam rau hauv cov kab ke sib cais, txhua tus yog lub luag haujlwm rau kev ua haujlwm tshwj xeeb. To taub qhov no, cia peb hloov chav kawm SpaceStation.
Cia peb faib lub luag haujlwm
Saum toj no peb tau txhais plaub hom kev ua haujlwm uas tau tswj los ntawm chav kawm SpaceStation. Peb yuav khaws lawv hauv siab thaum refactoring. Cov lej hloov tshiab zoo dua qub nrog 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
Muaj ntau qhov kev hloov pauv, qhov program twv yuav raug hu zoo dua tam sim no. Tam sim no peb chav kawm SpaceStation tau dhau los ua ntau lub thawv uas tau pib ua haujlwm rau qhov chaw nyob, suav nrog cov txheej txheem sensors, cov khoom siv hluav taws xob, lub tank roj, thiab cov boosters.
Muaj ntau qhov kev hloov pauv tseem ceeb hauv qhov version ntawm tus lej no. Lub ntsiab lus yog tias ib tus neeg ua haujlwm tsis yog nyob hauv lawv tus kheej cov chav kawm xwb, lawv tau teeb tsa hauv txoj hauv kev los ua kom paub tseeb thiab sib xws. Peb pab pawg ua haujlwm nrog cov haujlwm zoo sib xws kom ua raws li lub hauv paus ntsiab lus ntawm kev sib koom ua ke. Tam sim no, yog tias peb yuav tsum hloov txoj hauv kev ua haujlwm, txav los ntawm cov qauv hash mus rau ib qho array, tsuas yog siv chav kawm SupplyHold; peb tsis tas yuav kov lwm cov qauv. Txoj kev no, yog tias tus tub ceev xwm logistics hloov qee yam hauv nws ntu, tus so ntawm lub chaw nres tsheb yuav nyob twj ywm. Hauv qhov no, chav kawm SpaceStation yuav tsis paub txog qhov hloov pauv.
Peb cov tub ceev xwm ua haujlwm ntawm qhov chaw nres tsheb yuav zoo siab txog qhov kev hloov pauv vim lawv tuaj yeem thov qhov lawv xav tau. Daim ntawv ceeb toom tias cov cai muaj txoj hauv kev xws li report_supplies thiab report_fuel muaj nyob rau hauv SupplyHold thiab FuelTank chav kawm. Yuav ua li cas yog lub ntiaj teb thov kom hloov txoj kev nws qhia? Ob chav kawm, SupplyHold thiab FuelTank, yuav tsum tau hloov. Yuav ua li cas yog tias koj yuav tsum tau hloov cov roj thiab consumables xa? Tej zaum koj yuav tau hloov tag nrho cov chav kawm qub dua. Thiab qhov no twb yog ib qho txhaum cai ntawm SRP. Cia peb kho qhov no.
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.
Hauv qhov kev hloov tshiab kawg no, lub luag haujlwm tau muab faib ua ob chav kawm tshiab, FuelReporter thiab SupplyReporter. Nkawd yog ob tug me nyuam ntawm chav Reporter. Tsis tas li ntawd, peb ntxiv cov piv txwv piv txwv rau SpaceStation chav kawm kom cov subclass xav tau tuaj yeem pib yog tias tsim nyog. Tam sim no, yog lub ntiaj teb txiav txim siab hloov lwm yam, ces peb yuav hloov pauv rau cov subclasses, thiab tsis yog rau cov chav kawm loj.
Tau kawg, qee qhov ntawm peb cov chav kawm tseem nyob ntawm ib leeg. Yog li, SupplyReporter khoom nyob ntawm SupplyHold, thiab FuelReporter nyob ntawm FuelTank. Tau kawg, cov boosters yuav tsum tau txuas nrog lub tank roj. Tab sis ntawm no txhua yam twb zoo li muaj laj thawj, thiab kev hloov pauv yuav tsis nyuaj tshwj xeeb - kho cov cai ntawm ib yam khoom yuav tsis cuam tshuam rau lwm tus.
Yog li, peb tau tsim ib qho kev cai modular uas lub luag haujlwm ntawm txhua yam ntawm cov khoom / chav kawm raug txhais tau meej. Ua haujlwm nrog cov cai zoo li no tsis yog teeb meem, kev tswj hwm nws yuav yog ib txoj haujlwm yooj yim. Peb tau hloov tag nrho "qhov khoom los saum ntuj los" rau hauv SRP.