Objektiallas
Kokeneet kirjoittajat eivät ole vielä tarkistaneet sivun nykyistä versiota, ja se voi poiketa merkittävästi 5. huhtikuuta 2022 tarkistetusta
versiosta . tarkastukset vaativat
4 muokkausta .
Objektivarasto on luova suunnittelumalli , joukko alustettuja ja käyttövalmiita objekteja. Kun järjestelmä tarvitsee objektin, sitä ei luoda, vaan se otetaan poolista. Kun esinettä ei enää tarvita, sitä ei tuhota, vaan se palautetaan altaaseen.
Sovellus
Objektien yhdistämistä käytetään suorituskyvyn parantamiseen, kun objektin luominen työn alussa ja sen tuhoaminen lopussa on kallista. Suorituskyvyn paraneminen on erityisen havaittavissa, kun esineitä luodaan ja tuhotaan usein, mutta niitä on olemassa vain pieni määrä samanaikaisesti.
Objektivarasto on hyödyllinen, kun objekti omistaa muita resursseja kuin muistia, kuten verkkopistokkeita. Tai jos objektikokoelma vie huomattavan osan tietokoneen muistista ja syntyy paljon " roskaa ".
Ylivuoto
Jos poolissa ei ole yhtään vapaata objektia, yksi kolmesta strategiasta on mahdollinen:
- Altaan laajennus.
- Kieltäytyminen esineen luomisesta, hätäpysäytys.
- Jos kyseessä on moniajojärjestelmä , voit odottaa, kunnes jokin objekteista vapautetaan.
Esimerkkejä
- Tietoja avoimista tiedostoista DOSissa .
- Tietoa näkyvistä esineistä monissa tietokonepeleissä ( Doom-moottori on hyvä esimerkki ). Nämä tiedot koskevat vain yhtä kehystä; kun kehys on tulostettu, luettelo tyhjenee.
- Kaikkien kartan kohteiden tallentamiseen tarkoitettu tietokonepeli voi tavanomaisten muistinvarausmekanismien sijaan luoda sellaisen kokoisen taulukon , että sen tiedetään riittävän kaikille objekteille, ja säilyttää vapaat solut linkitetyn listan muodossa. . Tämä muotoilu parantaa nopeutta, vähentää muistin pirstoutumista ja vähentää roskankeräimen kuormitusta (jos sellainen on).
Ansoja
- Kun esine on palautettu, sen on palattava jatkokäyttöön sopivaan tilaan. Jos objektit ovat altaaseen palaamisen jälkeen väärässä tai määrittelemättömässä tilassa, tällaista rakennetta kutsutaan objektivarastoksi .
- Esineiden uudelleenkäyttö voi myös johtaa tietovuotoon. Jos objekti sisältää salaisia tietoja (esimerkiksi luottokortin numeron ), objektin julkaisun jälkeen nämä tiedot on kirjoitettava päälle.
- Monisäikeistä objektipoolia ei ole helppo kirjoittaa.
- 2020-luvulle roskakorjauskielillä muistinhallinta on hyvin optimoitu jatkuvaa allokointia varten. Joten jos objekti vie vain muistia, Java-käsikirjat eivät suosittele poolien käyttöä: tavallinen newvaatii vain kymmenen prosessoriohjetta. Ja roskankerääjät skannaavat usein objektiviittauksia, eivät niiden muistia - koska mitä enemmän "eläviä" objekteja muistissa on, sitä heikompi tällaisen kerääjän suorituskyky on.
Toteutusesimerkki
Lähdekoodi Pythonissa
#koodaus: utf-8
"""
Kuvittele tilanne, jossa meillä on laiva, joka kestää useita laukauksia.
Shot-objektin luominen on kallista.
Siksi Shot-perheen esineitä luodaan kerran.
Ja eliniän jälkeen esine jää muisti.
"""
luokka Shot ( objekti ):
"""Entiteetti, joka voi selviytyä useista osumista"""
def __init__ ( self , lifetime = 5 ):
itse . elinikä = elinikä
def update ( itse ):
itse . käyttöikä = 1
palautus itse . käyttöikä > 0
class ObjectPool :
"""Objektivarasto"""
def __init__ ( self , ** kwargs ):
"""Luodaan poolia"""
itse . _clsname = kwargs [ 'luokan nimi' ]
self . _args = kwargs . saada ( 'args' , [])
itse . _num_objects = max ( kwargs [ 'num' ], 0 )
self . _pred = kwargs [ 'update_func' ]
self . _max_objects = kwargs . get ( 'max' , itse . _num_objects )
# Luo objektit
itse . _objs = [ soveltaa ( itse . _clsname , self . _args )
x alueella ( itse . _num_objects ) ] self . _ _end = len ( itse . _objs )
def _extend_list ( self , args ):
"""Lisää yksi paikka pooliin"""
self . _objs . append ( soveltaa ( itse . _clsname , args ))
itse . _objektien_määrä += 1
def add ( self , * args ):
"""Lisää yksi objekti pooliin"""
newend = self . _end + 1
# Jos maksimi saavutetaan, katkaise puhelin,
jos newend > self . _max_objects :
return Ei mitään
# Jos kaikki paikat on varattu, lisää yksi paikka lisää
if newend > len ( self . _objs ):
self . _extend_list ( args )
else :
self . _objs [ itse . _end ] . nollaa ( * args )
itse . _end += 1
palauttaa itsensä . _end - 1
def update ( self , * args ):
"""Päivitä kaikki poolin objektit"""
itse . _end = osio ( self . _pred , self . _objs , 0 , itse . _end , args )
palauttaa itsensä . _end
def update_object ( x ):
"""Päivitä objekti"""
palauttaa x . päivitys ()
def- osio ( pred , seq , ensimmäinen , viimeinen , * args ):
"""Objektilajittelutoiminto"""
if first > last :
return 0
i :lle alueella ( ensimmäinen , viimeinen ) :
jos ei pred ( seq [ i ]):
break
else :
palauta viimeinen
j :lle alueella ( i + 1 , viimeinen ) :
jos pred ( sek [ j ]):
sek [ i ], sek [ j ] = sek [ j ], sek [ i ]
i += 1
paluu i
# Itse asiassa pool
shots = ObjectPool ( luokan nimi = Shot , update_func = update_object , num = 5 ) käyttäminen laukausten aikana . päivitys (): pass
tulosta "Valmis!"
C++ esimerkki
Lähdeteksti C++:ssa
#sisällytä <vektori>
luokan objekti
{
// ...
};
luokan ObjectPool
{
yksityinen :
struct PoolRecord
{
objekti * ilmentymä ;
bool in_use ;
};
std :: vektori < PoolRecord > m_pool ;
julkinen :
Objekti * createNewObject ()
{
for ( koko_t i = 0 ; i < m_pool . koko (); ++ i )
{
if ( ! m_pool [ i ]. in_use )
{
m_pool [ i ]. in_use = tosi ; // siirtää objekti käytettyjen listaan return m_pool [ i ]. esimerkki ;
}
}
// jos emme löytäneet vapaata objektia, laajenna
PoolRecord- tietue ;
ennätys . esiintymä = uusi objekti ;
ennätys . in_use = tosi ;
m_pool . push_back ( ennätys );
paluu ennätys . esimerkki ;
}
void deleteObject ( Object * objekti )
{
// todellisuudessa emme poista, vaan merkitsemme vain, että objekti on vapaa
( koko_t i = 0 ; i < m_pool . size ( ); ++ i )
{
if ( m_pool [ i ]. ilmentymä == objekti )
{
m_pool [ i ]. in_use = false ;
tauko ;
}
}
}
virtuaalinen ~ ObjectPool ()
{
// nyt "todella" poistamme objektit
kohteelle ( koko_t i = 0 ; i < m_pool . size (); ++ i )
poista m_pool [ i ]. esimerkki ;
}
};
int main ()
{
Objektiallas ; _
for ( koko_t i = 0 ; i < 1000 ; ++ i )
{
Objekti * objekti = pooli . CreateNewObject ();
// ...
allas . deleteObject ( objekti );
}
paluu 0 ;
}
Mallit ja lankasuojat on poistettu esimerkistä yksinkertaisuuden vuoksi . Jos haluat käyttää poolia useissa säikeissä, sinun tulee suojata createNewObject- ja deleteObject-menetelmien runko jonkin sopivan synkronointiobjektin, kuten kriittisen osan tai mutexin , samanaikaiselta suorittamiselta .
Lähdeteksti C#
nimitila Digital_Patterns.Creational.Object_Pool.Soft
{
/// <summary>
/// Käyttöliittymä "Object Pool" -mallin käyttämiseen <katso cref="Object_Pool"/>
/// </summary>
/// <typeparam name= " T"></typeparam>
julkinen käyttöliittymä ICreation < T >
{
/// <summary>
/// Palauttaa juuri luodun objektin
/// </summary>
/// <returns></returns>
T Luo () ;
}
}
Lähdeteksti C#
käyttäen System ;
käyttämällä System.Collections -ohjelmaa ;
käyttäen System.Threading ;
nimiavaruus Digital_Patterns.Creational.Object_Pool.Soft
{
/// <summary>
/// Objektivarannon toteuttaminen pehmeillä viittauksilla
/// </summary>
/// <typeparam name="T"></typeparam>
julkinen luokka ObjectPool < T > missä T : luokka
{
/// <summary>
/// Synkronointiobjekti
/// </summary>
yksityinen semafori semafori ;
/// <summary>
/// Kokoelma sisältää hallittuja objekteja
/// </summary>
yksityinen ArrayList pool ;
/// <summary>
/// Viittaus objektiin, jolle on delegoitu vastuu
/// poolin objektien luomisesta
/// </summary>
yksityinen ICreation < T > creator ;
/// <summary>
/// Olemassa olevien objektien määrä
/// </summary>
private Int32 instanceCount ;
/// <summary>
/// Poolin hallitsemien objektien enimmäismäärä
/// </summary>
yksityinen Int32 maxInstances ;
/// <summary>
/// Objektivarannon luominen
/// </summary>
/// <param name="creator">Objekti, jolle pooli siirtää vastuun
/// hallinnoimiensa objektien luomisesta< /param>
public ObjectPool ( ICreation < T > luoja )
: this ( luoja , Int32 . MaxValue )
{
}
/// <summary>
/// Objektivarannon luominen
/// </summary>
/// <param name="creator">Objekti, jolle pooli siirtää vastuun
/// hallinnoimiensa objektien luomisesta< /param>
/ // <param name="maxInstances">Luokkien enimmäismäärä
/// jonka pooli sallii olla olemassa samanaikaisesti
/// </param>
public ObjectPool ( ICreation < T > creator , Int32 maxInstances )
{
this . luoja = luoja ;
tämä . instanssimäärä = 0 ;
tämä . maxInstances = maxInstances ;
tämä . pool = uusi ArrayList ();
tämä . semafori = uusi Semafori ( 0 , tämä . maxInstances );
}
/// <yhteenveto>
/// Palauttaa uudelleenkäyttöä odottavien objektien lukumäärän poolissa
. Todellinen luku
/// voi olla pienempi kuin tämä arvo, koska
/// palautettu arvo on poolissa olevien pehmeiden viittausten määrä.
/// </summary>
public Int32 Size
{
get
{
lock ( pool )
{
return pool . laskea ;
}
}
}
/// <summary> /// Palauttaa
tällä hetkellä olemassa olevien poolattujen objektien määrän ///
/// </summary> public Int32 InstanceCount { get { return instanceCount ; } }
/// <yhteenveto>
/// Hae tai aseta enimmäismäärä
/// hallittuja objekteja, jotka pooli sallii olla olemassa samanaikaisesti.
/// </summary>
public Int32 MaxInstances
{
get { return maxInstances ; }
set { maxInstances = arvo ; }
}
/// <yhteenveto>
/// Palauttaa objektin poolista. Tyhjällä poolilla
/// objekti luodaan, jos
poolin hallitsemien objektien /// määrä ei ole suurempi tai yhtä suuri kuin
<katso cref="ObjectPool{T}" palauttama arvo ///. MaxInstances"/> -menetelmä. Jos poolin hallitsemien objektien määrä ///
ylittää tämän arvon, tämä menetelmä palauttaa null
/// </summary>
/// <returns></returns>
public T GetObject ()
{
lock ( pool )
{
T thisObject = PoistaObject ( );
if ( thisObject != null )
return thisObject ;
if ( InstanceCount < MaxInstances )
return CreateObject ();
palauttaa null ;
}
}
/// <yhteenveto>
/// Palauttaa objektin poolista. Tyhjällä poolilla
/// objekti luodaan, jos
poolin hallitsemien objektien /// määrä ei ole suurempi tai yhtä suuri kuin
<katso cref="ObjectPool{T}" palauttama arvo ///. MaxInstances"/> -menetelmä. Jos poolin hallitsemien objektien /// määrä
ylittää tämän arvon, tämä menetelmä odottaa kunnes
/// kunnes jokin objekti tulee saataville
/// uudelleenkäyttöön.
/// </summary>
/// <returns></returns>
public T WaitForObject ()
{
lock ( pool )
{
T thisObject = RemoveObject ();
if ( thisObject != null )
return thisObject ;
if ( InstanceCount < MaxInstances )
return CreateObject ();
}
semafori . odottaja ();
return WaitForObject ();
}
/// <summary>
/// Poistaa objektin poolikokoelmasta ja palauttaa sen
/// </summary>
/// <returns></returns>
yksityinen T PoistaObject ()
{
while ( pool . Count > 0 )
{
var refThis = ( WeakReference ) pool [ pool . Count - 1 ];
allas . RemoveAt ( pool . Count - 1 );
var thisObject = ( T ) refThis . Kohde ;
if ( thisObject != null )
return thisObject ;
instanceCount --;
}
return null ;
}
/// <summary>
/// Luo tämän poolin hallinnoima objekti
/// </summary>
/// <returns></returns>
yksityinen T CreateObject ()
{
T newObject = luoja . luo ();
instanceCount ++;
return newObject ;
}
/// <summary>
/// Vapauttaa objektin ja sijoittaa sen pooliin
/// uudelleenkäyttöä varten
/// </summary>
/// <param name="obj"></param>
/// <poikkeus cref ="NullReferenceException"></exception>
public void Release ( T obj )
{
if ( obj == null )
throw new NullReferenceException ();
lukko ( pool )
{
var refThis = new WeakReference ( obj );
allas . Lisää ( refThis );
semafori . vapauttaa ();
}
}
}
}
Lähdeteksti C#
nimiavaruus Digital_Patterns.Creational.Object_Pool.Soft
{
julkinen luokka Uudelleenkäytettävä
{
julkinen objekti [] Objs { get ; suojattu sarja ; }
public Uudelleenkäytettävä ( params Object [ ] objs )
{
this . Objs = objs ;
}
}
public class Luoja : ICreation < Uudelleen käytettävä >
{
yksityinen staattinen Int32 iD = 0 ;
public Uudelleen käytettävä Luo ()
{
++ iD ;
palauta uusi Uudelleen käytettävä ( iD );
}
}
public class ReusablePool : ObjectPool < Uudelleenkäytettävä >
{
public ReusablePool ()
: base ( new Creator (), 2 )
{
}
}
}
Lähdeteksti C#
käyttäen System ;
käyttäen System.Threading ;
käyttäen Digital_Patterns.Creational.Object_Pool.Soft ;
nimiavaruus Digital_Patterns
{
luokka Ohjelma
{
static void Main ( merkkijono [ ] args )
{
Konsoli . WriteLine ( System . Reflection . MethodInfo . GetCurrentMethod ( . Nimi );
var reusablePool = uusi ReusablePool ();
var thrd1 = uusi säie ( Suorita );
var thrd2 = uusi säie ( Suorita );
var thisObject1 = reusablePool . GetObject ();
var thisObject2 = reusablePool . GetObject ();
kolmas 1 . Käynnistä ( reusablePool );
kolmas 2 . Käynnistä ( reusablePool );
ViewObject ( thisObject1 );
ViewObject ( thisObject2 );
lanka . Sleep ( 2000 );
uudelleenkäytettävä allas . Vapauta ( thisObject1 );
lanka . Sleep ( 2000 );
uudelleenkäytettävä allas . Vapauta ( thisObject2 );
konsoli . ReadKey ();
}
yksityinen static void Suorita ( Objektiobjekti ) { Konsoli . _ WriteLine ( "\t" + System . Reflection . MethodInfo . GetCurrentMethod (). Nimi ); var reusablePool = ( ReusablePool ) obj ; konsoli . WriteLine ( "\tstart odottaa" ); var thisObject1 = reusablePool . WaitForObject (); ViewObject ( thisObject1 ); konsoli . WriteLine ( "\tend wait" ); uudelleenkäytettävä allas . Vapauta ( thisObject1 ); }
yksityinen static void ViewObject ( Uudelleen käytettävä thisObject )
{
foreach ( var obj in thisObject . Objs )
{
Console . Kirjoita ( obj . ToString () + @" " );
}
Konsoli . writeLine ();
}
}
}
Lähdeteksti VB.NET-kielellä
Nimiavaruus Digital_Patterns.Creational.Object_Pool.Soft
' Käyttöliittymä "Object Pool" -mallin käyttöön <katso cref="Object_Pool"/>
Julkinen käyttöliittymä ICreation ( Of T )
' Palauttaa juuri luodun objektin
Function Create () As T
End Interface
lopeta nimiavaruus
Lähdeteksti VB.NET-kielellä
Nimiavaruus Digital_Patterns.Creational.Object_Pool.Soft
"Objektivarannon toteutus pehmeillä viittauksilla
Public Class ObjectPool ( Of T As Class )
' Synkronoi objekti Yksityinen semafori Semaforina
Kokoelma sisältää hallittuja objekteja
Yksityinen pooli ArrayList - muodossa
Viittaus objektiin, jolle on delegoitu vastuu poolin
Private Creator As ICreation ( Of T ) objektien luomisesta
'Tällä hetkellä olemassa olevien objektien lukumäärä
Yksityinen m_instanceCount As Int32
Poolattujen objektien enimmäismäärä
Yksityinen m_maxInstances As Int32
'Object Pool Creation
' -luoja on objekti, jolle pooli siirtää vastuun hallinnoimiensa objektien luomisesta
Public Sub New ( ByVal creator As ICreation ( Of T ))
Me . Uusi ( luoja , Int32 . MaxValue )
End Sub
Kohdevarannon luonti
-objekti, jolle pooli siirtää vastuun hallinnoimiensa objektien luomisesta
. maxInstances - Luokan esiintymien enimmäismäärä, jonka pooli sallii olla olemassa samanaikaisesti
Public Sub New ( ByVal luoja Kuten ICreation ( Of T ), ByVal maxInstances As Int32 )
me . luoja = luoja
minä . m_instanceCount = 0
Me . m_maxInstances = maxInstances
Me . pool = Uusi ArrayList ()
Minä . semafori = Uusi semafori ( 0 , minä . m_maxInstances )
End Sub
'Palauttaa uudelleenkäyttöä odottavien kohteiden määrän poolissa
. Todellinen luku voi olla pienempi kuin
tämä arvo, koska palautettu arvo
on joukossa olevien pehmeiden viittausten määrä.
Julkinen vain luku -omaisuuden koko ( ) Int32 :na
Hanki
SyncLock - varasto Return pool
. Count End SyncLock End Hanki loppuominaisuus _
'Palauttaa tällä hetkellä olemassa
olevien poolattujen objektien määrän. Julkinen vain luku -ominaisuus InstanceCount () Kuten Int32 Get Return m_instanceCount End Get End Property
"Hanki tai aseta poolin hallinnoimien "objektien enimmäismäärä
, jonka pooli sallii olla olemassa kerrallaan.
Julkisen omaisuuden enimmäisinstanssit () Int32 : na Hae palautus m_maxInstances End Get Set ( ByVal arvo Int32 : na ) m_maxInstances = arvo Loppujoukko Lopetusominaisuus
'Palauttaa kohteen altaalta. Tyhjä pooli luo
objektin, jos poolin hallitsemien objektien määrä ei ole
suurempi tai yhtä suuri kuin ObjectPool{T}.MaxInstances-metodin palauttama arvo.
' Jos poolattujen objektien määrä ylittää tämän arvon, tämä
'menetelmä palauttaa nollan
Public Function GetObject () As T
SyncLock pool
Dim thisObject muodossa T = RemoveObject ( ) If thisObject IsNothing then Return thisObject End If
If InstanceCount < MaxInstances Then
Return CreateObject ()
End If
Return Nothing
End SyncLock
lopetustoiminto _
' Palauttaa kohteen altaalta. Tyhjä pooli luo
"objektin, jos poolattujen objektien määrä
" ei ole suurempi tai yhtä suuri kuin ObjectPool{T}-menetelmän palauttama arvo. MaxInstances-metodi
' Jos poolattujen objektien määrä ylittää tämän arvon,
' tämä menetelmä odottaa kunnes esinettä
ei anneta uudelleen käytettäväksi.
Julkinen toiminto WaitForObject () As T
SyncLock pool
Himmeä tämä Object muodossa T = PoistaObject ( ) Jos tämä objekti ei ole mitään , palauta tämäObjekti Lopeta jos
If InstanceCount < MaxInstances Then
Return CreateObject ()
End If
End SyncLock
semafori . WaitOne ()
Return WaitForObject ()
Lopeta funktio
' Poistaa objektin poolikokoelmasta ja palauttaa sen
Yksityinen toiminto RemoveObject () As T
While pool . Count > 0
Dim refThis = DirectCast ( pool ( pool . Count - 1 ), WeakReference )
pool . RemoveAt ( pool . Count - 1 )
Himmeä tämäObject = DirectCast ( refThis . Target , T )
Jos tämä objekti ei ole mitään , sitten
palauta tämäObject
End If
m_instanceCount - = 1
End While
Return Nothing
Lopetustoiminto
' Luo tämän poolin hallitsema objekti
Yksityinen toiminto CreateObject ( ) As T
Dim newObject As T = luoja . Luo ()
m_instanceCount += 1
Palauta newObject
End Function
' Vapauttaa objektin ja sijoittaa sen pooliin uudelleenkäyttöä varten Julkinen alijulkaisu ( ByVal obj As T ) Jos obj ei ole mitään , sitten Heitä uusi NullReferenceException () End If SyncLock pool Dim refThis = Uusi WeakReference ( obj ) pool . Lisää ( refThis ) semafori . Vapauta () End SyncLock End Sub End Class End Namespace
Lähdeteksti VB.NET-kielellä
Nimiavaruus Digital_Patterns.Creational.Object_Pool.Soft
'### Luokka Uudelleenkäytettävä ####
Julkinen luokka Uudelleenkäytettävä
Yksityinen m_Objs Objektina ( )
Julkinen Sub Uusi ( ByVal ParamArray objs Objektina () ) Minä . Objs = objs End Sub
Julkinen omaisuus Objs () Objektina ( ) Hae Palautus m_Objs End Get
Suojattu joukko ( ByVal arvo Objektina ( ) ) m_Objs = arvo Lopetusjoukko End Property End Class
"### Class Creator
#### Public Class Creator
toteuttaa ICreationin ( uudelleenkäytettävän )
Yksityinen jaettu tunnus Int32 = 0 _
Julkinen toiminto Luo ( ) uudelleenkäytettävinä toteuttaa ICreationin ( uudelleenkäytettävien ) . Luo iD += 1 Palauta uusi uudelleenkäytettävä ( iD ) End Function End Class
'### ReusablePool-luokka
#### Julkinen luokka ReusablePool
perii ObjectPool ( uudelleenkäytettävän )
Julkinen Sub Uusi ()
MyBase . Uusi ( Uusi luoja (), 2 )
End Sub
End Class
End Namespace
Lähdeteksti VB.NET-kielellä
Tuo System.Threading
Imports Digital_Patterns.Creational.Object_Pool.Soft
Namespace Digital_Patterns
Class Program
Jaettu Sub- pääkonsoli (
) . WriteLine ( System . Reflection . MethodInfo . GetCurrentMethod ( . Nimi )
Dim reusablePool = Uusi Uudelleenkäytettävä Pool ( )
Dim thrd1 = Uusi säie ( AddressOf Run )
Dim thrd2 = Uusi säie ( AddressOf Run )
Dim thisObject1 = reusablePool . GetObject ()
Dim thisObject2 = reusablePool . GetObject ()
kolmas 1 . Käynnistä ( reusablePool )
thrd2 . Aloita ( reusable Pool )
ViewObject ( thisObject1 )
ViewObject ( thisObject2 )
lanka . Sleep ( 2000 )
reusablePool . Vapauta ( thisObject1 )
lanka . Sleep ( 2000 )
reusablePool . Vapauta ( thisObject2 )
konsoli . ReadKey ()
End Sub
Yksityinen Jaettu Sub Run ( ByVal obj As [ Object ] ) -
konsoli . WriteLine ( vbTab & System . Reflection . MethodInfo . GetCurrentMethod (. Nimi )
Dim reusablePool = DirectCast ( obj , ReusablePool )
konsoli . WriteLine ( vbTab & "aloitus odotus" )
Dim thisObject1 = reusablePool . WaitForObject ()
ViewObject ( thisObject1 ) -
konsoli . WriteLine ( vbTab & "end wait" )
reusablePool . Release ( thisObject1 )
End Sub
Yksityinen Jaettu Sub ViewObject ( ByVal thisObject uudelleenkäytettävänä ) Jokaiselle objektille Objektina tässä objektissa . _ _ _ Objs- konsoli . Kirjoita ( obj . ToString ( ) & " " ) Seuraava konsoli . WriteLine () End Sub End Class End Namespace
Perl esimerkki
Lähdeteksti Perlissä
#!/usr/bin/perl -w
=kommenttia varten
ObjectPool-moduuli toteuttaa "objektipoolin" ohjelmointimallin simuloimalla
jousiampujan käyttäytymistä, jolla on rajoitettu määrä nuolia nuolia nuolissaan, minkä seurauksena
hänen on ajoittain poimittava niitä.
Paketti kuvaa jousimiehen käyttäytymistä
= leikattu
paketti jousimies {
käytä Quiveria ; #vire jousiampujan nuolilla
käytä tiukkaa ;
käytä varoituksia ;
käytä vakiota ARROWS_NUMBER => 5 ; # nuolien määrä värinä
käyttää vakiota SLEEP_TIME => 3 ; # enimmäistauko kahden toiminnon välillä (sekunneissa)
# -- ** rakentaja ** --
sub new {
minun $luokka = shift ;
minun $self = {
quiver => Quiver -> new ( ARROWS_NUMBER ), # objekti luokan "Quiver"
};
siunaa $itse , $luokka ;
palauttaa $self ;
}
# -- ** kuvauksen alustus ** --
sub shooting_start {
my ( $self ) = ( shift );
while ( 1 ) { # ehdollisesti ääretön silmukka, joka ampuu
$self -> shoot () for ( 0 .. rand ( ARROWS_NUMBER - 1 )); # satunnainen määrä laukauksia
$itse -> lataa uudelleen () for ( 0 .. rand ( ARROWS_NUMBER - 1 )); # satunnainen määrä laukaistettujen nuolien palautusta
}
}
# -- ** shot ** --
sub shoot {
my ( $itse ) = ( shift );
$self -> { quiver } -> arrow_pull (); # lähetä nuoli helvettiin
nukkumaan rand ( SLEEP_TIME ); # ... ja odota loputtomasti
}
# -- ** palauta laukaistu nuoli ** --
sub reload {
my ( $self ) = ( shift );
$self -> { quiver } -> arrow_return (); # palauttaa aiemmin laukaistun nuolen
uni - randin ( SLEEP_TIME ); # ja taas odotamme
}
}
$jousimies = Jousimies - > uusi (); # rohkea jousiampuja ottaa nuolivilisensä $jousimies -> shooting_start (); # ... ja alkaa ampua
=kommenttia varten
Paketti kuvaa jousimiehen käyttämän nuolen ominaisuudet (Archer) ja johon nuolet on tallennettu (Arrow)
= leikattu
pakettivire { _
käytä Arrow ; # yksi nuoli nuolesta
käytä ominaisuutta "sano" ;
käytä tiukkaa ;
käytä varoituksia ;
# -- ** rakentaja ** --
sub new {
oma ( $luokka , $nuolien_numero ) = ( shift , shift );
minun $self = {
nuolet => [] , # nuolta värinä (ei vielä, mutta tulee pian)
};
siunaa $itse , $luokka ;
$self -> arrows_prepare ( $nuolien_numero ); # lataa nuolet quiveriin
return $self ;
}
# -- ** valmistele nuolet ampumista varten ** --
sub arrows_prepare {
my ( $itse , $nuolien_numero ) = ( shift , shift );
push @ { $self -> { arrows }}, Arrow -> new ( $_ ) for ( 0 .. $nuolien_numero - 1 ); # laita nuolet nuoliin
}
# -- ** vedä nuoli värinästä ** --
alanuoli_veto { oma
( $ itse ) = ( vaihto );
foreach ( @ { $self -> { arrows }}) { # jokaisen nuolen kohdalla tarkista, onko se värinä
if ( $_ -> check_state ()) { # ja jos kyllä
$_ -> vedä (); # ota se pois sieltä (ja ammu)
viimeisenä ; # emme voi laukaista kahta nuolta yhtä aikaa
}
}
}
# -- ** paluunuoli värinä ** --
alanuoli_paluu { oma ( $ itse ) = ( vaihto ); foreach ( @ { $self -> { arrows }}) { # jokaisen nuolen kohdalla tarkista, onko se jo laukaistu if ( ! $_ -> check_state ()) { # jos nuolta ei ole nuolivireessä $_ -> palauta ( ); # mene ja nouda se viimeisenä ; # teoriassa jousiampuja voi poimia useamman kuin yhden nuolen kerrallaan, mutta kirjoittaja ajattelee toisin } } } }
1 ;
=kommenttia varten
Paketti kuvaa jousiampujan nuolesta löytyvän nuolen ominaisuuksia (Archer)
= leikattu
paketti Arrow {
käytä ominaisuutta "sano" ;
käytä tiukkaa ;
käytä varoituksia ;
# -- ** rakentaja ** --
sub new {
minun $luokka = shift ;
$itseni = { numero = > vaihto , # nuolen numerotila => 1 , # nuolen tila (1 = värinä, 0 = makaa laukauksen jälkeen) } ; siunaa $itse , $luokka ; palauttaa $self ; }
# -- ** poista nuoli nuolinäppäimestä ** --
sub pull {
my ( $self ) = ( shift );
$itse -> { tila } = 0 ; # muuta nuolen tilaksi "vapautettu"
sano "vedetty $self->{number}" ; # raportoi, että laukaus tapahtui
}
# -- ** laita nuoli takaisin nuoliin ** --
sub return {
my ( $self ) = ( shift );
$itse -> { tila } = 1 ; # muuta nuolen tilaksi "väritetty"
sano "palautti $self->{number}" ; # raportoi, että nuoli on palannut jousiampujaan
}
# -- ** tarkista nuolen tila ** --
alitarkistustila { oma ( $itse ) = ( shift ) ; return $self -> { tila }; # palauttaa nuolen tilan (1 = vapina, 0 = vapautettu) } }
1 ;
Linkit