Tárgykészlet

Az oldal jelenlegi verzióját még nem ellenőrizték tapasztalt közreműködők, és jelentősen eltérhet a 2022. április 5-én felülvizsgált verziótól ; az ellenőrzések 4 szerkesztést igényelnek .
Tárgykészlet
objektumkészlet
Típusú generáló
Leírása: Tervezési minták Nem

Az  objektumkészlet egy generáló tervezési minta , inicializált és használatra kész objektumok halmaza. Amikor a rendszernek szüksége van egy objektumra, az nem jön létre, hanem kiveszi a készletből. Amikor egy tárgyra már nincs szükség, nem semmisül meg, hanem visszakerül a medencébe.

Alkalmazás

Az objektumkészletezést a teljesítmény javítására használják, amikor egy objektum létrehozása a feladat elején, és a végén megsemmisítése költséges. A teljesítménynövekedés különösen akkor észrevehető, ha az objektumokat gyakran hoznak létre és semmisítik meg, de egyszerre csak kevés van belőlük.

Az objektumkészlet akkor hasznos, ha egy objektum a memórián kívül más erőforrásokkal is rendelkezik, például hálózati socketekkel. Vagy ha az objektumok gyűjteménye a számítógép memóriájának jelentős részét elfoglalja, és sok " szemét " keletkezik.

Túlcsordulás

Ha nincs egyetlen szabad objektum sem a készletben, három stratégia egyike lehetséges:

  1. Medence bővítés.
  2. Objektum létrehozásának megtagadása, vészleállítás.
  3. Többfeladatos rendszer esetén megvárhatja, amíg az egyik objektum felszabadul.

Példák

  1. Információ a DOS-ban megnyitott fájlokról .
  2. Információk sok számítógépes játékban látható tárgyakról ( jó példa a Doom motor ). Ez az információ csak egy keretre vonatkozik; a keret kiadása után a lista kiürül.
  3. Egy számítógépes játék, amely az összes objektumot a térképen tárolja, a szokásos memóriakiosztási mechanizmusok használata helyett olyan méretű tömböt tud létrehozni, amelyről ismert, hogy minden objektum számára elegendő, és a szabad cellákat linkelt lista formájában megtartja. . Ez a kialakítás javítja a sebességet, csökkenti a memória töredezettségét és csökkenti a szemétgyűjtő terhelését (ha van ilyen).

Csapdák

  1. Egy tárgy visszaküldése után vissza kell térnie a további használatra alkalmas állapotba. Ha az objektumok a készletbe való visszatérés után hibás vagy határozatlan állapotban vannak, az ilyen konstrukciót objektumtárolónak nevezzük . 
  2. A tárgyak újrafelhasználása információszivárgáshoz is vezethet. Ha az objektum titkos adatokat tartalmaz (például hitelkártyaszám ), az objektum kiadása után ezeket az információkat felül kell írni.
  3. Egy többszálú objektumkészletet nem könnyű írni.
  4. A 2020-as évekre a hulladékgyűjtő nyelveken a memóriakezelés jól optimalizált az állandó kiosztás-visszarúgáshoz. Tehát, ha az objektum csak memóriát foglal el, a Java kézikönyvek nem javasolják a poolok használatát: egy newnormálhoz mindössze tíz processzorutasítás szükséges. És a szemétgyűjtők gyakran az objektum-hivatkozásokat vizsgálják, nem a memóriájukat - mert minél több „élő” objektum van a memóriában, annál alacsonyabb egy ilyen gyűjtő teljesítménye.

Megvalósítási példa

Python példa

