Ruby on Rails modulēšana ar Packwerk Episode I
Cilvēkiem ir grūti saskatīt problēmas kopainu, neveltot tam daudz laika un pūļu. Īpaši tas notiek, strādājot ar lielām un sarežģītām lietojumprogrammām.....
Bieži sastopama problēma, strādājot ar Rails, ir izlemt, kur izvietot mūsu funkciju loģiku.
Loģika bieži vien tiek ievietota kontrolieros, modeļos vai, ja mums paveicas, pakalpojuma objektā. Tātad, ja mums ir pakalpojumu objekti, tad kāpēc mums ir vajadzīgi lietojuma gadījumi?
Sekojiet man šajā rakstā, lai atklātu priekšrocības šo modeli.
Lietošanas gadījums ir darbību vai notikumu soļu saraksts, kas parasti nosaka mijiedarbību starp lomu un sistēmu, lai sasniegtu mērķi.
Ir vērts pieminēt, ka šis modelis tiek izmantots dažādos veidos un tam ir dažādi nosaukumi. Mēs to varam atrast kā Interaktori, Operatori vai Komandas, bet Rubīns kopiena mēs pieturēties ar Lietošanas gadījums. Katra implementācija ir atšķirīga, bet tai ir viens un tas pats mērķis - kalpot sistēmas lietotāja lietojumam.
Pat ja mūsu projekts mēs nenosakām prasības, izmantojot Lietošanas gadījumss un UML šis modelis joprojām ir noderīgs, lai praktiski strukturētu biznesa loģiku.
Mūsu Lietošanas gadījumi jābūt:
Pieņemsim piemēru ar lietotāju, kas vēlas kaut ko iegādāties mūsu sistēmā.
modulis UseCases
modulis Pircējs
klase Pirkums
def initialize(pircējs:, grozs:)
@buyer = buyer
@cart = cart
end
def call
return ja vien check_stock
return ja vien create_purchase
paziņot end end
privāts
attr_reader :buyer, :cart
def check_stock
Services::CheckStock.call(cart: cart)
end
def create_purchase
Services::CreatePurchase.call(buyer: buyer, cart: cart).call
end
def notify
Services::NotifyBuyer.call(buyer: buyer)
end
end
end
end
Kā redzat šajā kods Piemēram, mēs izveidojām jaunu Lietošanas gadījums sauc par pirkumu. Mēs definējām tikai vienu publisko metodi zvaniet. Izsaukuma metodes iekšpusē ir atrodami diezgan pamata soļi, lai veiktu pirkumu, un visi soļi ir definēti kā privātas metodes. Katrā solī tiek izsaukts pakalpojuma objekts, tādējādi mūsu Lietošanas gadījums ir definēti tikai pirkuma veikšanas soļi, nevis pati loģika. Tas dod mums skaidru priekšstatu par to, ko var izdarīt mūsu sistēmā (veikt pirkumu), un soļus, kā to panākt.
Tagad mēs esam gatavi izsaukt mūsu pirmo Lietošanas gadījums no kontroliera.
klase Controller
def purchase
UseCases::Buyer::Purchase.new(
buyer: purchase_params[:buyer],
cart: purchase_params[:cart]
).call
...
beigas
...
beigas
No šāda viedokļa Lietošanas gadījums izskatās līdzīgi kā pakalpojuma objekts, taču mērķis ir atšķirīgs. Pakalpojuma objekts veic zema līmeņa uzdevumu un mijiedarbojas ar dažādām sistēmas daļām, piemēram, datu bāzi, bet pakalpojuma objekts Lietošanas gadījums rada jaunu augsta līmeņa abstrakciju un definē loģiskos soļus.
Mūsu pirmais Lietošanas gadījums darbojas, bet varētu būt labāks. Kā mēs to varētu uzlabot? Izmantosim sausais dārgakmeņi. Šajā gadījumā mēs izmantosim sausais darījums.
Vispirms definēsim mūsu bāzes klasi.
UseCase klase
include Dry::Transaction
klase << self
def call(**args)
new.call(**args)
end
end
end
Tas palīdzēs mums nodot atribūtus UseCase transakcijai un izmantot tos. Tad mēs esam gatavi no jauna definēt mūsu iepirkuma lietojuma gadījumu.
modulis UseCases
modulis Pircējs
klase Pirkums
def initialize(pircējs:, grozs:)
@buyer = buyer
@cart = cart
end
def call
return ja vien check_stock
return unless create_purchase
paziņot
end
privāts
attr_reader :buyer, :cart
def check_stock
Services::CheckStock.call(cart: cart)
end
def create_purchase
Services::CreatePurchase.call(buyer: buyer, cart: cart).call
end
def notify
Services::NotifyBuyer.call(buyer: buyer)
end
end
end
end
Ar jaunajām izmaiņām mēs varam skaidri redzēt, kā ir definēti mūsu soļi, un varam pārvaldīt katra soļa rezultātu, izmantojot Success() un Failure().
Mēs esam gatavi izsaukt mūsu jauno lietojuma gadījumu kontrolierī un sagatavot atbildi atkarībā no galarezultāta.
klase Controller
def purchase
UseCases::Buyer::Purchase.new.call(
buyer: purchase_params[:buyer],
cart: purchase_params[:cart]
) do |result|
result.success do
...
end
result.failure do
...
end
end
...
beigas
...
beigas
Šo piemēru varētu vēl vairāk uzlabot ar validāciju, taču ar to pietiek, lai parādītu šī modeļa iespējas.
Būsim godīgi, ka Lietošanas gadījuma modelis ir diezgan vienkāršs un ļoti līdzinās pakalpojuma objektam, taču šis abstrakcijas līmenis var būtiski mainīt jūsu lietojumprogrammu.
Iedomājieties jaunu izstrādātājs pievienojoties projektam un atverot mapi use_cases, pirmais iespaids būs tāds, ka viņš redzēs visu sistēmā pieejamo funkciju sarakstu, un, atverot vienu lietojuma gadījumu, viņš redzēs visas nepieciešamās darbības, kas saistītas ar šo funkciju, neiedziļinoties loģikā. Šī kārtības un kontroles sajūta ir galvenā šī modeļa priekšrocība.
Ņemiet to savā darbarīku kastē, un varbūt nākotnē jūs to labi izmantosiet.
