Guardian (tervezési minta)

Az őrző
Emlékeztető
Típusú viselkedési
Leírása: Tervezési minták Igen

A Keeper ( eng.  Memento ) egy viselkedési tervezési minta , amely lehetővé teszi egy objektum belső állapotának rögzítését és mentését a tokozás megsértése nélkül , hogy később vissza lehessen állítani ebbe az állapotba.

Ennek a mintának két lehetséges megvalósítása van: a klasszikus, amelyet a Design Patterns című könyvben ismertet , és a kevésbé elterjedt, nem szabványos változat.

Alkalmazás

A Guardian mintát akkor használják, ha:

Szerkezet

Klasszikus változat:

Nem szabványos opció:

Leírás

Klasszikus változat: A Guardian mintát két objektum használja: "Creator" (kezdeményező) és "Guardian" (gondozó). Az „alkotó” olyan tárgy, amelynek belső állapota van. A "Guardian" objektum végrehajthat bizonyos műveleteket a "Creator"-val, de ugyanakkor szükséges a változtatások visszaállítása. Ehhez a Guardian kéri a Guardian objektumot a Teremtőtől. Ezután végrehajtja a tervezett műveletet (vagy műveletsort). A "Creator" visszaállításához a változtatásokat megelőző állapotba, a "Guardian" visszaadja a "Keeper" objektumot a "Creator"-nak. A "Guardian" átlátszatlan (azaz olyan, amelyet az "Guardian" nem tud vagy nem szabad megváltoztatnia).

Nem szabványos változat: Ennek a változatnak a különbsége a klasszikustól abban rejlik, hogy az „Őrző” hozzáférését a „Teremtő” belső állapotához szigorúbban korlátozza. A klasszikus változatban a "Guardian" képes hozzáférni a "Creator" belső adataihoz a "Keeper"-en keresztül, megváltoztatni az állapotot és visszaállítani a "Creator"-ra. Ebben a verzióban a "Guardian" csak a "Guardian" állapotának visszaállítására képes a Restore hívásával. Többek között az „Guardian”-nak nem kell kapcsolatot létesítenie a „Gárdával” ahhoz, hogy helyreállítsa állapotát. Ez lehetővé teszi az összetett hierarchikus vagy hálózati struktúrák állapotának (az objektumok és a köztük lévő összes kapcsolat állapotának) mentését és visszaállítását a rendszerben lévő összes regisztrált objektum pillanatképeinek összegyűjtésével.

Megvalósítási példák

A szabványos Java sablon

Java forrás public class Memento { private final String state ; public Memento ( Karakterlánc állapota ) { this . állapot = állapot ; } public String getState () { return állapot ; } } public class Gondnok { private Memento memento ; public Memento getMemento () { return memento ; } public void setMemento ( Memento memento ) { this . memento = memento ; } } public class Kezdeményező { private String állapota ; public void setState ( String state ) { this . állapot = állapot ; } public String getState () { return állapot ; } public Memento saveState () { return new Memento ( állapot ); } public void restoreState ( Memento memento ) { this . állapot = memória . getstate (); } } public class Alkalmazás { public static void main ( String [] args ) { Eredeti szerző = new Kezdeményező (); Gondnok gondnok = új Gondnok (); kezdeményező . setState ( "on" ); Rendszer . ki . printf ( "Az állapot %s\n" , kezdeményező . getState ()); gondnok . setMemento ( originator.saveState ( ) ); kezdeményező . setState ( "off" ); Rendszer . ki . printf ( "Az állapot %s\n" , kezdeményező . getState ()); kezdeményező . restoreState ( caretaker.getMemento ( ) ); Rendszer . ki . printf ( "Az állapot %s\n" , kezdeményező . getState ()); } } /* * Kimenet: * Állapot be van kapcsolva * Állapot ki van kapcsolva * Állapot be van kapcsolva */

PHP5 alapértelmezett sablon