Forráskód Pythonban #kódolás: utf-8 """ Képzeljünk el egy olyan helyzetet, ahol van egy hajónk, amely több lövést is kibír. A Shot objektum létrehozása költséges. Ezért a Shot család objektumai egyszer jönnek létre. És az élettartam után az objektum benne marad memória. """ osztály Shot ( objektum ): """Olyan entitás, amely több találatot is túlél""" def __init__ ( self , lifetime = 5 ): self . élettartam = élettartam def update ( self ): self . élettartam -= 1 visszatérő én . élettartam > 0 class ObjectPool : """Object Pool""" def __init__ ( self , ** kwargs ): """A készlet létrehozása""" self . _clsname = kwargs [ 'osztálynév' ] self . _args = kwargs . get ( 'args' , []) self . _num_objects = max ( kwargs [ 'szám' ], 0 ) self . _pred = kwargs [ 'update_func' ] self . _max_objects = kwargs . get ( 'max' , self . _num_objects ) # Saját objektumok létrehozása . _objs = [ alkalmaz ( self . _clsname , self . _args ) for x in range ( self . _num_objects )] self . _end = len ( self . _objs ) def _extend_list ( self , args ): """Egy hely hozzáadása a készlethez""" self . _objs . append ( alkalmaz ( self . _clsname , args )) self . _objektumok száma += 1 def add ( self , * args ): """Egy objektum hozzáadása a készlethez""" newend = self . _end + 1 # Ha elérte a maximumot, tegye le, ha newend > self . _max_objects : return Nincs # Ha minden hely foglalt, adjon hozzá még egy helyet if newend > len ( self . _objs ): self . _extend_list ( args ) else : self . _objs [ self . _end ] . reset ( * args ) self . _end += 1 önmagát adja vissza . _end - 1 def update ( self , * args ): """A készlet összes objektumának frissítése""" self . _end = partíció ( self . _pred , self . _objs , 0 , self . _end , args ) önmagát adja vissza . _end def update_object ( x ): """Objektum frissítése""" return x . frissítés () def partíció ( pred , seq , first , last , * args ): """Objektumrendezési függvény""" if first > last : return 0 for i in range ( first , last ): ha nem pred ( seq [ i ] ): break else : return last j esetén az ( i + 1 , utolsó ) tartományban : ha pred ( seq [ j ]): seq [ i ], seq [ j ] = seq [ j ], seq [ i ] i += 1 visszatér i # Valójában a pool shots = ObjectPool ( osztálynév = Shot , update_func = update_object , num = 5 ) használata a shots közben . frissítés (): passz nyomtatni "Kész!"

C++ példa

Forrásszöveg C++ nyelven #include <vektor> osztály Objektum { // ... }; osztályú ObjectPool { privát : struct PoolRecord { objektum * példány ; bool in_use ; }; std :: vektor < PoolRecord > m_pool ; nyilvános : Object * CreateNewObject () { for ( size_t i = 0 ; i < m_pool . size (); ++ i ) { if ( ! m_pool [ i ]. in_use ) { m_pool [ i ]. in_use = igaz ; // az objektum átvitele a használtak listájába return m_pool [ i ]. példány ; } } // ha nem találtunk szabad objektumot, akkor bontsa ki a poolRecord rekordot ; rekord . példány = new Object ; rekord . in_use = igaz ; m_pool . push_back ( rekord ); visszatérési rekord . példány ; } void deleteObject ( objektum * objektum ) { // a valóságban nem töröljük, hanem csak azt jelöljük meg, hogy az objektum szabad a számára ( size_t i = 0 ; i < m_pool . size (); ++ i ) { if ( m_pool [ i ]. példány == objektum ) { m_pool [ i ]. in_use = false ; szünet ; } } } virtuális ~ ObjectPool () { // most "igazán" töröljük az objektumokat a következőhöz: ( size_t i = 0 ; i < m_pool . size (); ++ i ) az m_pool [ i ] törlése . példány ; } }; int main () { Object Pool ; for ( méret_t i = 0 ; i < 1000 ; ++ i ) { Object * object = pool . CreateNewObject (); // ... medence . deleteObject ( objektum ); } return 0 ; }

A sablonokat és a szálbiztonságot az egyszerűség kedvéért eltávolítottuk a példából . Ha több szálon keresztül kell használnia a készletet, védje meg a createNewObject és deleteObject metódusok törzsét egy megfelelő szinkronizálási objektum, például kritikus szakasz vagy mutex egyidejű végrehajtásától .

Példa C# -ban

