Interface Kit Team Process
This paper deals with the set of requirements for reimplementing any portion of the BeOS
covered by the Interface Kit team's charter; namely, the Interface Kit, the Application
Kit, the app_server, and related preferences applets. This team's resposibilities
may broaden later to include more areas of the OS which are related (the input_server
comes to mind as a possibility). Since the mandate of the group covers such a
large and public (from a 3rd party developer's perspective) portion of BeOS -- a portion
that is central to the user and developer experience of BeOS -- it is vital that our work
be done in a scrupulously documented and tested fashion. This paper lays out the
process which, when adhered to, aims to ensure this high standard of documentation and
testability.
First, a definition of "module" as it pertains to this paper.
Module:
A function, class, kit, application or related set of functions, classes, kits or
applications is refered to as a "module" in this paper, the implication being that
there can be modules within modules. A module is any specifiable and testable
entity -- which may or may not rely on other modules to accomplish its functionality.
Process Requirements
Each module in this project shall have the following items:
- Complete interface specification. For kits, this will mostly come
from the BeBook, but in many cases the specification will have to elaborate
on what the BeBook provides or even be created entirely (app_server internals
are a good example).
- Complete use case specification. For those not familiar with use cases,
they consist of the following:
- A list of ways in which a module is expected to be used
- Sublists of assumptions/prerequisites for each of those cases.
This should include items such as state of an object instance at the
time of method invocation, the state of parameters passed to functions,
etc.
- Sublists of error conditions and handling for each case where
assumptions/prerequisites are not properly met. This list should
not attempt to be all inclusive: circumstances that do not
directly bear upon the assumptions/prerequisites do not need to be
considered unless clearly necessary.
- A set of unit tests which verify that the module performs correctly in expected
use cases as well as under error conditions as described in the use case
specification.
- A plain-english discussion of how the module implements its functionality:
what algorithms are to be used, what other modules are relied upon, the general
design rationale, execution flow, etc.
- The actual reimplementation.
Each of the above items is to be completed roughly in the order listed. In other
words, a given module should have a complete interface specification, etc., before it is
reimplemented. Prototyping is encouraged, of course. For existing APIs, the
recommended course is to write the interface spec, use case spec and unit tests to the
API. Unit tests, in particular, should perform as expected when run against the
existing API. When they do not, changes may need to be made to the specifications.
Our goal is to reimplement the APIs as they are, not necessarily as they're
documented -- and then ensure that the docs accurately reflect the reimplementation.
Thorough testing of the existing implementation will show us where the
documentation is wrong, misleading or absent, thereby helping to ensure that our
reimplementation is functionaly identical to the existing one.
CppTest
is the test framework we will be using. By using this framework for all our unit
tests, we can easily build large test suites which will verify the codebase in a single
executed run. An excellent short discussion of the value of unit tests is here:
http://www.extremeprogramming.org/rules/unittests.html
A Suggestion
Although the interface specification for each module should be completed first, I have a
suggestion for how to proceed from there which should make the remainder of the process
less boring. Rather than following the interface specification with a full set of
use cases followed by a full set of tests, a more productive and enjoyable way to go is
to take each module in turn, write one of the use cases/error conditions for it and
immediately write the test for that use case/error condition. This will break up
the tedious process of specifying all the use cases and error conditions with a bit of
coding -- not implementation code, but code nonetheless.
Some Final Thoughts
This process is a very rigorous approach to take. Given that our goal is to produce
the most stable, robust and professional desktop operating system available, this sort of
thoroughness is justifiable and necessary. Our understanding of the system will be
greatly increased and the task of coming up to speed on the system will be made much
easier for outsiders and newcomers to the project.
This approach is also not the most "fun": sitting down and hacking out code has the
attraction of instant gratification that design work does not. It is important to
understand, however, that proper design work done up front makes the task of
implementation easier, the chore of integration much less onerous and testing and
code verification a snap. Provided we do not get locked in "analysis paralysis"
and attack the design work as vigorously as the coding work, the entire project will
actually move more quickly -- usually quite a bit more quickly -- than if we had simply
started coding. Thrown away versions of the codebase should be just that:
quick prototypes intended to be disposable, rather than full-blown implementation
attempts which fail or are mysterious blackboxes because we don't really understand the
module. Following this process makes it far more likely that when we sit down to
do a module implementation, the first try will be the last (bug fixes not withstanding,
of course ;).
To ensure the process is followed and we produce the highest quality code we can, code
will not be accepted for release until all of the process items are covered. If
this seems like a hardline stance to take, remember: every single app which
utilizes the Application and Interface Kits relies on our code to be rock solid --
totally predictable and completely reliable. Let's strive to be engineers, not
h4X0rz.
The OpenBeOS project is hosted by:
Copyright © 2001-2002
OpenBeOS Project