Design mode in making an upgrade file package
Qian Bao Qianxian Gao Chunling
introduction
The complexity of the software system is increasing, and the existing class library has no longer meet the needs of the project. The recommendations obtained by the Software Development Team are in addition to the characteristics of the software itself, fast launch market, low cost, and performance and performance and Safe, and software can make changes, can be delivered in time, and upgrade quickly. The software architecture can indeed become the primary goal, but the architecture may be difficult to say, because the facts will not be as designers, the demand and architecture solution will be more and more specific, the designer should Do it?
Presentation of design mode
Mode The importance of complicated systems has been recognized in other areas, and the design model in the software field provides developers with an effective way to use expert design experience. Flexible use of a variety of design patterns seem to have a design skill, existing design patterns have indeed a design basis, but design patterns are not limited to rules, and the key is how flexible use.
Make of instance upgrade files
Our file is the information and several files, which is later compressed on the basis of the need. Of course, after the upgrade file is downloaded, it is just the opposite process, decompress the division file, then place them to be properly The directory is in fact, this process can also be seen as the generation and backup recovery of the backup file. Using inheritance is an effective way to add functions, we can derive a class to add uncompressed features on the previous class. You can use new features after completion, which is indeed a method, but there is more flexible Methods, it is more likely to understand and split. We can use the pattern decoration, the mode decoration is an object structure mode. In terms of increasing functions, use inheritance is an effective way to add functions, but Decorator is more flexible than generated subclasses.
Now first split the function, it may be like this:
Figure one function split classification
From the picture, the TFileinfo class is actually our interface. It is a class in the top. It is now mainly three successors, 1 merged file class TfileinForeAdin, 2 split file class, TfileInforeadout, 3 decompression class Tzipfile, did not construct a top layer such as Tfileinfo at the beginning. Because it doesn't need him, we can build a merged program with a separate TFileinForeAdin object. After completing the descending of TzipFile, use the TzipFile object to decompress the file with TfileInForeAdout in the process, with TFileinForeadout to break down the file to the directory Go in. The function is already a single one.
As shown in Figure 1, try to manipulate three possible classes with an abstract base class, and their interface functions are not necessarily unified. Forcible definitions of unified interfaces may not understand, but at the top level This is still defined:
Procedure OpBaselist (var ls: tstrings); virtual; abstract; // manipulating information field
Procedure opfilelist; virtual; abstract; // manipulate all files
The OPBaseList function is the other information field added before manipulating files, and OpFileList will manipulate all files because it is a pure abstract function, ie, do not implement them, (in addition to, the top class is required to expand more Interface function). A list of file information is maintained in the top level: FileList: TStringList, contains a list of paths for all files. (All classes only list interfaces, please see the source code for details)
TYPE TFILEINFO = Class (TPERSIStent) Public PUBLIC
Procedure OpBaselist (var ls: tstrings); virtual; abstract; // manipulating information field
Procedure opfilelist; virtual; abstract; // manipulate all files
END;
A key step is to create a decorative class:
Type TfileDecorator = Class (TfileInfo)
public
Constructor Create (FileInfo: TfileInfo);
Procedure OpBaselist (VAR LS: TSTRINGS); OVERRIDE;
Procedure OpFileList; Override;
END;
Perhaps the decorative class has weird, he maintains a private object of TFileinfo, in fact it is connected to the connector of the object inherited from the TFileInfo class, and the M_FileInfo object references the object fileInfo that the constructor is transferred.
Constructor TfileDecorator.create (fileInfo: tfileinfo);
Begin
M_fileinfo: = fileInfo;
END;
It looks simpler in the OPBaselist and OpFileList interface:
Procedure TfileDecorator.opBaselist (VAR LS: TSTRINGS);
Begin
// inherited;
IF m_fileinfo <> nil dam
m_fileinfo.opbaselishslist (ls);
END;
Procedure tfiledecorator.opfilelist;
Begin
// inherited;
IF m_fileinfo <> nil dam
m_fileinfo.opfilelist;
END;
It seems that the objects in the constructor begin to act. Ok, the next job is to implement three functional classes, and the actual code will be in the function class:
TYPE TFILEINFOREADIN = Class (tfiledecorator)
protected
Procedure Writeafilein (filepathname: string); // Write a file
public
Constructor Create (fileInfo: tfileinfo; filename: string); //
Procedure OpBaselist (var ls: tstrings); override; // manipulated information list
Procedure opfilelist; override; // manipulate all files
END;
Type tfileinforeadout = class (tfiledecorator)
public
Constructor Create (fileInfo: tfileinfo; filename: String);
Procedure OpBaselist (VAR LS: TSTRINGS); OVERRIDE;
Procedure OpFileList; Override;
END;
Now look at the class tfileinforeadin.opfilelist function, how to manipulate the file:
Procedure tfileinforeadin.opfilelist;
VAR i: integer;
Begin
inherited; // inheritance
m_writer.writeinteger (m_filelist.count); // Write the number of files
For i: = 0 to m_filelist.count-1 do begin
Writeafilein (m_filelist.strings [i]); / / write file end according to the full path of the file;
IF assigned (m_writer) THEN
Freeandnil (M_Writer);
IF assigned (m_filestream) THEN
Freeandnil (M_FileStream);
END;
Writeafilein function implementation:
Procedure tfileinforeadin.writeafilein (filepathname: string);
VAR Readint: Integer;
Fsource: TfileStream;
Begin
Fsource: = tfilestream.create (filepathname, fmopenread); // Recreate file input stream here
m_writer.writeinteger (fsource.size); // Write the length of the file
m_writer.writestring (extractfilename); // Write file name
Repeat
Readint: = fsource.read (m_buffer ^, buffer_size); // Source file content read buffer
m_writer.write (m_buffer ^, readint);
Until Readint FreeAndnil (fsource); // Release the file stream END; As for the OpFileList implementation function of the TfileinForeadout class, the opposite of the TfileInforeadin process, is not listed here, specifically see the source code. The key is that the third class tzipfile, this class, implements the compression and decompression of the file, first plus the ZLIB unit in the unit so that we can use the TcompressStream class to implement the compression and decompression of the file stream, here there is a problem, TzipFile It is the other programmers to deliver, the interface is not uniform, but the adapter mode can make us solve such problems well. Figure 2 is a decorative class to add an adapter Figure 2 shows that tzipfile contains the compressFile () and DecompressFile () functions, while the interface OPBaseList and OpFileList are constant, and the TzipFile can be called an adapter. TYPE TZIPFILE = Class (TFiledecorator) Private m_zipfilename: string; public Constructor Create (fileInfo: tfileinfo; filename: string = '); DESTRUCTOR DESTROY; OVERRIDE; Function CompressFile (const srcfile, desfile: string; .......): TcompressResult; //Compressed file Function DecompressFile (const srcfile, desfile: string; .........): TcompressResult; //unzip files Procedure OpBaselist (var ls: tstrings); override; // The interface is still these two, but this interface does not do Procedure opfilelist; override; // call compression and decompression END; After explaining the mode, look at how we use our model, as shown in Figure 3 is the interface of this gadget: Figure three tool interface Figure 3 is our interface. After adding the file, trigger the package button, the EXE file directory will appear with the merge file EDT_EDITION.DAT file and the compressed file EDT_EDTTION.PAG with the file name edit box (edt_edition). In the Windows2000 and Delphi7, the test is successful, and the unpacking process is reversed. After clicking Add File, the file display list will add the files you need. Now the facade function is written to the information content in the TEDIT box, and then merge the files in the list into the file A, finally compression. You can now define an aread and azip objects Var aread: tfileinforeadin; azip: tzipfile; Begin Aread: = tfileinforeadin.create (nil, 'filename "; ......... Azip: = tzipfile.create (aread); // Azip object Add aread object Operatorfile (azip); // manipulate Azip object aread.free; Azip.Free; END; The operation file is simple, call two interface functions Procedure TMAINFRM.Operatorfile (OBJ: TFILEINFO); Begin Obj.opBaselist (f_strings); Obj.opfileList; // If there are other interfaces, you can call one by one here. END; If you don't have to compress files as needed, it is easy, Azip: = tzipfile.create (aread) This is removed. Also, if we write new algorithms to compress, you can modify tzipfile, or it is possible to call: = tnewzipfile.create (aread); you can also use this way: TfileInfoobj: = tfileinfoa.create (tfileinfoc.create (tfileinfoc.create (...)); Then call the interface tfileinfoobj.opfileList; a sentence to call all objects. Most importantly, the function can be split: for example TfileInfoobj: = tfileinfob.create (tfileInfoc.create))); TfileInfoobj: = tfileinfoa.create (nil); TfileInfoobj: = tfileinfob.create (tfileinfoa.create (nil)); This makes it possible to be designed, like wood, where the interface is not suitable, do not forget the structural mode of the adapter. summary In fact, I examine Delphi's TSTREAM and TMEMORYSTREAM, TFileStream, TcompressStream, etc., is an example of an excellent decorative style.