Forrásszöveg C# nyelven névtér Digital_Patterns.Creational.Object_Pool.Soft { /// <summary> /// Interfész az "Object Pool" minta használatához <see cref="Object_Pool"/> /// </summary> /// <typeparam name= " T"></typeparam> nyilvános felület ICreation < T > { /// <summary> /// Visszaadja az újonnan létrehozott objektumot /// </summary> /// <returns></returns> T Létrehoz () ; } } Forrásszöveg C# nyelven a rendszer használatával ; a System.Collections használatával ; a System.Threading használatával ; névtér Digital_Patterns.Creational.Object_Pool.Soft { /// <summary> /// Objektumkészlet megvalósítása soft referenciák segítségével /// </summary> /// <typeparam name="T"></typeparam> public class ObjectPool < T > ahol T : class { /// <summary> /// Szinkronizálási objektum /// </summary> private szemafor szemafor ; /// <summary> /// A gyűjtemény kezelt objektumokat tartalmaz /// </summary> private ArrayList pool ; /// <summary> /// Hivatkozás arra az objektumra, amelyre /// a készlet objektumainak létrehozásának felelőssége delegálva /// </summary> private ICreation < T > creator ; /// <summary> /// A jelenleg létező objektumok száma /// </summary> private Int32 instanceCount ; /// <summary> /// A készlet által kezelt objektumok maximális száma /// </summary> private Int32 maxInstances ; /// <summary> /// Objektumkészlet létrehozása /// </summary> /// <param name="creator">Az objektum, amelyre a készlet átruházza a felelősséget /// az általa kezelt objektumok létrehozásáért< /param> public ObjectPool ( ICreation < T > creator ) : this ( creator , Int32 . MaxValue ) { } /// <summary> /// Objektumkészlet létrehozása /// </summary> /// <param name="creator">Az objektum, amelyre a készlet átruházza a felelősséget /// az általa kezelt objektumok létrehozásáért< /param> / // <param name="maxInstances">Az osztálypéldányok maximális száma ///, amelyet a készlet engedélyez egyidejűleg /// </param> public ObjectPool ( ICreation < T > creator , Int32 maxInstances ) { this . alkotó = alkotó ; ezt . példányszám = 0 ; ezt . maxInstances = maxInstances ; ezt . pool = new ArrayList (); ezt . szemafor = new Semaphore ( 0 , this . maxInstances ); } /// <összefoglaló> /// Visszaadja a készletben lévő objektumok számát, amelyek újrafelhasználásra várnak ///. A tényleges szám /// kisebb lehet ennél az értéknél, mert /// a visszaadott érték a készletben lévő soft referenciák száma. /// </summary> public Int32 Size { get { lock ( pool ) { return pool . gróf ; } } } /// <summary> /// Visszaadja a jelenleg létező egyesített objektumok számát /// /// </summary> public Int32 InstanceCount { get { return instanceCount ; } } /// <összefoglaló> /// Szerezze be vagy állítsa be a felügyelt objektumok /// maximális számát, amelyet a készlet egyidejűleg engedélyez. /// </summary> public Int32 MaxInstances { get { return maxInstances ; } set { maxInstances = érték ; } } /// <összefoglaló> /// Egy objektumot ad vissza a készletből. Üres készlet esetén /// objektum jön létre, ha a készlet által kezelt objektumok /// száma nem nagyobb vagy egyenlő, mint a <see cref="ObjectPool{T} /// által visszaadott érték. MaxInstances"/> metódus. Ha a készlet által kezelt objektumok száma /// meghaladja ezt az értéket, akkor ez a metódus null értékkel tér vissza /// </summary> /// <returns></returns> public T GetObject () { lock ( pool ) { T thisObject = RemoveObject ( ); if ( thisObject != null ) return thisObject ; if ( InstanceCount < MaxInstances ) return CreateObject (); return null ; } } /// <összefoglaló> /// Egy objektumot ad vissza a készletből. Üres készlet esetén /// objektum jön létre, ha a készlet által kezelt objektumok /// száma nem nagyobb vagy egyenlő, mint a <see cref="ObjectPool{T} /// által visszaadott érték. MaxInstances"/> metódus. Ha a készlet által kezelt objektumok /// száma meghaladja ezt az értéket, akkor ez a metódus addig vár, amíg egy objektum /// újrafelhasználhatóvá válik. /// </summary> /// <returns></returns> public T WaitForObject () { lock ( pool ) { T thisObject = RemoveObject (); if ( thisObject != null ) return thisObject ; if ( InstanceCount < MaxInstances ) return CreateObject (); } szemafor . várakozó (); return WaitForObject (); } /// <summary> /// Eltávolít egy objektumot a készletgyűjteményből, és visszaadja /// </summary> /// <returns></returns> private T RemoveObject () { while ( pool . Count > 0 ) { var refThis = ( WeakReference ) pool [ pool . Szám - 1 ]; medence . RemoveAt ( pool . Count - 1 ); var thisObject = ( T ) refThis . Cél ; if ( thisObject != null ) return thisObject ; instanceCount --; } return null ; } /// <summary> /// A készlet által kezelt objektum létrehozása /// </summary> /// <returns></returns> private T CreateObject () { T newObject = creator . létrehozni (); instanceCount ++; return newObject ; } /// <summary> /// Felszabadítja az objektumot, a készletbe helyezve /// újrafelhasználásra /// </summary> /// <param name="obj"></param> /// <kivétel cref ="NullReferenceException"></exception> public void Release ( T obj ) { if ( obj == null ) throw new NullReferenceException (); lock ( pool ) { var refThis = new WeakReference ( obj ); medence . Add ( refThis ); szemafor . kiadás (); } } } } Forrásszöveg C# nyelven névtér Digital_Patterns.Creational.Object_Pool.Soft { public class Újrafelhasználható { public Object [] Objs { get ; védett készlet ; } public Újrafelhasználható ( params Object [ ] objs ) { this . Objs = objs ; } } public class Létrehozó : ICreation < Reusable > { private static Int32 iD = 0 ; public Újrafelhasználható Létrehoz () { ++ iD ; új újrafelhasználható ( iD ) visszaküldése ; } } public class ReusablePool : ObjectPool < Reusable > { public ReusablePool () : base ( new Creator (), 2 ) { } } } Forrásszöveg C# nyelven a rendszer használatával ; a System.Threading használatával ; a Digital_Patterns.Creational.Object_Pool.Soft használatával ; névtér Digital_Patterns { class Program { static void Main ( string [ ] args ) { Console . WriteLine ( System . Reflection . MethodInfo . GetCurrentMethod ( ). Név ); var reusablePool = new ReusablePool (); var thrd1 = új szál ( Futtatás ); var thrd2 = új szál ( Futtatás ); var thisObject1 = reusablePool . GetObject (); var thisObject2 = reusablePool . GetObject (); thrd1 . Start ( reusablePool ); thrd2 . Start ( reusablePool ); ViewObject ( thisObject1 ); ViewObject ( thisObject2 ); szál . Alvás ( 2000 ); újrafelhasználható medence . Release ( thisObject1 ); szál . Alvás ( 2000 ); újrafelhasználható medence . Release ( thisObject2 ); Konzol . ReadKey (); } private static void Futtatás ( Object obj ) { Konzol . WriteLine ( "\t" + System . Reflection . MethodInfo . GetCurrentMethod (). Név ); var reusablePool = ( ReusablePool ) obj ; Konzol . WriteLine ( "\tstart vár" ); var thisObject1 = reusablePool . WaitForObject (); ViewObject ( thisObject1 ); Konzol . WriteLine ( "\tend wait" ); újrafelhasználható medence . Release ( thisObject1 ); } private static void ViewObject ( Újrafelhasználható thisObject ) { foreach ( var obj in thisObject . Objs ) { Console . Write ( obj . ToString () + @" " ); } Konzol . writeLine (); } } }

