Pages

Labels

Featured Posts

Wednesday 26 February 2014

My Hardy Little Friend: Coding the Arduino in C++ - Choosing a development...

My Hardy Little Friend: Coding the Arduino in C++ - Choosing a development...: So now that we have decided what language to write the code in, we need to decide what development environment we want to use, and with th...

Monday 9 December 2013

Dependency Inversion in Go - Introduction

Introduction

The fact that you have landed on this page is a strong indication that you are aware of the existence of the go language.

The language itself was originally created by three Google developers back in 2007 (though officially released to the world in 2009) in their spare time, but it has since gone on to be one of the hottest new languages on the market and is even used by Google to power some of their own services.

Although a relatively young language, there is a big community of developers using it, and some of these are approaching the language in very much a craftsman like manner, and these developers are looking for ways to use principles like SOLID with it.

This is not a post about the merits of SOLID in go, what I want to cover here is one aspect of SOLID, Dependency Inversion Principle, and how you can apply DIP to go code.

Requirements of Dependency Inversion

The principle of Dependency Inversion, is to remove hardwired dependencies from any code that you write, further more functions, structs, and even packages should only depend on abstractions of other modules, and not the module itself.

This can be achieved in many ways, and some of the standard methods are:
  • Separated Interface Pattern
  • Dependency Injection
  • Inversion of Control
  • Adapter Pattern
In this group of articles I will demonstrate a simple method of implementing Inversion of Control, before moving on to Dependency Injection. The focus on these two methods is a result of the 'relative ease' of implementing IoC, and the 'availability' of DI in go when compared with the other options available.

DI Options

So what are my options as far as Dependency Injection is concerned in the go language. Well this is not an exhaustive review of all of the libraries, and if you know of others that you think are worth exploring please feel free to let me know, but at the time of writing this post the three packages below stood out as promising.
  • go-inject
  • go.inject
  • depinject
When searching for Dependency Injection packages the first two come up time and time again, and unless you pay close attention you might be forgiven for thinking that they are one in the same package.

Over the next couple of posts I will go through each option detailed above, give some background about each, as well as, with the use of a simple example discuss the good and bad points of each option.

Next: Simple IoC >>

Links

Dependency Inversion in Go - Introduction
Dependency Inversion in Go - Simple IoC
Dependency Inversion in Go - go-inject
Dependency Inversion in Go - go.inject
Dependency Inversion in Go - depinject
Dependency Inversion in Go - Summary

Dependency Inversion in Go - Simple IoC

There are many out there who seem stumped by Dependency Inversion Principle (DIP) in go, especially if they don't have experience of it in other languages it can seem a lot of work for little payoff. Those that do persevere often, like myself, immediately go off and look for a third party Dependency Injection (DI) package, but it turns out that it is relatively easy to implement DIP, via Inversion of Control (IoC), and can be achieved using the built in functions of go.

First things first, the functions required to implement IoC are in the language, but a simple description of how to do it is hard to find.

What is IoC?

At it's simplest level the basic concept of IoC is that any code that needs an object does not create it, rather the objects are already available and an implementation can be reused, and in go this can be implemented using factory functions defined on startup and stored in a map. Using this method the actual binding is not done by a function, function uses the factory to get the object, usually reference by it's interface.

So what does this achieve? Well at the simplest level the functions are not directly coupled to an object, and so other objects, based on the same interface, can substitute in and used. This comes into it's own in two particular scenarios, unit testing and ability to plug different providers into the application.

In unit testing, we are able to create mocked/fake objects to ensure that the unit tests are only testing a unit of code, and not the infrastructure beneath it.

In the plug-in case, this enables us to change systems such as databases, and message queues, relatively easily, and in a way that means that the original providers can be switched back in without reverting too much code. 

Example

The example below is based on a imaginary car sales system. The idea is that when ordering a car the request must go to a car factory that builds that particular model.

The code is broken down into it's four key areas, these being the interfaces, the concrete implementations, the 'class' factories (I know classes don't actually exist in go), and a method that defines the mapping of the objects and later uses those objects to get details of the car that has been 'built'.

If you are new to DIP you might struggle to understand how this benefits development, but if you study the code closely, and particular the main function, it should become obvious that if you wanted to substitute the make and model of car, you can register a new factory and use pass the key for this factory into the 'class' factory instead of the existing "Ford" key.

Loading ....

Summary

In summary, the simple IoC example above does provide a very straight forward option to DIP, but it isn't perfect. In the ideal world we want to setup object mappings at runtime and not build time, which is what we have here, is it possible? Very much so, and in future posts I will look to take the example and update it to be driven from a configuration file.

Would I recommend this as a path to implementing SOLID principles? I think if done properly using this approach would work well, especially on smaller projects. 

<< Previous: Introduction Next: go-inject >>

Links

Dependency Inversion in Go - Introduction
Dependency Inversion in Go - Simple IoC
Dependency Inversion in Go - go-inject
Dependency Inversion in Go - go.inject
Dependency Inversion in Go - depinject
Dependency Inversion in Go - Summary

Dependency Inversion in Go - go-inject

GoDoc http://godoc.org/code.google.com/p/go-inject
Code https://code.google.com/p/go-inject/
License Apache License, Version 2.0

This library has been created, and open sourced by Jason Kinner, who although he does work for Google, is not associated with the go project.

The style of dependency injection that go.inject uses is reflection.

Example

The example below is based on the same imaginary car sales system as used in the previous post. The idea is that when ordering a car the request must go to a car factory that builds that particular model.

