1
0
mirror of https://github.com/open-telemetry/opentelemetry-go.git synced 2024-12-10 09:50:58 +02:00

Refine configuration design docs (#1841)

* Refine configuration design docs

* Remove repetition

* Fix typo

* Unify code blocks

Co-authored-by: Tyler Yahn <MrAlias@users.noreply.github.com>
This commit is contained in:
Robert Pająk 2021-04-27 20:04:09 +02:00 committed by GitHub
parent 62cd933da5
commit 392a44fa46
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23

View File

@ -15,7 +15,7 @@ join the meeting or get in touch on
You can view and edit the source code by cloning this repository:
```bash
```sh
git clone https://github.com/open-telemetry/opentelemetry-go.git
```
@ -166,16 +166,16 @@ to the reasons why.
### Configuration
When creating an instantiation function for a complex `struct` it is useful
to allow variable number of options to be applied. However, the strong type
system of Go restricts the function design options. There are a few ways to
solve this problem, but we have landed on the following design.
When creating an instantiation function for a complex `type T struct`, it is
useful to allow variable number of options to be applied. However, the strong
type system of Go restricts the function design options. There are a few ways
to solve this problem, but we have landed on the following design.
#### `config`
Configuration should be held in a `struct` named `config`, or prefixed with
specific type name this Configuration applies to if there are multiple
`config` in the package. This `struct` must contain configuration options.
`config` in the package. This type must contain configuration options.
```go
// config contains configuration options for a thing.
@ -184,7 +184,7 @@ type config struct {
}
```
In general the `config` `struct` will not need to be used externally to the
In general the `config` type will not need to be used externally to the
package and should be unexported. If, however, it is expected that the user
will likely want to build custom options for the configuration, the `config`
should be exported. Please, include in the documentation for the `config`
@ -203,7 +203,7 @@ func newConfig([]Option) config {
// Set default values for config.
config := config{/* […] */}
for _, option := range options {
option.Apply(&config)
option.apply(&config)
}
// Preform any validation here.
return config
@ -224,10 +224,14 @@ To set the value of the options a `config` contains, a corresponding
```go
type Option interface {
Apply(*config)
apply(*config)
}
```
Having `apply` unexported makes sure that it will not be used externally.
Moreover, the interface becomes sealed so the user cannot easily implement
the interface on its own.
The name of the interface should be prefixed in the same way the
corresponding `config` is (if at all).
@ -250,11 +254,11 @@ func With*(…) Option { … }
```go
type defaultFalseOption bool
func (o defaultFalseOption) Apply(c *config) {
func (o defaultFalseOption) apply(c *config) {
c.Bool = bool(o)
}
// WithOption sets a T* to have an option included.
// WithOption sets a T to have an option included.
func WithOption() Option {
return defaultFalseOption(true)
}
@ -263,15 +267,15 @@ func WithOption() Option {
```go
type defaultTrueOption bool
func (o defaultTrueOption) Apply(c *config) {
func (o defaultTrueOption) apply(c *config) {
c.Bool = bool(o)
}
// WithoutOption sets a T* to have Bool option excluded.
// WithoutOption sets a T to have Bool option excluded.
func WithoutOption() Option {
return defaultTrueOption(false)
}
````
```
##### Declared Type Options
@ -280,11 +284,11 @@ type myTypeOption struct {
MyType MyType
}
func (o myTypeOption) Apply(c *config) {
func (o myTypeOption) apply(c *config) {
c.MyType = o.MyType
}
// WithMyType sets T* to have include MyType.
// WithMyType sets T to have include MyType.
func WithMyType(t MyType) Option {
return myTypeOption{t}
}
@ -292,11 +296,11 @@ func WithMyType(t MyType) Option {
#### Instantiation
Using this configuration pattern to configure instantiation with a `New*`
Using this configuration pattern to configure instantiation with a `NewT`
function.
```go
func NewT*(options ...Option) T* {…}
func NewT(options ...Option) T {…}
```
Any required parameters can be declared before the variadic `options`.
@ -313,38 +317,38 @@ For example.
```go
// config holds options for all animals.
type config struct {
Weight float64
Color string
MaxAltitude float64
Weight float64
Color string
MaxAltitude float64
}
// DogOption apply Dog specific options.
type DogOption interface {
ApplyDog(*config)
applyDog(*config)
}
// BirdOption apply Bird specific options.
type BirdOption interface {
ApplyBird(*config)
applyBird(*config)
}
// Option apply options for all animals.
type Option interface {
BirdOption
DogOption
BirdOption
DogOption
}
type weightOption float64
func (o weightOption) ApplyDog(c *config) { c.Weight = float64(o) }
func (o weightOption) ApplyBird(c *config) { c.Weight = float64(o) }
func (o weightOption) applyDog(c *config) { c.Weight = float64(o) }
func (o weightOption) applyBird(c *config) { c.Weight = float64(o) }
func WithWeight(w float64) Option { return weightOption(w) }
type furColorOption string
func (o furColorOption) ApplyDog(c *config) { c.Color = string(o) }
func (o furColorOption) applyDog(c *config) { c.Color = string(o) }
func WithFurColor(c string) DogOption { return furColorOption(c) }
type maxAltitudeOption float64
func (o maxAltitudeOption) ApplyBird(c *config) { c.MaxAltitude = float64(o) }
func (o maxAltitudeOption) applyBird(c *config) { c.MaxAltitude = float64(o) }
func WithMaxAltitude(a float64) BirdOption { return maxAltitudeOption(a) }
func NewDog(name string, o ...DogOption) Dog {…}