本文发表在 rolia.net 枫下论坛OP posted an example of masking exceptions. Suppose you were asked to write a function to read a file and fill a given buffer with file content. Sure, you expected errors of file not found or access denied, are you expected to propagate the error information to your caller? Maybe the caller needs to know that you failed to open the file and notify user or write a log? If the caller expected error information from you, have you documented how the error will be passed out (throw exception or return error code)? Even if you opened the file successfully, have you prepared for the file is being too large and buffer is not big enough? Have the caller been prepared for the file has been corrupted and the content read is not in the format expected?
Elevator not moving, it is not normal, should you make a call to administrator, call for repairman, or just standing there silently?
OP also posted using design patterns and writing mock-ups. Those are concepts and not generic rules. You have to rely on engineers' experience and talent in dealing with complexities. There were few systems that are more complex than Windows, I just pick few examples from it.
If you are familiar with COM, you have known IDispatch interface. Its concept is simple: you can expose arbitrary number of functions through IDispatch interface, each function is given a unique number, and the when those functions are being called, all parameters are packed into an array with each element of type VARIANT which can contain any data type, and it could even be another IDispatch object.
The goal? If somebody gives you an IDispatch object, you can know all the functions it provides and all the parameters information. The writer of the IDispatch object can add new functions into it without affecting existing code.
How flexible is it? You may also have heard of web services. Microsoft provided a utility Soap Toolkit, which allows you pass a wsdl to it, it will build the function table in memory dynamically and you can call the web service functions through the IDispatch interface, from script languages.
I believe few people here likes UAC in Vista. However there was great engineering under it. In the days of XP, programs are running under admin privilege and they can write to HKLM or Windows directory. With UAC turned on in Vista, only programs running with elevated privilege can do so. For legacy programs that are running under protected privilege and still trying to write to those forbidden locations, instead of failing the write operation, Microsoft introduced “virtual store” which redirects the write operation to a location to allow those programs continue running properly.
Kaspersky introduced “safe run” feature in recent two years and it is based on same concept. Once a program was added into safe run list, all its write operations that are considered could have impact to system stability will be redirected to a temporary location without program’s awareness. Web browsers are typical candidates for safe run.
If you are a Windows programmer, I strongly recommend reading “Windows Internals Fifth Edition”. It is a great book. Not only does it tell details how Windows works, you can also learn many great designs inside Windows. Take an example of file I/O stack: when you read something from a file, I/O manager will generate an IRP and it will pass at least three different driver stacks before it can get to hard disk controller: file system driver <-> volume driver <-> disk driver. Is it necessary? Why can’t I/O manager talk to device directly? The layered driver stack design has its purpose: anti-virus software can use file system filter driver to scan for viruses; Windows uses file driver for per-file-basis encryption; ISV can use volume driver to implement RAID functionality; ISV can also use disk driver to implement virtual disks (think RAM disk, virtual CD/disk). Each layer has its own purposes and ISVs can insert their driver into the stack to implement new functionalities. I call this is how complexity is managed.更多精彩文章及讨论,请光临枫下论坛 rolia.net