DesignPattern
Name: ParameterObject
Type: Design
Problem: An API call gets huge, with TooManyParameters and/or the need to change the signature frequently during development. Most invocations use default arguments. Function overloading is unavailable or considered undesirable. Or, it is desired to expand an interface without breaking existing code. Or, you need to return multiple values and don't have reference parameters available.
Context: API development, especially for a complex class/system/function.
Forces: Need to not have to type in huge argument lists; need to aid refactoring, need to decrease coupling between a function/method and its callers.
Proposed Solution: Replace the LongParameterList with a ParameterObject; an object or structure with data members representing the arguments to be passed in.
Resulting Context:
- API now takes a single argument, the ParameterObject
- ParameterObject can have multiple constructors, which configure it for different common use cases. Or, a default constructor and mutator methods can be used to initialize the parameters.
- One instance (besides UnitTests and beans) where public data members are useful.
- In languages which support named aggregate initialization, can be used to simulate "named" parameters in a language without them.
- If you want all defaults, just pass in the NullPointer or NullObject.
- Can be used only for input parameters, or if the ParameterObject is mutable, can be used to handle outbound parameters as well.
- Adding arguments to the function call can be handled by adding members to the ParameterObject; existing constructors can ensure that new arguments are set to backwards-compatible defaults.
- In languages with StaticTyping, typechecking makes sure the ParameterObject is of appropriate type.
Drawbacks:
- Performance penalty; the ParameterObject will not be cached in resources. Creating it may require additional time and may further abuse the garbage collector.
- If not careful, can leave parameters in an undefined state (depending on language).
- In some older languages, creating the ParameterObject may require more typing (and more programmer frustration/error) than just specifying an argument list.
Design Rationale: Decoupling systems.
Related Patterns:
AntiPattern you should beware of: MagicContainer. Similar to ParameterObject, but uses a generic associative container (such as a HashTable) to contain the parameters. Much slower, and you have to handle missing or superfluous parameters. (On the other hand, coupling is further reduced, and no new class need be written).
Pattern Category: CategoryStructuralPatterns
Also Known As:
Examples in the Literature:
Examples in Practice:
- X11 Graphics Context objects are examples of this pattern, using a GC to represent the equivalent of a whole mass of parameters which are of value to various drawing primitives, including fonts, colors, line thicknesses, etc.
- File handles in Unix maintain file state such as the "current read/write pointer." Passing a handle of this nature can eliminate the need to manually maintain this state.
See also (and merge with?) ValueObject, ArgumentObject, ResultObject, PredicateDispatching