The code is broken down into it's four key areas, these being the interfaces, the concrete implementations, injector tags, and a method that defines the mapping of the objects and later uses those objects to get details of the car that has been 'built'.

As with the previous post a quick look at the code, and the main function, and it should be obvious that if you wanted to substitute the make and model of car, you can change the object returned by the GetCarFactory struct to a new factory instead of the FordFactory used.

Loading ....

Summary

In summary, the go-inject example above does provide a relatively straight forward option to DIP, but like the IoC option previous, it isn't perfect, and beyond that is not as easy to extend and improve. As before we would ideally want to setup object mappings at runtime and not build time, unlike the IoC post it wouldn't be as simple to achieve, however time permitting I may look at branching the library and include a configuration driven approach.

Would I recommend this as a path to implementing SOLID principles? Although not as simple to do, it be achieved, though I may be tempted to use it on smaller projects only. 

Links

Dependency Inversion in Go - Introduction
Dependency Inversion in Go - Simple IoC
Dependency Inversion in Go - go-inject
Dependency Inversion in Go - go.inject
Dependency Inversion in Go - depinject
Dependency Inversion in Go - Summary

Dependency Inversion in Go - go.inject

GoDoc http://godoc.org/github.com/ParsePlatform/go.inject
Code https://github.com/ParsePlatform/go.inject
License Apache License, Version 2.0

This library has been created, and open sourced by the guys over at Parse, a provider of a cloud based backend system designed for mobile development, and a major contributor to the open source community.

The style of dependency injection that go.inject uses is reflection

Example

The example below is based on the same imaginary car sales system as used in the previous posts. The idea is that when ordering a car the request must go to a car factory that builds that particular model.

The code is broken down into it's three key areas, these being the interfaces, the concrete implementations, and a method that defines the mapping of the objects and later uses those objects to get details of the car that has been 'built'.

As with the previous post a quick look at the code, and the main function, and it should be obvious that if you wanted to substitute the make and model of car, you can change the object mapped in the graph. One key downside to this package is that it's not as flexible as the two previous packages and to truely achieve the functionality of the other examples a larger level of refactoring would be required.

Loading ....

Summary

In summary, the go.inject example above does provide an option for DIP, but it is neither straightforward, or perfect. As before we would ideally want to setup object mappings at runtime and not build time, in the case of go.inject, achieving this is a not inconsiderable task, and with other options out there I don't see a reason for extending this library to include a configurable approach.

As for a recommendation, my personal view is that there are better options out there.

<< Previous: go-inject Next: depinject >>

Links

Dependency Inversion in Go - Introduction
Dependency Inversion in Go - Simple IoC
Dependency Inversion in Go - go-inject
Dependency Inversion in Go - go.inject
Dependency Inversion in Go - depinject
Dependency Inversion in Go - Summary

Dependency Inversion in Go - depinject

GoDoc http://godoc.org/github.com/99designs/goodies/depinject
Code https://github.com/99designs/goodies/tree/master/depinject
License The MIT License (MIT)

This library is part of a much larger library created, and open sourced by the guys over at 99designs, a provider of website design and hosting, as well as a major contributor to the open source community.
The style of dependency injection that depinject uses is reflection.

Example

The example below is based on the same imaginary car sales system as used in the previous posts. The idea is that when ordering a car the request must go to a car factory that builds that particular model.

The code is broken down into it's three key areas, these being the interfaces, the concrete implementations, and a method that defines the mapping of the objects and later uses those objects to get details of the car that has been 'built'.

As with the previous post a quick look at the code, and the main function, and it should be obvious that if you wanted to substitute the make and model of car, you can change the factory functions registered against the types. As with go.inject this package is that it's not as flexible as the first two packages and to truly achieve the functionality of the other examples a larger level of refactoring would be required.

Loading ....

Summary

In summary, as with go.inject, the example above does provide an option for DIP, but it is again neither straightforward, or perfect. As before we would ideally want to setup object mappings at runtime and not build time, in the case of depinject, achieving this is a not inconsiderable task, and with other options out there I don't see a reason for extending this library to include a configurable approach.

As for a recommendation, my personal view is that there are better options out there.

<< Previous: go.inject Next: Summary >>

Links

Dependency Inversion in Go - Introduction
Dependency Inversion in Go - Simple IoC
Dependency Inversion in Go - go-inject
Dependency Inversion in Go - go.inject
Dependency Inversion in Go - depinject
Dependency Inversion in Go - Summary

Dependency Inversion in Go - Summary

Summary

After looking at a number of the options out there for implementing Dependency Inversion Principle (DIP) in go, there seems to be two obvious options.

The first is using Inversion of Control (IoC), and as we have seem the basics are there in the base code. It can also be seen that extending this to include features such as configuration driven binding is very possible.

The other option is Dependency Injection (DI), however of the three packages we have looked at, it looks from my viewpoint that only one is straightforward enough to use, and is probably the one best positioned to be extended.

In future posts I will look into extending these two approaches, hopefully producing two complete processes for implementing DIP in go.

If you would like to download and try the samples used in these posts please check out the following git repo: commentsondev

<< Previous: depinject

Links

Dependency Inversion in Go - Introduction
Dependency Inversion in Go - Simple IoC
Dependency Inversion in Go - go-inject
Dependency Inversion in Go - go.inject
Dependency Inversion in Go - depinject
Dependency Inversion in Go - Summary
 
 
Blogger Templates ReadABlog.com