In a system where there is a parameter store, there are two basic strategies for handling defaults:
- If the parameter is not specified in the store, a default value specified in the code is used. - A default value is supplied in the store at installation time, and it is a configuration error if the parameter is not specified in the store. The code relies on the value being present in the store. Historically, the most common scheme is the first, where the code supplies some sort of final default. However, it is far from clear to me that this is the correct answer, since: - If a default value is also included in the store at installation time, it's unclear what the true default is. - The hardcoded default is not visible to the user, and probably not to configuration tools. - If the code retrieves the value from multiple places, it could (erroneously) apply different defaults in different contexts. On the other hand: - Putting the ultimate default in the code allows the code to execute when the parameter store is missing or empty. Rebuttal: a missing critical system file is a catastrophic failure. - Putting the ultimate default in the code (and not in the parameter store) makes a clear distinction between the "factory default" value and any user-specified value. - Declaring undocumented variables in the parameter store increases their visibility, perhaps undesirably. Does anybody have any thoughts on how this philosophical difference should be applied to SMF properties? Should an SMF application include definitions and default values for all of its variables in its manifest, set the "required" flag on all of them, and then rely on the manifest to supply default values, or should it avoid including default values in the manifest and instead hardcode those defaults? (Yes, it can do either, or a mix, but is there a best practice?) The last time that I defined a parameter store mechanism, I had parameter definitions in two files: one contained metadata, including the factory default value, and was considered a read-only file, part of the source code of the application; the other was delivered empty and contained only user-specified values. This made upgrade simple: the metadata file was unconditionally overwritten on upgrade, while the user-value file was unconditionally preserved on upgrade. Since the metadata file was considered part of the application, inconsistency between it and the executable code was considered a bug. The application could rely on it to supply a default value, and considered it an internal error if a value could not be found. (That parameter store mechanism had a number of other interesting features that I would be happy to describe if anybody's interested, but that aren't relevant here.)