Avastage Pythoni võimsad käitumuslikud disainimustrid: Vaatleja, Strateegia ja Käsklus. Õppige praktiliste näidete abil, kuidas parandada koodi paindlikkust, hooldatavust ja skaleeritavust.
Pythoni käitumuslikud mustrid: Vaatleja, Strateegia ja Käsklus
Käitumuslikud disainimustrid on tarkvaraarendaja arsenalis olulised tööriistad. Nad lahendavad tavalisi suhtlus- ja interaktsiooniprobleeme objektide vahel, mis viib paindlikuma, hooldatavama ja skaleeritavama koodini. See põhjalik juhend süveneb kolme olulisse käitumuslikku mustrisse Pythonis: Vaatleja, Strateegia ja Käsklus. Uurime nende eesmärki, implementeerimist ja reaalseid rakendusi, varustades teid teadmistega, et neid mustreid oma projektides tõhusalt ära kasutada.
Käitumuslike mustrite mõistmine
Käitumuslikud mustrid keskenduvad objektidevahelisele suhtlusele ja interaktsioonile. Nad defineerivad algoritme ja jaotavad vastutust objektide vahel, tagades lõdva sidususe ja paindlikkuse. Neid mustreid kasutades saate luua süsteeme, mida on lihtne mõista, muuta ja laiendada.
Käitumuslike mustrite kasutamise peamised eelised on:
- Parem koodi organiseeritus: Kapseldades spetsiifilisi käitumisi, edendavad need mustrid modulaarsust ja selgust.
- Suurem paindlikkus: Need võimaldavad teil muuta või laiendada süsteemi käitumist ilma selle põhikomponente muutmata.
- Vähendatud sidusus: Käitumuslikud mustrid soodustavad objektide vahelist lõtva sidusust, muutes koodibaasi hooldamise ja testimise lihtsamaks.
- Suurendatud taaskasutatavus: Mustreid endid ja neid implementeerivat koodi saab taaskasutada rakenduse erinevates osades või isegi erinevates projektides.
Vaatleja muster
Mis on Vaatleja muster?
Vaatleja muster defineerib objektide vahel ühe-mitmele sõltuvuse, nii et kui ühe objekti (subjekti) olek muutub, teavitatakse ja uuendatakse automaatselt kõiki selle sõltlasi (vaatlejaid). See muster on eriti kasulik, kui teil on vaja säilitada järjepidevus mitme objekti vahel, tuginedes ühe objekti olekule. Seda nimetatakse mõnikord ka Avalda-Telli (Publish-Subscribe) mustriks.
Mõelge sellest kui ajakirja tellimisest. Teie (vaatleja) registreerite end, et saada uuendusi (teavitusi), kui ajakiri (subjekt) avaldab uue numbri. Te ei pea pidevalt uusi numbreid kontrollima; teid teavitatakse automaatselt.
Vaatleja mustri komponendid
- Subjekt (Subject): Objekt, mille olek pakub huvi. See hoiab nimekirja vaatlejatest ja pakub meetodeid vaatlejate lisamiseks (tellimiseks) ja eemaldamiseks (tellimuse tühistamiseks).
- Vaatleja (Observer): Liides või abstraktne klass, mis defineerib uuendusmeetodi, mida subjekt kutsub välja, et teavitada vaatlejaid olekumuutustest.
- Konkreetne subjekt (ConcreteSubject): Subjekti konkreetne implementatsioon, mis hoiab olekut ja teavitab vaatlejaid oleku muutumisel.
- Konkreetne vaatleja (ConcreteObserver): Vaatleja konkreetne implementatsioon, mis implementeerib uuendusmeetodi, et reageerida subjekti olekumuutustele.
Pythoni implementatsioon
Siin on Pythoni näide, mis illustreerib Vaatleja mustrit:
class Subject:
def __init__(self):
self._observers = []
self._state = None
def attach(self, observer):
self._observers.append(observer)
def detach(self, observer):
self._observers.remove(observer)
def notify(self):
for observer in self._observers:
observer.update(self._state)
@property
def state(self):
return self._state
@state.setter
def state(self, new_state):
self._state = new_state
self.notify()
class Observer:
def update(self, state):
raise NotImplementedError
class ConcreteObserverA(Observer):
def update(self, state):
print(f"ConcreteObserverA: Olek muudetud {state}")
class ConcreteObserverB(Observer):
def update(self, state):
print(f"ConcreteObserverB: Olek muudetud {state}")
# Näidiskasutus
subject = Subject()
observer_a = ConcreteObserverA()
observer_b = ConcreteObserverB()
subject.attach(observer_a)
subject.attach(observer_b)
subject.state = "Uus olek"
subject.detach(observer_a)
subject.state = "Teine olek"
Selles näites haldab `Subject` `Observer` objektide nimekirja. Kui `Subject` olek muutub, kutsub see välja meetodi `notify()`, mis itereerib läbi vaatlejate nimekirja ja kutsub välja nende `update()` meetodi. Iga `ConcreteObserver` reageerib seejärel olekumuutusele vastavalt.
Reaalse maailma rakendused
- Sündmuste käsitlemine: GUI raamistikes kasutatakse Vaatleja mustrit laialdaselt sündmuste käsitlemiseks. Kui kasutaja interakteerub kasutajaliidese elemendiga (nt klikib nupul), teavitab element (subjekt) registreeritud kuulajaid (vaatlejaid) sündmusest.
- Andmete edastamine: Finantsrakendustes edastavad aktsiate kursitabelid (subjektid) hinnavärskendusi registreeritud klientidele (vaatlejatele).
- Arvutustabelite rakendused: Kui lahter arvutustabelis muutub, arvutatakse ja uuendatakse sõltuvad lahtrid (vaatlejad) automaatselt.
- Sotsiaalmeedia teavitused: Kui keegi postitab sotsiaalmeedia platvormil, teavitatakse tema jälgijaid (vaatlejaid).
Vaatleja mustri eelised
- Lõtv sidusus: Subjekt ja vaatlejad ei pea teadma üksteise konkreetseid klasse, mis soodustab modulaarsust ja taaskasutatavust.
- Skaleeritavus: Uusi vaatlejaid saab hõlpsasti lisada ilma subjekti muutmata.
- Paindlikkus: Subjekt saab vaatlejaid teavitada mitmel erineval viisil (nt sünkroonselt või asünkroonselt).
Vaatleja mustri puudused
- Ootamatud uuendused: Vaatlejaid võidakse teavitada muudatustest, millest nad huvitatud pole, mis viib ressursside raiskamiseni.
- Uuenduste ahelad: Kaskaaduvad uuendused võivad muutuda keerukaks ja raskesti silutavaks.
- Mälulekked: Kui vaatlejaid ei eemaldata korralikult, ei pruugita neid prügikoristusega eemaldada, mis viib mäluleketeni.
Strateegia muster
Mis on Strateegia muster?
Strateegia muster defineerib algoritmide perekonna, kapseldab igaühe neist ja muudab need omavahel vahetatavaks. Strateegia laseb algoritmil varieeruda sõltumatult klientidest, kes seda kasutavad. See muster on kasulik, kui teil on ülesande täitmiseks mitu viisi ja te soovite nende vahel käitusajal vahetada ilma kliendi koodi muutmata.
Kujutage ette, et reisite ühest linnast teise. Saate valida erinevaid transpordistrateegiaid: lennuk, rong või auto. Strateegia muster võimaldab teil valida parima transpordistrateegia, tuginedes teguritele nagu maksumus, aeg ja mugavus, ilma sihtkohta muutmata.
Strateegia mustri komponendid
- Strateegia (Strategy): Liides või abstraktne klass, mis defineerib algoritmi.
- Konkreetne strateegia (ConcreteStrategy): Strateegia liidese konkreetsed implementatsioonid, millest igaüks esindab erinevat algoritmi.
- Kontekst (Context): Klass, mis hoiab viidet Strateegia objektile ja delegeerib algoritmi täitmise sellele. Kontekst ei pea teadma Strateegia spetsiifilist implementatsiooni; see suhtleb ainult Strateegia liidesega.
Pythoni implementatsioon
Siin on Pythoni näide, mis illustreerib Strateegia mustrit:
class Strategy:
def execute(self, data):
raise NotImplementedError
class ConcreteStrategyA(Strategy):
def execute(self, data):
print("Käivitan strateegia A...")
return sorted(data)
class ConcreteStrategyB(Strategy):
def execute(self, data):
print("Käivitan strateegia B...")
return sorted(data, reverse=True)
class Context:
def __init__(self, strategy):
self._strategy = strategy
def set_strategy(self, strategy):
self._strategy = strategy
def execute_strategy(self, data):
return self._strategy.execute(data)
# Näidiskasutus
data = [1, 5, 3, 2, 4]
strategy_a = ConcreteStrategyA()
context = Context(strategy_a)
result = context.execute_strategy(data)
print(f"Tulemus strateegiaga A: {result}")
strategy_b = ConcreteStrategyB()
context.set_strategy(strategy_b)
result = context.execute_strategy(data)
print(f"Tulemus strateegiaga B: {result}")
Selles näites defineerib `Strategy` liides meetodi `execute()`. `ConcreteStrategyA` ja `ConcreteStrategyB` pakuvad sellele meetodile erinevaid implementatsioone, sorteerides andmed vastavalt kasvavas ja kahanevas järjekorras. Klass `Context` hoiab viidet `Strategy` objektile ja delegeerib algoritmi täitmise sellele. Klient saab käitusajal strateegiate vahel vahetada, kutsudes välja meetodi `set_strategy()`.
Reaalse maailma rakendused
- Maksete töötlemine: E-kaubanduse platvormid kasutavad Strateegia mustrit erinevate makseviiside (nt krediitkaart, PayPal, pangaülekanne) toetamiseks. Iga makseviis on implementeeritud kui konkreetne strateegia.
- Saatmiskulude arvutamine: Veebipoed kasutavad Strateegia mustrit saatmiskulude arvutamiseks, tuginedes teguritele nagu kaal, sihtkoht ja saatmisviis.
- Pildikompressioon: Pilditöötlustarkvara kasutab Strateegia mustrit erinevate pildikompressiooni algoritmide (nt JPEG, PNG, GIF) toetamiseks.
- Andmete valideerimine: Andmesisestusvormid saavad kasutada erinevaid valideerimisstrateegiaid sõltuvalt sisestatavate andmete tüübist (nt e-posti aadress, telefoninumber, kuupäev).
- Marsruutimisalgoritmid: GPS-navigatsioonisüsteemid kasutavad erinevaid marsruutimisalgoritme (nt lühim vahemaa, kiireim aeg, vähim liiklus) vastavalt kasutaja eelistustele.
Strateegia mustri eelised
- Paindlikkus: Saate hõlpsasti lisada uusi strateegiaid ilma konteksti muutmata.
- Taaskasutatavus: Strateegiaid saab taaskasutada erinevates kontekstides.
- Kapseldamine: Iga strateegia on kapseldatud oma klassi, mis soodustab modulaarsust ja selgust.
- Avatud/suletud printsiip: Saate süsteemi laiendada, lisades uusi strateegiaid ilma olemasolevat koodi muutmata.
Strateegia mustri puudused
- Suurenenud keerukus: Klasside arv võib suureneda, muutes süsteemi keerukamaks.
- Kliendi teadlikkus: Klient peab olema teadlik erinevatest saadaolevatest strateegiatest ja valima sobiva.
Käsklus muster
Mis on Käsklus muster?
Käsklus muster kapseldab päringu objektiks, võimaldades seeläbi kliente parameetritega varustada erinevate päringutega, päringuid järjekorda panna või logida ning toetada tagasivõetavaid operatsioone. See lahutab operatsiooni käivitava objekti sellest, mis teab, kuidas seda teostada.
Mõelge restoranile. Teie (klient) esitate tellimuse (käskluse) kelnerile (käivitaja). Kelner ei valmista toitu ise; ta edastab tellimuse kokale (vastuvõtja), kes tegelikult toimingu sooritab. Käsklus muster võimaldab teil eraldada tellimisprotsessi toiduvalmistamisprotsessist.
Käsklus mustri komponendid
- Käsklus (Command): Liides või abstraktne klass, mis deklareerib meetodi päringu täitmiseks.
- Konkreetne käsklus (ConcreteCommand): Käsklus liidese konkreetsed implementatsioonid, mis seovad vastuvõtja objekti toiminguga.
- Vastuvõtja (Receiver): Objekt, mis teeb tegeliku töö.
- Käivitaja (Invoker): Objekt, mis palub käsklusel päringu täita. See hoiab Käsklus objekti ja kutsub operatsiooni algatamiseks välja selle execute meetodi.
- Klient (Client): Loob ConcreteCommand objekte ja seab nende vastuvõtja.
Pythoni implementatsioon
Siin on Pythoni näide, mis illustreerib Käsklus mustrit:
class Command:
def execute(self):
raise NotImplementedError
class ConcreteCommand(Command):
def __init__(self, receiver, action):
self._receiver = receiver
self._action = action
def execute(self):
self._receiver.action(self._action)
class Receiver:
def action(self, action):
print(f"Vastuvõtja: Teostan toimingut '{action}'")
class Invoker:
def __init__(self):
self._commands = []
def add_command(self, command):
self._commands.append(command)
def execute_commands(self):
for command in self._commands:
command.execute()
# Näidiskasutus
receiver = Receiver()
command1 = ConcreteCommand(receiver, "Operatsioon 1")
command2 = ConcreteCommand(receiver, "Operatsioon 2")
invoker = Invoker()
invoker.add_command(command1)
invoker.add_command(command2)
invoker.execute_commands()
Selles näites defineerib `Command` liides meetodi `execute()`. `ConcreteCommand` seob `Receiver` objekti spetsiifilise toiminguga. Klass `Invoker` haldab `Command` objektide nimekirja ja täidab need järjestikku. Klient loob `ConcreteCommand` objektid ja lisab need `Invoker`isse.
Reaalse maailma rakendused
- GUI tööriistaribad ja menüüd: Iga nuppu või menüüelementi saab esitada käsklusena. Kui kasutaja klikib nupul, täidetakse vastav käsklus.
- Tehingute töötlemine: Andmebaasisüsteemides saab iga tehingut esitada käsklusena. See võimaldab tagasivõtmise/uuestitegemise funktsionaalsust ja tehingute logimist.
- Makrode salvestamine: Tarkvararakenduste makrode salvestamise funktsioonid kasutavad Käsklus mustrit kasutaja toimingute salvestamiseks ja taasesitamiseks.
- Tööjärjekorrad: Süsteemid, mis töötlevad ülesandeid asünkroonselt, kasutavad sageli tööjärjekordi, kus iga tööd esindab käsklus.
- Kaugprotseduurikutse (RPC): RPC mehhanismid kasutavad Käsklus mustrit kaugete meetodite väljakutsete kapseldamiseks.
Käsklus mustri eelised
- Lahtisidumine: Käivitaja ja vastuvõtja on lahti seotud, mis võimaldab suuremat paindlikkust ja taaskasutatavust.
- Järjekorda panemine ja logimine: Käsklusi saab panna järjekorda ja logida, mis võimaldab funktsioone nagu tagasivõtmine/uuestitegemine ja auditeerimisjäljed.
- Parameetritega varustamine: Käsklusi saab parameetritega varustada erinevate päringutega, muutes need mitmekülgsemaks.
- Tagasivõtmise/uuestitegemise tugi: Käsklus muster muudab tagasivõtmise/uuestitegemise funktsionaalsuse implementeerimise lihtsamaks.
Käsklus mustri puudused
- Suurenenud keerukus: Klasside arv võib suureneda, muutes süsteemi keerukamaks.
- Ülekoormus: Käsklusobjektide loomine ja täitmine võib tekitada teatud ülekoormust.
Kokkuvõte
Vaatleja, Strateegia ja Käsklus mustrid on võimsad tööriistad paindlike, hooldatavate ja skaleeritavate tarkvarasüsteemide ehitamiseks Pythonis. Mõistes nende eesmärki, implementeerimist ja reaalseid rakendusi, saate neid mustreid kasutada tavaliste disainiprobleemide lahendamiseks ning luua robustsemaid ja kohandatavamaid rakendusi. Pidage meeles arvestada iga mustriga seotud kompromisse ja valida see, mis sobib kõige paremini teie konkreetsetele vajadustele. Nende käitumuslike mustrite valdamine parandab oluliselt teie kui tarkvarainseneri võimekust.