VB.NET példa

Forrásszöveg VB.NET nyelven Névtér Digital_Patterns.Creational.Object_Pool.Soft ' Interfész az "Object Pool" sablon használatához <lásd cref="Object_Pool"/> Public Interface ICreation ( Of T ) ' Visszaadja az újonnan létrehozott objektumot Function Create () As T End Interface névtér vége Forrásszöveg VB.NET nyelven Névtér Digital_Patterns.Creational.Object_Pool.Soft 'Objektumkészlet-megvalósítás puha hivatkozások használatával Public Class ObjectPool ( Of T As Class ) 'Szinkronizálja az objektumot Privát szemafor szemaforként 'A gyűjtemény felügyelt objektumokat tartalmaz Privát készlet ArrayList néven "Hivatkozás arra az objektumra, amelyre a készlet Private Creator As ICreation ( Of T ) objektumainak létrehozásának felelőssége át van ruházva 'A jelenleg létező objektumok száma Private m_instanceCount As Int32 'Az összevont objektumok maximális száma Privát m_maxInstances As Int32 Az 'Object Pool Creation ' létrehozó az az objektum, amelyre a készlet átruházza a felelősséget az általa kezelt objektumok létrehozásáért Public Sub New ( ByVal creator As ICreation ( Of T )) Me . Új ( készítő , Int32 . MaxValue ) End Sub 'Objektumkészlet létrehozása ' creator - Az objektum, amelyre a készlet átruházza a felelősséget az általa kezelt objektumok létrehozásáért. ' maxInstances - Az osztály azon példányainak maximális száma, amelyeket a készlet egyidejűleg engedélyezni fog Public Sub New ( ByVal creator As ICreation ( Of T ), ByVal maxInstances As Int32 ) me . teremtő = teremtő Én . m_instanceCount = 0 Me . m_maxInstances = maxInstances Me . pool = Új ArrayList () Me . szemafor = Új szemafor ( 0 , Me . m_maxInstances ) End Sub 'A készletben lévő, újrafelhasználásra váró objektumok számát adja vissza . A tényleges szám kisebb lehet ennél az értéknél, mert a visszaadott érték a készletben lévő lágy hivatkozások száma. Nyilvános , csak olvasható tulajdonság mérete () Int32 - ként Get SyncLock pool Return pool . Count End SyncLock End Get End Property 'A jelenleg létező összevont objektumok számát adja vissza. ' Public ReadOnly Property InstanceCount () As Int32 Get Return m_instanceCount End Get End Property Szerezze be vagy állítsa be a készlet által felügyelt objektumok maximális számát, amelyet a készlet egyszerre engedélyez. Public Property MaxInstances ( ) As Int32 Get Return m_max Instances End Get Set ( ByVal érték mint Int32 ) m_maxInstances = érték End Set End Tulajdonság 'Egy tárgyat ad vissza a készletből. Egy üres készlet akkor hoz létre objektumot, ha a készlet által kezelt objektumok száma nem nagyobb vagy egyenlő, mint az ObjectPool{T}.MaxInstances metódus által visszaadott érték. 'Ha a gyűjtött objektumok száma meghaladja ezt az értéket, akkor ez a 'metódus nullát ad vissza Public Function GetObject () As T SyncLock pool Dim thisObject As T = RemoveObject () Ha thisObject IsNot Nothing Akkor ezt az Objectet adja vissza End If If InstanceCount < MaxInstances Then Return CreateObject () End If Return Nothing End SyncLock End Function ' Egy objektumot ad vissza a készletből. Egy üres készlet létrehoz egy "objektumot, ha a gyűjtött objektumok száma " nem nagyobb vagy egyenlő az ObjectPool{T} által visszaadott értékkel. MaxInstances metódus " Ha a gyűjtött objektumok száma meghaladja ezt az értéket, akkor ez a metódus vár. amíg az objektum nem lesz elérhető újrafelhasználásra. Nyilvános függvény WaitForObject () As T SyncLock készlet Dim thisObject mint T = RemoveObject () Ha ez az objektum nem semmi , akkor adja vissza ezt az objektumot End If If InstanceCount < MaxInstances Then Return CreateObject () End If End SyncLock szemafor . WaitOne () Return WaitForObject ( ) Végfüggvény ' Eltávolít egy objektumot a készletgyűjteményből, és visszaadja Private Function RemoveObject () As T While készletként . Szám > 0 Dim refThis = DirectCast ( pool ( készlet . Szám - 1 ), Gyenge hivatkozás ) pool . RemoveAt ( pool . Count - 1 ) Dim thisObject = DirectCast ( refThis . Target , T ) If thisObject IsNothing then Return thisObject End If m_instanceCount - = 1 End While Return Nothing Befejezési függvény ' Hozzon létre egy objektumot, amelyet ez a készlet kezel. Privát függvény CreateObject () As T Dim newObject As T = creator . Create () m_instanceCount += 1 Új Object End Function visszaadása ' Felszabadítja az objektumot, és a készletbe helyezi újrafelhasználás céljából Nyilvános alkiadás ( ByVal obj As T ) Ha az obj semmi , akkor dobjon új NullReferenceException () End If SyncLock pool Dim refThis = New WeakReference ( obj ) pool . Adjon hozzá ( refThis ) szemafort . Release () End SyncLock End Sub End Class End névtér Forrásszöveg VB.NET nyelven Névtér Digital_Patterns.Creational.Object_Pool.Soft '### Osztály újrafelhasználható #### Nyilvános osztály Újrafelhasználható Privát m_Objs mint objektum () Public Sub New ( ByVal ParamArray objs As Object ( )) Me . Objs = objs End Sub Public Property Objs () Objektumként ( ) Get Return m_Objs End Get Védett halmaz ( ByVal érték mint objektum ( ) ) m_Objs = érték Végkészlet vége Tulajdonság végosztály '### Class Creator #### Public Class Creator valósítja meg az ICreation-t ( újrafelhasználható ) Privát megosztott azonosító , mint Int32 = 0 Nyilvános funkció Create () As Reusable Implements ICreation ( Of Reusable ). Create iD += 1 Return New Reusable ( iD ) End Function End Class „### ReusablePool Class #### Public Class ReusablePool örökli az ObjectPool- t ( az újrafelhasználhatóból ) Nyilvános Sub Új () MyBase . Új ( Új alkotó (), 2 ) End Sub End Class End névtér Forrásszöveg VB.NET nyelven Importálás System.Threading Importálás Digital_Patterns.Creational.Object_Pool.Soft Névtér Digital_Patterns Class Program Megosztott al- () Konzol . WriteLine ( System . Reflection . MethodInfo . GetCurrentMethod ( ). Név ) Dim reusablePool = New ReusablePool ( ) Dim thrd1 = Új szál ( Futtatás címe ) Dim thrd2 = Új szál ( Futtatás címe ) Dim thisObject1 = reusablePool . GetObject () Dim thisObject2 = reusablePool . GetObject () thrd1 . Start ( reusablePool ) thrd2 . Indítás ( reusablePool ) ViewObject ( thisObject1 ) ViewObject ( thisObject2 ) szál . Sleep ( 2000 ) reusablePool . Kiadás ( thisObject1 ) szál . Sleep ( 2000 ) reusablePool . Kiadás ( thisObject2 ) Konzol . ReadKey () End Sub Privát megosztott alfutás ( ByVal obj As [ Object ] ) konzol . _ WriteLine ( vbTab & System . Reflection . MethodInfo . GetCurrentMethod (. Név ) Dim reusablePool = DirectCast ( obj , ReusablePool ) Konzol . WriteLine ( vbTab & "kezdési várakozás" ) Dim thisObject1 = reusablePool . WaitForObject () ViewObject ( thisObject1 ) konzol . WriteLine ( vbTab & "end wait" ) reusablePool . Release ( thisObject1 ) End Sub Privát megosztott alnézeti objektum ( ByVal thisObject újrafelhasználhatóként ) Minden objektumhoz , mint objektum ebben az objektumban . Objs konzol . Write ( obj . ToString ( ) & " " ) Következő konzol . WriteLine () End Sub End Class End névtér

