home *** CD-ROM | disk | FTP | other *** search
/ Delphi Magazine Collection 2001 / Delphi Magazine Collection 20001 (2001).iso / DISKS / Issue49 / Factory / FactoryReport.pas < prev    next >
Encoding:
Pascal/Delphi Source File  |  1999-06-16  |  5.8 KB  |  194 lines

  1. {* * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * *
  2.   TechInsite Pty. Ltd.
  3.   PO Box 429, Abbotsford, Melbourne. 3067 Australia
  4.   Phone: +61 3 9419 6456
  5.   Fax:   +61 3 9419 1682
  6.   Web:   www.techinsite.com.au
  7.   EMail: peter_hinrichsen@techinsite.com.au
  8.  
  9.   Created: 01/06/1999
  10.  
  11.   Notes: An introduction to the factory pattern
  12.  
  13. * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * *}
  14.  
  15. unit FactoryReport;
  16.  
  17. interface
  18. uses
  19.    Classes             // For TObject
  20.   ,FReportAbstract     // For TReportAbstract
  21.   ;
  22.  
  23. type
  24.  
  25.   //----------------------------------------------------------------------------
  26.   TReportClass = class of TFormReportAbstract ;
  27.  
  28.   //----------------------------------------------------------------------------
  29.   TReportMapping = class( TObject )
  30.   private
  31.     FStrReportName : string ;
  32.     FReportClass   : TReportClass ;
  33.   public
  34.     Constructor CreateExt( const pStrReportName : string ;
  35.                            pClassRef : TReportClass ) ;
  36.     property    ReportName  : string read FStrReportName
  37.                                      write FStrReportName ;
  38.     property    ReportClass : TReportClass read FReportClass
  39.                                            write FReportClass ;
  40.   end ;
  41.  
  42.   //----------------------------------------------------------------------------
  43.   TFactoryReport = class( TObject )
  44.   private
  45.     FReportMappings : TStringList ;
  46.   public
  47.     Constructor Create ;
  48.     Destructor Destroy ; override ;
  49.     Procedure RegisterReport( const pStrReportName : string;
  50.                               pClassRef : TReportClass ) ;
  51.     Function GetReport( const pStrReportName : string ) :
  52.                 TFormReportAbstract ;
  53.   end ;
  54.  
  55. // The poor man's singleton, a function to return
  56. // a reference to a variable with unit wide visibility.
  57. function gFactoryReport : TFactoryReport ;
  58.  
  59. implementation
  60. uses
  61.   SysUtils   // UpperCase
  62.   ,Dialogs   // MessageDlg
  63.   ;
  64.  
  65. var
  66.   // A variable to hold our single
  67.   // instance of TFactoryReport. This variable has
  68.   // unit wide scope, hence the u prefix.
  69.   uFactoryReport : TFactoryReport
  70.   ;
  71.  
  72. // Our poor man's singleton.
  73. // This function has global (or application) wide scope,
  74. // hence the prefix g.
  75. function gFactoryReport : TFactoryReport ;
  76. begin
  77.   // If uFactoryReport has not been created, then
  78.   // create one.
  79.   if uFactoryReport = nil then
  80.     uFactoryReport := TFactoryReport.Create ;
  81.   // Return a reference to uFactoryReport
  82.   result := uFactoryReport ;
  83. end ;
  84.  
  85. // * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * *
  86. // *
  87. // *  TReportMapping
  88. // *
  89. // * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * *
  90. constructor TReportMapping.CreateExt(
  91.                                const pStrReportName: string;
  92.                                pClassRef: TReportClass);
  93. begin
  94.   Create ;
  95.   ReportName  := pStrReportName ;
  96.   ReportClass := pClassRef ;
  97. end;
  98.  
  99. // * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * *
  100. // *
  101. // *  TFactoryReport
  102. // *
  103. // * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * *
  104. constructor TFactoryReport.Create;
  105. begin
  106.   inherited ;
  107.   // Create a TSTringList to hold the ReportMappings
  108.   FReportMappings := TStringList.Create ;
  109. end;
  110.  
  111. //------------------------------------------------------------------------------
  112. destructor TFactoryReport.Destroy;
  113. var i : integer ;
  114. begin
  115.   // Scan through FReportMappings,
  116.   // and free any associated objects
  117.   for i := 0 to FReportMappings.Count - 1 do
  118.     TObject( FReportMappings.Objects[i] ).Free ;
  119.   // Free FReportMappings
  120.   FReportMappings.Free ;
  121.   // Call inherited
  122.   inherited ;
  123. end;
  124.  
  125. //------------------------------------------------------------------------------
  126. procedure TFactoryReport.RegisterReport(
  127.                                const pStrReportName: string;
  128.                                pClassRef: TReportClass);
  129. var i : integer ;
  130.     lReportMapping : TReportMapping ;
  131.     lStrReportName : string ;
  132. begin
  133.   lStrReportName := upperCase(pStrReportName) ;
  134.  
  135.   // Does the reportName already exist?
  136.   i := FReportMappings.IndexOf( lStrReportName );
  137.   // If yes, report an error.
  138.   if i <> -1 then begin
  139.     messageDlg( 'Registering a duplicate ' +
  140.                 'report name <' +
  141.                 pStrReportName + '>',
  142.                 mtInformation,
  143.                 [mbOK],
  144.                 0 ) ;
  145.     Exit ; //==>
  146.   end ;
  147.  
  148.   // Create a reportMapping object
  149.   lReportMapping := TReportMapping.CreateExt(
  150.                       lStrReportName,
  151.                       pClassRef ) ;
  152.  
  153.   // Add the reportName, and reportMapping object to the list
  154.   FReportMappings.AddObject( upperCase( pStrReportName ),
  155.                              lReportMapping ) ;
  156.  
  157. end;
  158.  
  159. //------------------------------------------------------------------------------
  160. function TFactoryReport.GetReport(
  161.                               const pStrReportName: string):
  162.                               TFormReportAbstract;
  163. var i : integer ;
  164. begin
  165.  
  166.   // Does the report exist in the list?
  167.   i := FReportMappings.IndexOf( upperCase(pStrReportName));
  168.  
  169.   // If not, then raise an exception
  170.   if i = -1 then
  171.     Raise Exception.Create( 'Request for invalid report ' +
  172.                             'name <' +
  173.                             pStrReportName + '>' ) ;
  174.  
  175.   // Create an instance of the report, and return.
  176.   // Note that the module that called GetReport is
  177.   // responsible for freeing the report.
  178.   result :=
  179.     TReportMapping( FReportMappings.Objects[i]
  180.                                ).ReportClass.Create( nil ) ;
  181. end ;
  182.  
  183. initialization
  184.   // Call the function gFactoryReport, to create an instance
  185.   // of TFactoryReport.
  186.   gFactoryReport ;
  187.  
  188. finalization
  189.   // Free uFactoryReport
  190.   uFactoryReport.Free ;
  191.  
  192. end.
  193.  
  194.