PHP5 forráskód <?php /** * A Keeper minta tárolja és visszaállítja az objektumállapotokat */ névtér Memento { /** * A Creator elmenti és visszaállítja a belső állapotot */ class Originator { privát $állam ; public function setState ( $állapot ) { $this -> state = $state ; echo sprintf ( "Állapotkészlet %s \n " , $this -> állapot ); } public function getState () { return $this -> state ; } /** * Pillanatkép készítése az objektum állapotáról * @return Memento */ public function saveMemento () { return new Memento ( $this -> state ); } /** * Állapot visszaállítása * @param \Memento\Memento $memento */ public function restoreMemento ( Memento $memento ) { echo sprintf ( "Állapot visszaállítása... \n " ); $this -> state = $memento -> getState (); } } /** * Állapot pillanatfelvétel */ class Memento { privát $állam ; public function __construct ( $állapot ) { $this -> state = $állapot ; } public function getState () { return $this -> state ; } } /** * Az objektum állapotának gondozója */ class Gondnok { privát $memento ; public function getMemento () { return $this -> memento ; } public function setMemento ( Memento $memento ) { $this -> memento = $memento ; } } $kezdeményező = új Kezdeményező (); $originator -> setState ( "Be" ); // Tárolás belső állapota $gondnok = new Gondnok (); $gondozó -> setMemento ( $ eredető -> saveMemento ()); // Kezdő módosításának folytatása $originator -> setState ( "Off" ); // Mentett állapot visszaállítása $originator -> restoreMemento ( $ caretaker -> getMemento ()); }

A C# sablon első verziója

Forrásszöveg C# nyelven //Ez a szerkezeti kód bemutatja a Memento mintát, amely ideiglenesen elmenti és visszaállítja egy másik objektum belső állapotát. // Memento minta -- Szerkezeti példa a rendszer használatával ; névtér DoFactory.GangOfFour.Memento.Structural { /// <summary> /// MainApp indítási osztály a Structural számára /// Memento Design Pattern. /// </summary> class MainApp { /// <summary> /// Belépési pont a konzolalkalmazásba. /// </summary> static void () { Kezdeményező o = new Kezdeményező (); o . Állapot = "Be" ; // Tárolás belső állapota Gondnok c = new Gondnok (); c . Memento = o . CreateMemento (); // A kezdeményező o módosításának folytatása . Állapot = "Ki" ; // Mentett állapot visszaállítása o . SetMemento ( c . Memento ); // Várja meg a felhasználói konzolt . ReadKey (); } } /// <summary> /// Az 'Originator' class /// </summary> class Eredeti { private string _state ; // Property public string Állapot { get { return _state ; } set { _state = érték ; Konzol . WriteLine ( "Állapot = " + _állapot ); } } // Memento létrehozása public Memento CreateMemento () { return ( new Memento ( _state )); } // Visszaállítja az eredeti állapotot public void SetMemento ( Memento memento ) { Console . WriteLine ( "Állapot visszaállítása..." ); állapot = mementó . állam ; } } /// <summary> /// A 'Memento' osztály /// </summary> class Memento { private string _state ; // Konstruktor public Memento ( string state ) { this . _state = állapot ; } // Állapot lekér vagy beállít public string Állapot { get { return _state ; } } } /// <summary> /// A 'Gondozó' osztály /// </summary> class Gondnok { private Memento _memento ; // Lekéri vagy beállítja a memento public Memento Memento { set { _memento = value ; } get { return _memento ; } } } } Kimeneti állapot = Be Állapot = Ki Állapot visszaállítása : Állapot = Be


C#

Forrásszöveg C# nyelven a rendszer használatával ; névtér MementoPatte { class Program { static void Main ( string [] args ) { Foo foo = new Foo ( "Teszt" , 15 ); . nyomtat (); Gondnok ct1 = új Gondnok (); Gondnok ct2 = új Gondnok (); ct1 . SaveState ( foo ); . IntProperty += 152 ; . nyomtat (); ct2 . SaveState ( foo ); ct1 . RestoreState ( foo ); . nyomtat (); ct2 . RestoreState ( foo ); . nyomtat (); Konzol . ReadKey (); } } nyilvános felület IOriginator { object GetMemento (); void SetMemento ( objektum mementó ); } public class Foo : IOriginator { public string StringProperty { get ; magánkészlet ; _ } public int IntProperty { get ; készlet ; } public Foo ( string stringPropertyValue , int intPropertyValue = 0 ) { StringProperty = stringPropertyValue ; IntProperty = intPropertyValue ; } public void Nyomtatás () { Konzol . WriteLine ( "==============" ); Konzol . WriteLine ( "StringProperty érték: {0}" , StringProperty ); Konzol . WriteLine ( "IntProperty érték: {0}" , IntProperty ); Konzol . WriteLine ( "==============" ); } objektum IOriginator . GetMemento () { return new Memento { StringProperty = this . StringProperty , IntProperty = ez . IntProperty }; } érvénytelen IOriginator . SetMemento ( object memento ) { if ( Object . ReferenceEquals ( memento , null )) throw new ArgumentNullException ( "memento" ); if (!( memento is Memento )) throw new ArgumentException ( "memento" ); StringProperty = (( Memento ) memento ). StringProperty ; IntProperty = (( Memento ) memento ). IntProperty ; } class Memento { public string StringProperty { get ; készlet ; } public int IntProperty { get ; készlet ; } } } public class Gondnok { private object m_memento ; public void SaveState ( IOriginator originator ) { if ( originator == null ) throw new ArgumentNullException ( "eredető" ); m_memento = kezdeményező . GetMemento (); } public void RestoreState ( IOriginator originator ) { if ( originator == null ) throw new ArgumentNullException ( "eredeti" ); if ( m_memento == null ) throw new InvalidOperationException ( "m_memento == null" ); kezdeményező . SetMemento ( m_memento ); } } }

Egyéni sablon

Forrásszöveg C# nyelven a rendszer használatával ; a System.Collections.Generic használatával ; nyilvános felület IOriginator { IMemento GetState (); } nyilvános interfész IShape : IOriginator { void Draw (); voidScale ( doublescale ) ; _ void Move ( double dx , double dy ); } nyilvános felület IMemento { void RestoreState (); } public class CircleOriginator : IShape { private class CircleMemento : IMemento { privát , csak olvasható double x ; privát csak olvasható double y ; privát csak olvasható double r ; privát , csak olvasható CircleOriginator kezdeményező ; public CircleMemento ( CircleOriginator kezdeményezője ) { this . kezdeményező = kezdeményező ; x = kezdeményező . x ; y = kezdeményező . y ; r = kezdeményező . r ; } public void RestoreState () { kezdeményező . x = x ; kezdeményező . y = y_ _ kezdeményező . r = r ; } } dupla x ; dupla y ; kettős r ; public CircleOriginator ( double x , double y , double r ) { this . x = x ; ezt . y = y_ _ ezt . r = r ; } public void Draw () { Konzol . WriteLine ( "{0} sugarú kör a ({1}, {2}) pontnál" , r , x , y ); } public void Skála ( kettős skála ) { r *= skála ; } public void Mozgatás ( dupla dx , dupla dy ) { x += dx ; y += dy ; } public IMemento GetState () { return new CircleMemento ( this ); } } public class RectOriginator : IShape { private class RectMemento : IMemento { privát csak olvasható double x ; privát csak olvasható double y ; privát csak olvasható double w ; privát csak olvasható double h ; privát , csak olvasható RetOriginator kezdeményező ; public RectMemento ( RectOriginator kezdeményezője ) { this . kezdeményező = kezdeményező ; x = kezdeményező . x ; y = kezdeményező . y ; w = kezdeményező . w _ h = kezdeményező . h _ } public void RestoreState () { kezdeményező . x = x ; kezdeményező . y = y_ _ kezdeményező . w = w _ kezdeményező . h = h ; } } dupla x ; dupla y ; dupla w ; dupla h ; public RectOriginator ( double x , double y , double w , double h ) { this . x = x ; ezt . y = y_ _ ezt . w = w _ ezt . h = h ; } public void Draw () { Konzol . WriteLine ( "Téglalap {0}x{1} at ({2}, {3})" , w , h , x , y ); } public void Skála ( kettős skála ) { w *= skála ; h *= skála ; } public void Mozgatás ( dupla dx , dupla dy ) { x += dx ; y += dy ; } public IMemento GetState () { return new RectMemento ( this ); } } public class Gondnok { public static void Rajzol ( IEnumerable < IShape > alakzatok ) { foreach ( ISforma alakzatokban ) { alakzat . _ _ húzni (); } } public static void MoveAndScale ( IEnumerable < IShape > alakzatok ) { foreach ( IShape alakzat alakzatokban ) { alakzat . _ skála ( 10 ); forma . Mozgás ( 3 , 2 ); } } public static IEnumerable < IMemento > SaveStates ( IEnumerable < IShape > alakzatok ) { LinkedList < IMemento > states = new LinkedList < IMemento >(); foreach ( IShape alakzat az alakzatokban ) { states . AddLast ( shape.GetState ( ) ); } visszatérési állapotok ; } public static void RestoreStates ( IEnumerable < IMemento > állapotok ) { foreach ( IMemento állapota állapotokban ) { state . _ RestoreState (); } } public static void Main () { IShape [] alakzatok = { new RectOriginator ( 10 , 20 , 3 , 5 ), new CircleOriginator ( 5 , 2 , 10 ) }; //Kimenetek: // Téglalap 3x5 at (10, 20) // Kör 10 sugarú pontban (5, 2) Rajzolj ( alakzatok ); //Alakzatok állapotainak mentése IEnumerable < IMemento > states = SaveStates ( alakzatok ); //Az alakzatok helyzetének megváltoztatása MoveAndScale ( alakzatok ); //Kimenetek: // Téglalap 30x50 at (13, 22) // Kör sugara 100 at (8, 4) Draw ( alakzatok ); //Az alakzatok régi pozíciójának visszaállítása RestoreStates ( states ); //Kimenetek: // Téglalap 3x5 at (10, 20) // Kör 10 sugarú pontban (5, 2) Rajzolj ( alakzatok ); } }

Nem szabványos C++ sablon

Forrásszöveg C++ nyelven # include <iostream> névtér használata std ; osztály kezdeményezője { int állapot ; nyilvános : kezdeményező (); osztályMemento ; _ Memento * getMemento (); void setState ( int ); void dumpState (); class Memento { barát osztály Kezdeményező ; privát : int állapot ; kezdeményező * org ; nyilvános : emlék (); void restoreState (); }; }; kezdeményező :: kezdeményező () : állapot ( 0 ) { } void Originator :: setState ( int s ) { állapot = s ; } void Iniginator :: dumpState () { cout << "Állapot: " << állapot << endl ; } Kezdeményező :: Memento :: Memento () : állapot ( 0 ) { } Kezdeményező :: Memento * Kezdeményező :: getMemento () { Kezdeményező :: Memento * m = új Kezdeményező :: Memento (); m -> org = ez ; m -> állapot = állapot ; visszatér m ; } void Originator :: Memento :: restoreState () { org -> állapot = állapot ; } int main ( void ) { kezdeményező org ; org . setState ( 1 ); org . szeméttelep (); Kezdeményező :: Memento * m1 = org . getMemento (); org . setState ( 2 ); org . szeméttelep (); m1 -> restoreState (); org . szeméttelep (); törölje m1 ; }

Linkek