Ruby on Rails módúlun með Packwerk Episode I
Mönnum finnst erfitt að sjá heildarmynd vandamálsins án þess að verja miklum tíma og fyrirhöfn. Þetta gerist sérstaklega þegar unnið er með stórar og flóknar forritanir....
Algengt vandamál þegar unnið er með Rails er að ákveða hvar eigi að setja lógíkina úr eiginleikunum okkar.
Hér er tómt.Rökfræði er oft sett í stjórnendur (controllers) eða módel (models), eða ef heppnin er með okkur í þjónustuhlut (Service Object). Svo ef við höfum þjónustuhluti, af hverju þurfum við þá notkunartilvik (Use Cases)?
Fylgdu mér í þessari grein til að uppgötva kosti þessa mynsturs.
Notkunartilvik er listi yfir aðgerðir eða atburðarstig sem venjulega skilgreina samskipti milli hlutverks og kerfis til að ná markmiði.
Það er þess virði að nefna að þetta mynstur er beitt á margvíslegan hátt og hefur önnur nöfn. Við getum fundið það sem Viðskiptavinir, Rekendur eða Skipanir, en í Rúbín samfélag sem við stöndum með Notkunartilvik. Hver innleiðing er ólík en með sama tilgangi: að þjóna notanda í notkunartilfelli kerfisins.
Jafnvel ef í okkar verkefni Við erum ekki að skilgreina kröfurnar með því að nota NotkunartilvikMeð s og UML er þetta mynstur enn gagnlegt til að byggja upp viðskiptalógíkina á hagnýtan hátt.
Okkar Notkunartilvik verður að vera:
Tökum dæmi um notanda sem vill kaupa eitthvað í kerfinu okkar.
module UseCases
module Buyer
class Purchase
def initialize(buyer:, cart:)
@buyer = buyer
@cart = cart
end
def call
return unless check_stock
return unless create_purchase
notify end
private
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
Eins og þú gætir séð í þessu kóði til dæmis, við bjuggum til nýtt Notkunartilvik kallað Purchase. Við skilgreindum aðeins eina almenna aðferð hringja. Inni í call-aðferðinni finnum við nokkuð grunnskref til að gera kaup, og öll skrefin eru skilgreind sem einkareiginleikar. Hvert skref kallar á þjónustuhlut, þannig að okkar Notkunartilvik er eingöngu að skilgreina skrefin til að gera kaup en ekki sjálfa rökin. Þetta gefur okkur skýr mynd af því hvað hægt er að gera í kerfinu okkar (að gera kaup) og skrefunum til að ná því fram.
Nú erum við tilbúin að kalla fyrsta okkar. Notkunartilvik frá stýritæki.
class Controller
def purchase
UseCases::Buyer::Purchase.new(
buyer: purchase_params[:buyer],
cart: purchase_params[:cart]
).call
...
end
...
end
Úr þessu sjónarhorni, Notkunartilvik Lítur nánast út eins og þjónustuhlutur en tilgangurinn er annar. Þjónustuhlutur sinnir lággreiðsluverkefni og hefur samskipti við mismunandi hluta kerfisins, eins og gagnagrunninn, á meðan Notkunartilvik býr til ný hásstigs abstraktjón og skilgreinir rökréttu skrefin.
Okkar fyrsti Notkunartilvik Virkar en gæti verið betra. Hvernig gætum við bætt það? Skulum nýta okkur þurr göng. Í þessu tilfelli ætlum við að nota þurr-viðskipti.
Fyrst skulum við skilgreina grunnflokkinn okkar.
class UseCase
include Dry::Transaction
class << self
def call(**args)
new.call(**args)
end
end
end
Þetta mun hjálpa okkur að senda eiginleika til UseCase-viðskiptanna og nota þá. Þá erum við tilbúin að endurskilgreina kaupnotkunartilfellið okkar.
module UseCases
module Buyer
class Purchase
def initialize(buyer:, cart:)
@buyer = buyer
@cart = cart
end
def call
return unless check_stock
return unless create_purchase
notify
end
private
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
Með nýju breytingunum sjáum við skýrt hvernig skrefin okkar eru skilgreind og getum stjórnað niðurstöðu hvers skrefs með Success() og Failure().
Við erum tilbúin að kalla á nýja notendatilfellið í stýritækinu og undirbúa svarið okkar eftir lokaniðurstöðunni.
class 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
...
end
...
end
Þetta dæmi mætti bæta enn frekar með gildiskönnunum, en þetta dugar til að sýna mátt þessa mynsturs.
Verum heiðarleg hér, Notkunartilfella mynstur er nokkuð einfalt og lítur mjög út eins og þjónustuhlutur, en þessi stig abstraktions getur gert mikinn mun á forritinu þínu.
Ímyndaðu þér nýtt þróunaraðili Þegar hann gengur til liðs við verkefnið og opnar möppuna use_cases, fær hann sem fyrstu sýn lista yfir allar aðgerðir sem kerfið býður upp á, og eftir að hann opnar eina notkunartilvik sér hann öll nauðsynleg skref fyrir þá aðgerð án þess að kafa ofan í kerfisfræði. Þetta skynjun reglu og stjórnunar er helsti ávinningur þessa mynsturs.
Taktu þetta í verkfærakistuna þína og kannski munt þú nýta það vel í framtíðinni.
