delphi3000.com - the free delphi knowledge platform
delphi3000.com - the free delphi knowledge platform
493 Users Online NOW
Have a look at your member-status

connecting people's knowledge


  - Recent ArticlesRSS feed for Recent Articles on delphi3000.com
  - List of All Articles
  - Top Viewed Articles
  - Articles (+Attachem.)
  - Articles Of Interest
  - Categories
  - Top Uploader
  - Search
  - Index

  - My Home
  - Submit an Article
  - My Articles
  - My Personal Data
  - My Bookmarks
  - Activities
  - Login/Logout

  - Sign Up
  - Why Sign Up
  - Newsletter

  - Press
  - Advertise

  - Contact
  - Feedback





Community
Borland
ClubeDelphi
Dr. Bob
UK-BUG
Delphi Meetings
Planeta Delphi



Loremo - the 1.5 liter car coming in 2009




Startblatt.de






Share this article with friendsShare this article with friends
Rate this articleRate this article - to keep the quality of delphi3000.com !
Comment this article or read through previous comments (0)


Implementation of the Memento Design PatternFormat this article printer-friendly!Bookmark function is only available for registered users!
Product:
Delphi all versions
Category:
OO-related
Skill Level:
Scoring:
Last Update:
02/28/2002
Search Keys:
delphi delphi3000 article borland vcl code-snippet tBrushRecall tFontRecall tPenRecall Memento Design Pattern
Times Scored:
6
Visits:
3207
Uploader: Jochen Fromm
Company:
Reference: N/A
 
Question/Problem/Abstract:
How do you implement the MEMENTO Design Pattern in Delphi ?
Answer:



A Memento is an object that stores a snapshot of the
internal state of another object - the memento's originator,
according to Gamma, Helm, Johnson and Vlissides
("Design Patterns", Addision-Wesley, 1995)

In the following example the originator class is a class that
does some calculations named "tCalculator". The recall-class
must be a friend class of the originator class in order to
access the private variables that characterize the current state.
In delphi you can realize this if the two classes are defined
in the same unit.

A concrete implementation of the Memento design pattern looks
like this :

tCalculator = class
              private
                ValueA,ValueB,Interval : extended;
                Strings : TStringList;
              public
                ...
              end;          

tCalculatorRecall = class
                    private
                      RefObject : tCalculator;
                      ValueA,ValueB,Interval : extended;
                      Strings : TStringList;
                    public
                      constructor Create(Calculator : tCalculator);
                      destructor Destroy; override;
                    end;

constructor tCalculatorRecall.Create(Calculator: tCalculator);
begin
  inherited Create;
  RefObject := Calculator;
  ValueA := RefObject.ValueA;
  ValueB := RefObject.ValueB;
  Interval := RefObject.Interval;

  Strings := TStringList.Create;
  Strings.Assign(RefObject.Strings);
end;

destructor tCalculatorRecall.Destroy;
begin
  RefObject.ValueA := ValueA;
  RefObject.ValueB := ValueB;
  RefObject.Interval := Interval;

  RefObject.Strings.Assign(Strings);
  Strings.Free;
  inherited Destroy;
end;


The following lines demonstrate how to use this class :

  // Store state of object
  CalculatorRecall:=tCalculatorRecall.Create(Calculator);

  // Change the state of object to do some calculations
  Calculator.ValueA := ...
  Calculator.DoSomething;

  // Restore the original state
  CalculatorRecall.Destroy;



Examples from the VCL for the Memento Design Pattern
are tFontRecall, tPenRecall and tBrushRecall, three
new available classes in Delphi 6 that are derived from TRecall.
Of course you can also define your own classes in this way.
If you do this, consider two important points :

* Derive the originator class from TPersistent
* Implement the Assign procedure

Then our example looks like this :

TCalculator = class(TPersistent)
              private
                ValueA,ValueB,Interval : extended;
                Strings : TStringList;
                ...
              public
                ...
                procedure Assign(Source: TPersistent); override;
                ...
              end;

TCalculatorRecall = class(TRecall)
                    public
                      constructor Create(ACalculator : TCalculator);
                    end;

procedure tCalculator.Assign(Source: TPersistent);
var RefObject : tCalculator;
begin
  if Source is tCalculator then
  begin
    RefObject := Source as tCalculator;
    ValueA    := RefObject.ValueA;
    ValueB    := RefObject.ValueB;
    Interval  := RefObject.Interval;
    ...
    Strings.Assign(RefObject.Strings);
    ...
  end else
    inherited Assign(Source);
end;

constructor TCalculatorRecall.Create(ACalculator: TCalculator);
begin
  inherited Create(TCalculator.Create, ACalculator);
end;














Please rate this article!
Skill level:
BeginnerExpert

Useful:
No!Very!

Overall rating:
PoorExcellent



Comments to this article
Write a new comment













 
Sign up to consume product discounts for Bronze memberships !

read more


  Visit our Sponsor

 

  Community Ad of
E. Irigoyen
 
   














 







     
  Copyright © 2000 - 2007 delphi3000.com - All rights reserved. Terms of use. || Privacy
delphi3000.com is a service by bluestep.com IT-Services GmbH (Vienna)