System Design Issues

After the requirements for a program or system are successfully identified, it is time to get busy with the design—that is, the complete package of documentation that an implementer needs to create the final product. In some technical literature, a separate analysis phase is identified. However, this book presents analyzing the program and its surroundings as fully integrated with finding the requirements and making the design. As such, it would be unnatural to try to treat analysis separately.

The next section examines performance and footprint issues to be dealt with during the design phase. The first part discusses the static framework of a program, and the second part discusses the dynamic objects of a program.

Application Framework (Static)

The previous section highlighted key areas where performance and footprint requirements could be found. Of course, these also have implications where the design is concerned. This section highlights the key areas for the design of the program itself:

  • Design Focus

    Is it better to optimize a program for performance or for footprint? Designing a (fast) program where memory is not a scarce resource completely differs from trying to squeeze functionality into a small runtime space (such as, in-place algorithms versus memory-hungry input-to-output conversion algorithms). Consider optimizing just certain parts of a program for footprint size to save some memory. Using that saved memory in other parts of the program allows these to be even better optimized for performance.

  • Functional Modeling

    Is it best to build one large program containing all functionality or to split the program into smaller tools? By running the tools separately (maybe even from a single continuous menu), it is possible to save considerably on runtime memory.

  • Look and Feel

    How is the program operated? Where are delays expected? What kind of feedback does the user expect? When and where do you use double functionality (mouse, and hotkeys, and so on)? Consider having slow operations take place in the background while the main application (separate thread) stays responsive to the user.

  • Subsystems

    What kind of subsystems can you identify? How do they communicate? Do they call each other's functions? Do they transfer data or share the same data?

  • Flexibility

    How flexible do you want to be (and need to be) for future changes? Do you build a wildly generic framework or concentrate only on the functionality required by the current customer? Are you actually prepared to sacrifice performance to be more flexible?

  • Data Flow

    How does the data flow through the designed components? Are there time dependencies? Have you considered where scheduled and where event-driven mechanisms are appropriate?

  • Portability

    Do you want to be flexible enough to allow the software to be easily rebuilt to run on other hardware systems (porting the software)? If so, the set up of the software cannot be made hardware dependent. All hardware interactions will need to be done through a generic mechanism. Any hardware-specific elements will need to be put in separate modules which will be replaced during a port.

  • Reusability

    Do you expect to use (parts) of your program in some future contexts? Any parts to be reused should then be identified and put together in functional groups. This is true also for the relevant documentation.

  • Intelligence Placement

    Do you want intelligent submodules or do you want to keep all the decision-making power in the main module? The differences are that either the submodules become quite large or the main module does, and portability and reusability are therefore influenced.

    The same intelligence choices need to be made concerning client/server applications. Who does most of the work, the client or the server?

Object Lifetime (Dynamic)

Generally, programs are made up of several functional objects of which a number of instances can be found in memory during runtime (classes, threads, libraries, and so on). Objects which are not part of the static framework of a program are generally created and destroyed as needed. This section examines typical life cycles of software objects.

Intermediate Objects

Intermediate objects are used to store intermediate results and information during processing. They are typically used within a certain part of a program only, often localized inside a single function, and have a very short life span. They do not outlive the program, and they do not outlive the function or module they are used in. An example of intermediate objects is the variables declared inside a class or function, as shown in Listing 2.1:

Code Listing 2.1. Intermediate Objects
~
class PaintCanvas;
~
PaintCanvasManager::DoWop()
{
    int a;                              // intermediate
    ~
    PaintCanvas  firstCanvas;                // intermediate
    ~
    int intMed = nrOfProcessedCanvasses;        // intermediate
    if(~~
    {
        nrOfProcessedCanvasses = IntMed;
    }
    ~

}

Persistent Objects

Because persistent objects stay alive after the program terminates, they are still when the program restarts. These objects are used to retain information about a previous run. Examples of this are files in which program data is stored and keys which are set in the registry of the OS (Windows uses this). Such objects will even outlive a computer reboot. Other persistent objects may be resident in memory, like the clipboard to which you can copy pieces of text or pictures from for instance, a word processor. Dedicated hardware may even have special memory reserved for storing persistent objects, disks, EEPROM, FLASH, and so on. The advantage of keeping objects such as these in memory is the speed with which they can be recalled when they are needed again. This can even increase restart time of the program or the dedicated hardware on which the system runs.

Decisions to make in memory management (as part of the program or system) can include deleting certain objects or moving them to disk to (temporarily) free some runtime memory.

Temporary Objects

Temporary objects fall somewhere between intermediate and persistent objects. Their lifetime is generally longer than that of intermediate objects, meaning they outlive functions and program modules; however, they do not often outlive the program itself. An example of a temporary object is the Undo Buffer. Found in most word processors, the Undo function can recall a previous version of text. The buffer content changes constantly during program execution, but the buffer itself is accessible as long as the program is active.

Temporary autosave files fall into this category also; however, their properties are closer to persistent storage than the previous example.

Spawned Objects

Spawned objects are donated to—and used by—a scope beyond their creation. Their lifetime is managed and controlled by the object or program they are donated to. Think, for example, of an object returned by a function or program module:

char * Donator::Creator()
{

~
    char * spawn = new char [stlen(initstring) + 1];
    ~
    return spawn;

}

~
~

void Receiver::User()
{
~
    char * spawned = donateClass->Creator();

    ~
    delete [] spawned;
}

The spawned object in this example is a string allocated by the Donator class and donated to the Receiver class. The donator proceeds as if the object never existed. The Receiver class is now the sole owner of the object and is in charge of its lifetime. Any memory leakage caused by the spawned object is in effect a Receiver problem.

After a receiver indicates it has correctly received a donated spawned, it is necessary to destroy all administration of the object. The communication interface is very important here because if for some reason the object is copied in the transferal, this will have an impact on performance as well as footprint. Refer to Chapter 8, "Functions."

Having examined the different storage types, you can conclude that the design should specify what kinds of objects are being dealt with, which in turn indicates how they should be stored. Short-lived, frequently used objects should be stored in memory, with perhaps more persistent copies of data for crash recovery purposes, and so on.

..................Content has been hidden....................

You can't read the all page of ebook, please click here login for view all page.
Reset