β
Mfundo ya Single Responsibility Principle (SRP) imanena kuti kalasi iliyonse kapena gawo lililonse mu pulogalamu liyenera kukhala ndi gawo limodzi lokha la magwiridwe antchito a pulogalamuyi. Kuphatikiza apo, zinthu zaudindozi ziyenera kuperekedwa kwa kalasi yawo, m'malo momwazika m'makalasi osagwirizana. Woyambitsa SRP ndi mlaliki wamkulu, Robert S. Martin, akufotokoza kuyankha ngati chifukwa cha kusintha. Poyambirira adapereka mawuwa ngati chimodzi mwazinthu zantchito yake "Mfundo Zopangira Zinthu Zogwirizana ndi Zinthu". Lingaliroli limaphatikizapo njira zambiri zolumikizirana zomwe zidafotokozedwa kale ndi Tom DeMarco.
Lingaliroli linaphatikizaponso malingaliro angapo opangidwa ndi David Parnas. Ziwiri zazikuluzikulu ndikubisa ndi kubisala chidziwitso. Parnas adanena kuti kugawa dongosolo kukhala magawo osiyana sikuyenera kutengera kusanthula kwazithunzi za block kapena mayendedwe akupha. Ma module aliwonse ayenera kukhala ndi yankho lapadera lomwe limapereka chidziwitso chochepa kwa makasitomala.
Mwa njira, Martin anapereka chitsanzo chochititsa chidwi ndi oyang'anira akuluakulu a kampani (COO, CTO, CFO), omwe aliyense amagwiritsa ntchito mapulogalamu apadera a bizinesi pazinthu zosiyanasiyana. Chotsatira chake, aliyense wa iwo akhoza kukhazikitsa kusintha kwa mapulogalamu popanda kukhudza zofuna za oyang'anira ena.
Chinthu chaumulungu
Monga nthawi zonse, njira yabwino yophunzirira SRP ndikuyiwona ikugwira ntchito. Tiyeni tiwone gawo la pulogalamuyi lomwe silimatsatira Mfundo ya Udindo Umodzi. Iyi ndi kachidindo ka Ruby yomwe imafotokoza machitidwe ndi mawonekedwe a malo okwerera mlengalenga.
Onaninso chitsanzocho ndipo yesani kudziwa zotsatirazi:
Udindo wa zinthu zomwe zalengezedwa mu kalasi ya SpaceStation.
Amene angakhale ndi chidwi ndi ntchito ya malo okwerera mlengalenga.
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
M'malo mwake, malo athu apamlengalenga sakugwira ntchito (sindikuganiza kuti ndilandila foni kuchokera ku NASA posachedwa), koma pali china choti muwunike apa.
Chifukwa chake, kalasi ya SpaceStation ili ndi maudindo angapo (kapena ntchito). Onse a iwo akhoza kugawidwa mu mitundu:
masensa;
zinthu (zowonjezera);
mafuta;
ma accelerator.
Ngakhale palibe wogwira ntchito pasiteshoniyo amapatsidwa kalasi, titha kuganiza kuti ndani ali ndi udindo pa chiyani. Nthawi zambiri, wasayansi amawongolera masensa, woyang'anira mayendedwe ndi omwe ali ndi udindo wopereka zinthu, injiniya ndi amene amayang'anira mafuta, ndipo woyendetsa ndegeyo amawongolera zowonjezera.
Kodi tinganene kuti pulogalamuyi sikugwirizana ndi SRP? Inde, zedi. Koma kalasi ya SpaceStation ndi "chinthu chamulungu" chomwe chimadziwa zonse ndikuchita chilichonse. Ichi ndi chotsutsana chachikulu pakupanga mapulogalamu opangidwa ndi zinthu. Kwa oyamba kumene, zinthu zoterezi zimakhala zovuta kwambiri kuzisamalira. Pakadali pano pulogalamuyi ndi yophweka, inde, koma taganizirani zomwe zidzachitike ngati tiwonjezera zatsopano. Mwina malo athu apamlengalenga adzafuna malo azachipatala kapena chipinda chochitira misonkhano. Ndipo ntchito zikachuluka, SpaceStation imakula. Chabwino, popeza malowa adzalumikizidwa ndi ena, kugwiritsa ntchito zovuta zonse kumakhala kovuta kwambiri. Zotsatira zake, tikhoza kusokoneza ntchito, mwachitsanzo, ma accelerator. Ngati wofufuza apempha kusintha kwa masensa, izi zitha kukhudza kwambiri njira zoyankhulirana za station.
Kuphwanya mfundo ya SRP kungapereke chigonjetso chachifupi, koma pamapeto pake "tidzataya nkhondo", ndipo zidzakhala zovuta kwambiri kusunga chilombo choterocho m'tsogolomu. Ndi bwino kugawa pulogalamuyo m'magawo osiyana a code, yomwe ili ndi udindo wochita ntchito inayake. Pomvetsetsa izi, tiyeni tisinthe kalasi ya SpaceStation.
Tiyeni tigawane udindo
Pamwambapa tafotokoza mitundu inayi ya ntchito zomwe zimayendetsedwa ndi gulu la SpaceStation. Tidzawakumbukira pamene refactoring. Khodi yosinthidwa imagwirizana bwino ndi 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
Pali zosintha zambiri, pulogalamuyo ikuwoneka bwino tsopano. Tsopano kalasi yathu ya SpaceStation yakhala ngati chidebe chomwe chimayambira magawo odalira, kuphatikiza ma sensa, makina ogwiritsira ntchito, tanki yamafuta, ndi zowonjezera.
Pali zosintha zingapo zofunika mu mtundu uwu wa code. Mfundo ndi yakuti ntchito zapayekha sizimangophatikizidwa m'makalasi awo okha, zimakonzedwa m'njira yoti zidziwike bwino komanso zogwirizana. Timagawa zinthu zomwe zili ndi ntchito zofanana kuti titsatire mfundo yogwirizana. Tsopano, ngati tikufuna kusintha momwe dongosolo limagwirira ntchito, kusuntha kuchokera ku hashi kupita ku gulu, ingogwiritsani ntchito gulu la SupplyHold; sitiyenera kukhudza ma module ena. Mwanjira iyi, ngati woyang'anira mayendedwe asintha china chake m'gawo lake, malo ena onsewo azikhalabe. Pankhaniyi, gulu la SpaceStation silidziwa ngakhale kusintha.
Akuluakulu athu ogwira ntchito pamalo okwerera mlengalenga mwina ali okondwa ndi zosinthazi chifukwa amatha kupempha zomwe akufuna. Zindikirani kuti code ili ndi njira monga report_supplies ndi report_fuel zomwe zili m'makalasi a SupplyHold ndi FuelTank. Kodi chingachitike nβchiyani ngati Dziko Lapansi likanati lisinthe mmene limanenera? Makalasi onsewa, SupplyHold ndi FuelTank, adzafunika kusinthidwa. Nanga bwanji ngati mukufuna kusintha momwe mafuta ndi zinthu zina zimaperekera? Muyenera kusintha makalasi onse omwewo kachiwiri. Ndipo izi ndizophwanya kale mfundo ya SRP. Tiyeni tikonze izi.
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.
Mu pulogalamu yaposachedwa iyi, maudindowa adagawidwa m'magulu awiri atsopano, FuelReporter ndi SupplyReporter. Onse ndi ana a kalasi ya Reporter. Kuphatikiza apo, tidawonjeza zosinthika ku kalasi ya SpaceStation kuti gawo lomwe mukufuna likhazikitsidwe ngati kuli kofunikira. Tsopano, ngati Dziko Lapansi lisankha kusintha china chake, ndiye kuti tidzasintha ku subclasses, osati ku kalasi yayikulu.
Inde, ena mwa makalasi athu amadalirabe wina ndi mnzake. Chifukwa chake, chinthu cha SupplyReporter chimadalira SupplyHold, ndipo FuelReporter imadalira FuelTank. Zachidziwikire, zowonjezera ziyenera kulumikizidwa ndi thanki yamafuta. Koma apa zonse zikuwoneka zomveka, ndipo kusintha sikudzakhala kovuta kwambiri - kusintha ndondomeko ya chinthu chimodzi sikudzakhudza kwambiri wina.
Chifukwa chake, tapanga code yokhazikika pomwe maudindo a chinthu chilichonse/makalasi amafotokozedwa ndendende. Kugwira ntchito ndi code yotere si vuto, kusunga izo kudzakhala ntchito yosavuta. Tasintha "chinthu chaumulungu" chonse kukhala SRP.