Hacker News new | ask | show | jobs
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.

2 comments

Thats true that such approach also exists.

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".

Doing this is going to make navigating your code harder for little gain. It’s ok to put logging next to business logic. If you do this and actually follow through with it you can end up with a dozen wrapping classes with only one business logic class. I’ve seen this at my work. It makes debugging/finding/mutating the business class harder because you have to figure out which class you actually care about and how the classes were organized when they were constructed. Just make 1 class. It’ll save you plenty of code and be easier to understand/read.