Thursday, June 17, 2004

Clean, simple interfaces



Measures for Excellence: Reliable Software on Time, Within Budget (Yourdon Press Computing Series)The initial goal when designing a modular system should be simplicity between layers. Making the interface as straightforward as possible will ensure its longevity and encourage its use by others.

Never compromise a design by optimizing for performance up-front. Design the simplest and cleanest interface that has a good chance of being extensible. Odds are extremely high that a clean interface can be enhanced to support very high performance without drastic modification of the design.

Consider the case of a database system. A simplified class might use the calls:

§ Table.Open(table-name, access-mode)
§ Table.RecordAdd(record-data)
§ Table.Close()

If we needed to support the addition of a large number of records to the table (a high-performance bulk load), we might be tempted to add more methods:

§ Table.PrepareForBulkLoad()
§ Table.BulkLoad(record-data)
§ Table.EndBulkLoad()

However, this makes the interface more complicated. What if we preserved the initial implementation and simply required that the caller open the table with a “bulk” access mode when loading large numbers of records?

In other words:


if ((rc = table.Open(szTable, TBL_BULK_MODE)) != 0) {
// log
break;
}
bTableOpen = TRUE;
for (i = 0; i < csaImportRecords.GetSize(); i++) {
sRecord = csaImportRecords.GetAt(i);
table.RecordAdd(sRecord);
}


Because the table has been opened in “bulk mode”, the class knows to cache records before writing them en masse. In other words, all of the optimizations occur inside the class and not in the interface(s) between classes.

The clean, simple design approach permits this to happen without cluttering the design.

No comments: