The workbook and worksheet could be defined as interfaces or as classes。 Which would be better? Let’s assume that workbook will be defined as an interface and then implemented by a class。 The approach is a mitment to a ponent architecture; allowing you to implement multiple types of workbooks。 However; the likelihood of implementing multiple workbook types is rather remote; so why use interfaces? Because interfaces fit better into a bigger context。 Let’s say that you have pleted your super…duper server…side application and want to programmatically share the code with multiple machines。 Having one puter call functionality on another machine is almost trivial; but to attain the best performance and resource usage; you should use interfaces。 Defining the Server Spreadsheet Interfaces Defining the interfaces for the server spreadsheets is actually rather plicated because of the requirements。 The requirements state performance and usability are important; which; in this case; is asking quite a bit; as you will see as we work through the example。 Let’s start with a bottom…up development approach and outline the interfaces。 Defining the Debug Interface Because the spreadsheet is from a production coding example; included in the discussion will be pieces of code that demonstrate good programming practices。 The following is the base interface for all of my interfaces; which is defined in the Devspace。Trader。mon project。 Public Interface IDebug Property Debug() As Boolean End Interface …………………………………………………………Page 315…………………………………………………………… CH AP T E R 1 1 ■ L E A R N IN G AB O U T 。 N E T G E N E R I CS 293 The IDebug interface has a single Boolean property called Debug; which can be assigned and retrieved。 The idea behind the IDebug interface is to enable a ponent to generate debug output。 One of the major headaches with debugging applications that process large amounts of data is finding where the problem is。 Imagine processing several million records; and the bug happens in record 900;001。 You don’t want to debug 900;000 records before hitting the bug。 Thus; the challenge is figuring out what went wrong without using the debugger。 This is where IDebug es into play。 It provides a mechanism to let the implementation say what is going on; so if a bug needs to be deciphered; you do so by looking at the output。 The following example demonstrates how to use the Debug flag。 The class that contains this code implements the IDebug interface and sets the Debug flag at the beginning of its execution。 Dim baseType As String() = _ typeToInstantiate。Split(New String() { 〃''〃; 〃''〃 }; StringSplitOptions。None) If baseType。Length = 0 Then Throw New Exception(〃There is no base type; which is an error〃) End If If Debug Then For Each str As String In baseType GenerateOutput。Write(〃Workbook。Load〃; 〃baseType(〃 & str & 〃)〃) Next End If The first line of code is used to split up a buffer into individual pieces; where double square brackets delimit the buffers。 The Debug property is used to output the split…up buffer using the mand GenerateOutput。Write()。 ■Tip Although I have defined my own debugging infrastructure; there is another infrastructure that you can use; called log4net (http://logging。apache。org/log4net/)。 This is a prehensive infrastructure that you may want to investigate。 A Debug flag was used to output some text; otherwise; that information is not usually visible。 Without a Debug flag; the only way to get that information is by setting a breakpoint after the Split() statement; and then individually investigating the resulting buffers。 If you had to do that for 900;000 records; you would bee bored very quickly; and let’s not even talk about how much time you would waste。 The Debug flag serves two purposes。 The first is to generate output to allow you to do a post mortem analysis when trying to figure out a bug。 The second is to generate output when a bug occurs in a production context。 By giving the user the ability to define a Debug flag; you are no longer reliant on having the user explain to you step by step how to reproduce the bug。 All you need to do is tell the user to activate the Debug flag (your program would probably have a menu item for this); run the program until the bug occurs; and then send you the debug log file output for analysis。 …………………………………………………………Page 316…………………………………………………………… 294 CH AP T E R 1 1 ■ L E A R N I N G A B OU T 。 N E T G E N E R I CS Defining the IWorksheetBase and IWorksheet Interfaces The worksheet is implemented using worksheet and workbook interfaces。 Remember that one of the requirements is to have a spreadsheet implementation that is very fast。 This would mean if a spreadsheet contained numbers; the best implementation would be a spreadsheet of Double types。 However; if the spreadsheet contained string buffers; the best implementation would be a spreadsheet of String types。 Figure 11…2 shows a spreadsheet of Double and String types。 Figure 11…2。 Spreadsheet of strings and doubles In Figure 11…2; the workbook references a worksheet of type Worksheet(Of Double) and Worksheet(Of String); and in the general case; Worksheet(Of BaseType)。 You can see how an interface using generics for a worksheet could be potentially defined: define a general worksheet and define the actual type using generics。 The problem with th