Guardian (designmönster)

Målvakten
Minne
Sorts beteendemässiga
Beskrivs i Design Patterns Ja

Keeper ( eng.  Memento ) är ett beteendedesignmönster som tillåter, utan att bryta inkapsling , att fixa och spara ett objekts interna tillstånd så att det kan återställas till detta tillstånd senare.

Det finns två möjliga implementeringar av detta mönster: det klassiska, som beskrivs i boken Design Patterns , och den mindre vanliga icke-standardvarianten.

Applikation

Guardian-mönstret används när:

Struktur

Klassisk variant:

Icke-standardalternativ:

Beskrivning

Klassisk variant: Guardian-mönstret används av två objekt: "Creator" (upphovsman) och "Guardian" (vaktmästare). En "skapare" är ett objekt som har ett internt tillstånd. "Guardian"-objektet kan utföra vissa åtgärder med "Skaparen", men samtidigt är det nödvändigt att kunna rulla tillbaka ändringarna. För att göra detta ber Guardian om Guardian-objektet från Skaparen. Utför sedan den planerade åtgärden (eller sekvensen av åtgärder). För att rulla tillbaka "Skaparen" till det tillstånd som föregick ändringarna, returnerar "Guardian" objektet "Keeper" till dess "Skapare". "Guardian" är ogenomskinlig (dvs en som inte kan eller bör ändras av "Guardian").

Icke-standardvariant: Skillnaden mellan denna variant och den klassiska ligger i en mer allvarlig begränsning av "Guardian"s tillgång till "Skaparens" interna tillstånd. I den klassiska versionen har "Guardian" potentialen att komma åt "Skaparens" interna data genom "Keeper", ändra tillståndet och ställa tillbaka det till "Skaparen". I den här versionen har "Guardian" förmågan att endast återställa tillståndet för "Guardian" genom att anropa Restore. Bland annat behöver "Guardian" inte äga en koppling till "Guardian" för att återställa hans tillstånd. Detta gör att du kan spara och återställa tillståndet för komplexa hierarkiska strukturer eller nätverksstrukturer (tillståndet för objekt och alla relationer mellan dem) genom att samla in ögonblicksbilder av alla registrerade objekt i systemet.

Implementeringsexempel

Standard Java-mallen

Java -källa public class Memento { private final String state ; public Memento ( String state ) { detta . tillstånd = tillstånd ; } public String getState () { return state ; } } offentlig klass Vaktmästare { privat Memento memento ; public Memento getMemento () { return memento ; } public void setMemento ( Memento memento ) { detta . memento = memento ; } } public class Originator { privat strängtillstånd ; _ public void setState ( String state ) { this . tillstånd = tillstånd ; } public String getState () { return state ; } public Memento saveState () { returnera nytt Memento ( state ); } public void restoreState ( Memento memento ) { detta . tillstånd = minne . getstate (); } } public class Application { public static void main ( String [] args ) { Originator originator = new originator (); Vaktmästare vaktmästare = ny Vaktmästare (); upphovsman . setState ( "på" ); System . ut . printf ( "Tillstånd är %s\n" , upphovsman . getState ()); vaktmästare . setMemento ( originator.saveState ( ) ); upphovsman . setState ( "av" ); System . ut . printf ( "Tillstånd är %s\n" , upphovsman . getState ()); upphovsman . restoreState ( caretaker.getMemento ( ) ); System . ut . printf ( "Tillstånd är %s\n" , upphovsman . getState ()); } } /* * Utdata: * Status är på * Status är av * Status är på */

PHP5 standardmall