Perl példa

Forrásszöveg Perlben #!/usr/bin/perl -w = megjegyzésre Az ObjectPool modul úgy valósítja meg az "objektumkészlet" programozási mintát, hogy szimulálja egy íjász viselkedését, akinek korlátozott számú nyila van a tegezében, aminek következtében rendszeresen fel kell vennie azokat. A csomag az íjász viselkedését írja le = vágott csomag íjász { használd a Quivert ; # tegez íjász nyilaival szigorúan használd ; figyelmeztetések használata ; konstans használata ARROWS_NUMBER => 5 ; # a nyilak száma a tegezben használjon állandót SLEEP_TIME => 3 ; # maximális szünet két művelet között (másodpercben) # -- ** konstruktor ** -- sub new { my $class = shift ; my $self = { tegez => Tegez -> new ( ARROWS_NUMBER ), # "Quiver" osztály objektuma }; áldja meg $self , $class ; return $self ; } # -- ** felvétel inicializálása ** -- sub shooting_start { my ( $self ) = ( shift ); while ( 1 ) { # feltételesen végtelen ciklus, amely $self -> shoot () for ( 0 .. rand ( ARROWS_NUMBER - 1 )); # véletlenszerű számú lövés $self -> újratöltés () for ( 0 .. rand ( ARROWS_NUMBER - 1 )); # véletlenszerű számú kilőtt nyilak } } # -- ** shot ** -- sub shoot { my ( $self ) = ( shift ); $self -> { tegez } -> arrow_pull (); # küldje el a nyilat a pokolba alvás rand ( SLEEP_TIME ); # ... és várj a végtelenségig } # -- ** a kilőtt nyíl visszaadása ** -- sub reload { my ( $self ) = ( shift ); $self -> { tegez } -> arrow_return (); # visszaadja az előzőleg kilőtt nyilat alvó rand -ot ( SLEEP_TIME ); # és újra várunk } } $íjász = Íjász -> új (); # a bátor íjász elveszi a nyilak tegezét $íjász -> shooting_start (); # ... és elkezd lőni = megjegyzésre A csomag leírja az íjász által használt tegez tulajdonságait (Archer), és amelyben a nyilakat tárolják (Arrow) = vágott csomagtegez { _ használja az Arrow ; # egy nyíl a tegezből használja a "say" funkciót ; szigorúan használd ; figyelmeztetések használata ; # -- ** konstruktor ** -- sub new { my ( $osztály , $nyilak_száma ) = ( shift , shift ); my $self = { nyilak => [] , # nyilak a tegezben (még nem, de hamarosan ott lesz) }; áldja meg $self , $class ; $self -> arrows_prepare ( $nyilak_száma ); # nyilak betöltése quiverbe return $self ; } # -- ** nyilak előkészítése a lövöldözéshez ** -- sub arrows_prepare { my ( $self , $nyilak_száma ) = ( shift , shift ); push @ { $self -> { arrows }}, Arrow -> new ( $_ ) for ( 0 .. $nyilak_száma - 1 ); # tedd a nyilakat a tegezbe } # -- ** pull arrow from quiver ** -- sub arrow_pull { my ( $self ) = ( shift ); foreach ( @ { $self -> { nyilak }}) { # minden nyílnál ellenőrizze, hogy benne van-e a tegezben if ( $_ -> check_state ()) { # és ha igen, akkor $_ -> pull (); # vedd ki onnan (és lődd le) utoljára ; # nem tudunk egyszerre két nyilat kilőni } } } # -- ** return arrow to quiver ** -- sub arrow_return { my ( $self ) = ( shift ); foreach ( @ { $self -> { nyilak }}) { # minden nyílnál ellenőrizze, hogy már el lett- e indítva if ( ! $_ -> check_state ()) { # ha nincs ilyen nyíl a tegezben $_ -> visszatérés ( ); # menj és vedd fel utoljára ; # elméletileg egy íjász egyszerre több nyilat is fel tud venni, de a szerző másként gondolja } } } } 1 ; = megjegyzésre A csomag egy íjász tegezében található egyetlen nyíl tulajdonságait írja le (Íjász) = vágott csomag Arrow { használja a "say" funkciót ; szigorúan használd ; figyelmeztetések használata ; # -- ** konstruktor ** -- sub new { my $class = shift ; my $self = { szám => shift , # arrow number state => 1 , # arrow state (1 = tegezben, 0 = fekvés lövés után) }; áldja meg $self , $class ; return $self ; } # -- ** nyíl eltávolítása a tegezből ** -- sub pull { my ( $self ) = ( shift ); $self -> { állapot } = 0 ; # módosítsa a nyíl állapotát "kibocsátva"-ra, mondd: "pulled $self->{number}" ; # jelentés arról, hogy a lövés megtörtént } # -- ** tedd vissza a nyilat a tegezbe ** -- sub return { my ( $self ) = ( shift ); $self -> { állapot } = 1 ; # módosítsa a nyíl állapotát "remegett"-re , mondd : "returned $self->{number}" ; # jelentés, hogy a nyíl visszatért az íjászhoz } # -- ** check arrow state ** -- sub check_state { my ( $self ) = ( shift ); return $self -> { állapot }; # visszaadja a nyíl állapotát (1 = remegett, 0 = elengedett) } } 1 ;

Linkek