|
|
|
|
|
by gtramont
2215 days ago
|
|
"Logging is a feature", as the authors of Growing Object-Oriented Software Guided by Tests state. As such, we need to treat them as we would treat any other feature. One relatively straightforward way of adding logs is by decorating your objects. Logging decorators. For example, if `Client` is defined as an interface, we can have two concrete implementations. One that holds business logic – `NetClient` – and one that holds logging/developer logic – `VerboseClient`. As we inject dependencies, we can compose a client like this: `NewVerboseClient(NewClient())`. This way you may even test you logging logic by composing it with different implementations of clients (one that always fails, for example) to test the different kinds of logs. |
|
But it doesn't work well in Go by several reasons.
For example, you usually define interface not in the package where its implemented, but where its needed. Thus you must provide such wrappers in every place where some (subset) of the `Client`'s methods are used.
Another reason is that such thing rejects an ability to use your struct as is, without interfaces (and thus sometimes without heap allocation for your struct).
And, finally, if you want to adopt such approach in proprietary/internal software, where interfaces usually change more often than in libraries, you will change code in N places instead of 1 (in best case); where N is number of instrumentation methods you want to provide "as feature".