PHP5 källkod <?php /** * Keeper-mönstret lagrar och återställer objekttillstånd */ namnutrymme Memento { /** * Skaparen sparar och återställer internt tillstånd */ klass Originator { privat $stat ; offentlig funktion setState ( $state ) { $this -> state = $state ; echo sprintf ( "Tillståndsuppsättning %s \n " , $this -> state ); } public function getState () { return $this -> state ; } /** * Skapa en ögonblicksbild av objektets tillstånd * @return Memento */ public function saveMemento () { return new Memento ( $this -> state ); } /** * Återställ tillstånd * @param \Memento\Memento $memento */ public function restoreMemento ( Memento $memento ) { echo sprintf ( "Återställer tillstånd... \n " ); $this -> state = $memento -> getState (); } } /** * State Snapshot */ class Memento { privat $stat ; offentlig funktion __construct ( $state ) { $this -> state = $state ; } public function getState () { return $this -> state ; } } /** * Vaktmästaren för objektets tillstånd */ klass Vaktmästare { privat $memento ; public function getMemento () { return $this -> memento ; } public function setMemento ( Memento $memento ) { $this -> memento = $memento ; } } $originator = ny upphovsman (); $ originator -> setState ( "På" ); // Lagra internt tillstånd $caretaker = new Caretaker (); $caretaker -> setMemento ( $ originator -> saveMemento ()); // Fortsätt att byta upphovsman $ originator -> setState ( "Av" ); // Återställ sparat tillstånd $ originator -> restoreMemento ( $caretaker -> getMemento ()); }

Den första versionen av C#-mallen

Källtext i C# //Denna strukturella kod demonstrerar Memento-mönstret som tillfälligt sparar och återställer ett annat objekts interna tillstånd. // Memento pattern -- Strukturellt exempel använder System ; namnutrymme DoFactory.GangOfFour.Memento.Structural { /// <summary> /// MainApp-startklass för Structural /// Memento Design Pattern. /// </summary> class MainApp { /// <summary> /// Ingångspunkt till konsolapplikationen. /// </summary> static void Main () { Originator o = new originator (); o . State = "På" ; // Lagra internt tillstånd Vaktmästare c = ny Vaktmästare (); c . Memento = o . SkapaMemento (); // Fortsätt att byta upphovsman o . State = "Av" ; // Återställ sparat tillstånd o . SetMemento ( c . Memento ); // Vänta på användarkonsolen . ReadKey (); } } /// <summary> /// Klassen 'Originator' /// </summary> klassen Originator { private string _state ; // Property public string State { get { return _state ; } set { _state = värde ; Konsol . WriteLine ( "State = " + _state ); } } // Skapar memento public Memento CreateMemento () { return ( new Memento ( _state )); } // Återställer det ursprungliga tillståndet offentligt void SetMemento ( Memento memento ) { Console . WriteLine ( "Återställer tillstånd..." ); tillstånd = memento . tillstånd ; } } /// <summary> /// Klassen 'Memento' /// </summary> klassen Memento { private string _state ; // Constructor public Memento ( strängtillstånd ) { this . _stat = tillstånd ; } // Får eller sätter tillstånd offentlig sträng State { get { return _state ; } } } /// <summary> /// 'Caretaker'-klassen /// </summary> -klassen Caretaker { private Memento _memento ; // Får eller ställer in minnet offentligt Memento Memento { set { _memento = värde ; } { retur _memento ; } } } } Utgångstillstånd = Tillstånd = Av Återställande tillstånd : Tillstånd = _


C#

Källtext i C# använder System ; namnutrymme MementoPatte { class Program { static void Main ( string [] args ) { Foo foo = new Foo ( "Test" , 15 ); foo . print (); Vaktmästare ct1 = ny Vaktmästare (); Vaktmästare ct2 = ny Vaktmästare (); ct1 . SaveState ( foo ); foo . IntProperty += 152 ; foo . print (); ct2 . SaveState ( foo ); ct1 . RestoreState ( foo ); foo . print (); ct2 . RestoreState ( foo ); foo . print (); Konsol . ReadKey (); } } offentligt gränssnitt IOriginator { objekt GetMemento (); void SetMemento ( objektminne ) ; } public class Foo : IOriginator { public string StringProperty { get ; privat set ; } public int IntProperty { get ; set ; } public Foo ( string stringPropertyValue , int intPropertyValue = 0 ) { StringProperty = stringPropertyValue ; IntProperty = intPropertyValue ; } public void Skriv ut () { Console . WriteLine ( "==============" ); Konsol . WriteLine ( "StringProperty value: {0}" , StringProperty ); Konsol . WriteLine ( "IntProperty-värde: {0}" , IntProperty ); Konsol . WriteLine ( "==============" ); } objekt IOriginator . GetMemento () { return new Memento { StringProperty = this . StringProperty , IntProperty = detta . IntProperty }; } void IOriginator . SetMemento ( objekt memento ) { if ( Object . ReferenceEquals ( memento , null )) throw new ArgumentNullException ( "memento" ); if (!( memento är Memento )) kasta nytt ArgumentException ( "minne" ); StringProperty = (( Memento ) memento ). StringProperty ; IntProperty = (( Memento ) memento ). IntProperty ; } class Memento { public string StringProperty { get ; set ; } public int IntProperty { get ; set ; } } } public class Vaktmästare { privat objekt m_memento ; public void SaveState ( IOriginator originator ) { if ( originator == null ) throw new ArgumentNullException ( " originator" ); m_memento = upphovsman . GetMemento (); } public void RestoreState ( IOriginator originator ) { if ( originator == null ) throw new ArgumentNullException ( " originator" ); if ( m_memento == null ) kasta ny InvalidOperationException ( "m_memento == null" ); upphovsman . SetMemento ( m_memento ); } } }

Anpassad mall

Källtext i C# använder System ; använder System.Collections.Generic ; offentligt gränssnitt IOriginator { IMemento GetState (); } offentligt gränssnitt IShape : IOriginator { void Draw (); voidScale ( dubbelskala ) ; _ void Flytta ( dubbel dx , dubbel dy ); } offentligt gränssnitt IMemento { void RestoreState (); } public class CircleOriginator : IShape { privatklass CircleMemento : IMemento { privat skrivskyddad dubbel x ; _ privat skrivskyddad dubbel y ; privat skrivskyddad dubbel r ; privat skrivskyddad CircleOriginator- upphovsman ; public CircleMemento ( CircleOriginator originator ) { detta . upphovsman = upphovsman ; x = upphovsman . x ; y = upphovsman . y ; r = upphovsman . r ; } public void RestoreState () { originator . x = x ; upphovsman . y = y _ upphovsman . r = r ; } } dubbel x ; dubbelt y ; dubbelt r ; public CircleOriginator ( dubbel x , dubbel y , dubbel r ) { detta . x = x ; detta . y = y _ detta . r = r ; } public void Draw () { Console . WriteLine ( "Cirkel med radie {0} vid ({1}, {2})" , r , x , y ); } public void Skala ( dubbel skala ) { r *= skala ; } public void Flytta ( dubbel dx , dubbel dy ) { x += dx ; y += dy ; } public IMemento GetState () { return new CircleMemento ( this ); } } public class RectOriginator : IShape { privatklass RectMemento : IMemento { privat skrivskyddad dubbel x ; _ privat skrivskyddad dubbel y ; privat skrivskyddad dubbel w ; privat skrivskyddad dubbel h ; privat skrivskyddad RectOriginator- upphovsman ; public RectMemento ( RectOriginator originator ) { detta . upphovsman = upphovsman ; x = upphovsman . x ; y = upphovsman . y ; w = upphovsman . w _ h = upphovsman . h _ } public void RestoreState () { originator . x = x ; upphovsman . y = y _ upphovsman . w = w _ upphovsman . h = h ; } } dubbel x ; dubbelt y ; dubbel w ; dubbel h ; public RectOriginator ( dubbel x , dubbel y , dubbel w , dubbel h ) { detta . x = x ; detta . y = y _ detta . w = w _ detta . h = h ; } public void Draw () { Console . WriteLine ( "Rektangel {0}x{1} vid ({2}, {3})" , w , h , x , y ); } public void Skala ( dubbel skala ) { w *= skala ; h *= skala ; } public void Flytta ( dubbel dx , dubbel dy ) { x += dx ; y += dy ; } public IMemento GetState () { return new RectMemento ( this ); } } public class Caretaker { public static void Draw ( IEnumerable < IShape > shapes ) { foreach ( IShape shape in shapes ) { shape . rita (); } } public static void MoveAndScale ( IEnumerable < IShape > former ) { foreach ( IShape form i former ) { form . skala ( 10 ); form . Flytta ( 3 , 2 ); } } public static IEnumerable < IMemento > SaveStates ( IEnumerable < IShape > shapes ) { LinkedList < IMemento > states = new LinkedList < IMemento >(); foreach ( IShape form in shapes ) { stater . AddLast ( shape.GetState ( ) ); } returlägen ; _ } public static void RestoreStates ( IEnumerable < IMemento > states ) { foreach ( IMemento state in states ) { state . RestoreState (); } } public static void Main () { IShape [] shapes = { new RectOriginator ( 10 , 20 , 3 , 5 ), new CircleOriginator ( 5 , 2 , 10 ) }; //Utgångar: // Rektangel 3x5 vid (10, 20) // Cirkel med radie 10 vid (5, 2) Rita ( former ); //Spara tillstånden för formerna IEnumerable < IMemento > states = SaveStates ( shapes ); //Ändra positionen för formerna MoveAndScale ( shapes ); //Utgångar: // Rektangel 30x50 vid (13, 22) // Cirkel med radie 100 vid (8, 4) Rita ( former ); //Återställ den gamla positionen för formerna RestoreStates ( tillstånd ); //Utgångar: // Rektangel 3x5 vid (10, 20) // Cirkel med radie 10 vid (5, 2) Rita ( former ); } }

Icke-standard C++ mall

Källtext i C++ # inkluderar <iostream> använder namnutrymme std ; klass upphovsman { int tillstånd ; offentliga : upphovsman (); classMemento ; _ Memento * getMemento (); void setState ( int ); void dumpState (); klass Memento { vänklass Upphovsman ; _ privat : int tillstånd ; upphovsman * org ; offentliga : memento (); void restoreState (); }; }; upphovsman :: upphovsman () : tillstånd ( 0 ) { } void Originator :: setState ( int s ) { tillstånd = s ; } void Upphovsman :: dumpState () { cout << "State: " << tillstånd << endl ; } Upphovsman :: Memento :: Memento () : state ( 0 ) { } Upphovsman :: Memento * Originator :: getMemento () { Upphovsman :: Memento * m = ny upphovsman :: Memento (); m -> org = detta ; m -> tillstånd = tillstånd ; returnera m ; } void Upphovsman :: Memento :: restoreState () { org -> tillstånd = tillstånd ; } int main ( void ) { upphovsman org ; org . setState ( 1 ); org . dumpstate (); Upphovsman :: Memento * m1 = org . getMemento (); org . setState ( 2 ); org . dumpstate (); m1 -> restoreState (); org . dumpstate (); ta bort m1 ; }

Länkar