Design mode, implementation with Delphi ----> Template Method mode

zhaozj2021-02-08  232

Template Method mode

origin

Delphi's Template Method mode is based on the virtual function of Object Pascal.

purpose

Define a framework for a set of algorithms to define some subclasses that do not change the algorithm structure.

motivation

· Better packaging strategic policy and distribute to different agents.

• Better code reuse of complex algorithms, base classes encapsulated parts, and allow subclasses to achieve overloaded partial behavior methods.

• Better through the scope of the scope of the scope, but the Template Method mode is only allowed to be called by the base class.

UML illustration:

application

Let's take a look at several Template Method mode VCL components. In the following example, abstract class TSTREAM in the VCL component implements a copy method CopyFrom (), and the template method CopyFrom () contains the necessary algorithms for the current copy. TSTREAM claims the READ () and WRITE () methods as abstract methods, and will deliver the specific subclass of it. CopyFrom () Access Readput (), Write (), readbuffer (), WriteBuffer () is a template method. They will provide static and simple read () and Write () imaginary interface. READ () and Write () are executed in the derived class in the derived class.

For more detailed implementation code, please refer to the Classes.Pas unit of VCL, abstract class TSTREAM and specific stream: TcustomMemMemoryStream / TMemoryStream and Tstringstream. Usually the Template method is defined in the base class, and the derived operation is defined as the virtual method, and you only need to overload the extension in the subclass. Yes, the interface does not support the Template method.

{Abstract class TSTREAM}

TSTREAM = Class (TOBJECT)

Private

...

protected

Procedure setsize (newsize: longint); virtual;

public

// Source supported the original method

Function Read (var buffer; count: longint; virtual; abstentract;

Function Write (CONST BUFFER): Longint; Virtual; ABSTRACT

Function seek (offset: longint; origin: word): longint; virtual; abstentract;

// Template method

Procedure Readbuffer (VAR Buffer; Count: longint);

Procedure WriteBuffer (Const Buffer; Count: longint);

/ / Encapsulate the stream of stream of the template method

Function CopyFrom (Source: TSTREAM; Count: longint): Longint

...

END;

// Specific class

TStringStream = Class (TSTREAM)

...

public

Constructor Create (const astring: string);

// The specific class implements overloaded methods

Function Read (VAR Buffer; Count: Longint; OVERRIDE): LONGINT;

...

Function Write (CONST BUFFER): Longint; OVERRIDE;

...

END;

---------

{TSTREAM} // Abstract class ...

// Template method

Procedure TSTREAM.Readbuffer (VAR Buffer; Count: longint);

Begin

IF (Count <> 0) and (buffer, count) <> count) THEN

Raise EREADERROR.CREATE (Sreaderror);

END;

Procedure TStream.writebuffer (Const Buffer; Count: longint);

Begin

IF (count <> 0) and (write (buffer, count) <> count) THEN

Raise EwriteError.create (SWRITEERROR);

END;

Function TSTREAM.COPYFROM (Source: TSTREAM; Count: longint): Longint

Const

Maxbufsize = $ f000;

VAR

BUFSIZE, N: Integer;

Buffer: pchar;

Begin

If count = 0 THEN

Begin

Source.position: = 0;

Count: = source.size;

END;

RESULT: = Count;

IF count> maxbufsize the buffsize: = maxbufsize else buffsize: = count

GetMem (buffer, bufsize);

Try

While Count <> 0 DO

Begin

IF count> buffsize kiln: = bufsize else n: = count;

Source.Readbuffer (buffer ^, n);

Writebuffer (buffer ^, n);

Dec (count, n);

END;

Finally

FreeMem (buffer, bufsize);

END;

END;

---------

{TSTRINGSTREAM} // Specific class

...

// The specific class implements the source of the source

Function TStringStream.read (var buffer; count: longint): longint

Begin

Result: = Length (fdataString) - fposition;

If Result> Count the result: = count

Move (pchar (@fdataString [fposition 1]) ^, buffer, result);

Inc (fposition, result);

END;

Function TStringStream.write (CONST BUFFER): longint

Begin

RESULT: = Count;

SetLength (fdataString, (fposition result));

Move (Buffer, Pchar (@fdataString [fposition 1]) ^, result);

Inc (fposition, result);

END;

转载请注明原文地址:https://www.9cbs.com/read-3015.html

New Post(0)