# Composition with Go

- Published: September 13, 2015
- Author: William Kennedy
- URL: https://www.ardanlabs.com/blog/2015/09/composition-with-go.html

Composition goes beyond the mechanics of <a href="https://www.ardanlabs.com/blog/2014/05/methods-interfaces-and-embedded-types.html" target="_blank">type embedding</a>. It's a paradigm we can leverage to design better APIs and to build larger programs from smaller parts. It all starts from the declaration and implementation of types that have a single purpose. Programs that are architected with composition in mind have a better chance to grow and adapt to changing needs. They are also much easier to read and reason about.

<br />
<br />
To demonstrate these concepts, we will be reviewing the following program:<br />
<br />
<a href="https://github.com/ardanlabs/gotraining/blob/c081f15e59fbe895c50b25a8a2d2eaf7a5772cbc/topics/composition/example4/example4.go" target="_blank">Sample Code</a><br />
<br />
This code sample explores the mechanics behind embedding and provides us with an opportunity to discuss how, with composition, we can design for both flexibility and readability. Every identifier that is exported from a package makes up the package’s API. This includes all the constants, variables, types, methods and functions that are exported. Comments are a frequently-overlooked aspect of every package's API, so be very clear and concise when communicating information to the user of the package.<br />
<br />
The example is long so let’s break it down in pieces and walk our way through it.<br />
<br />
The idea behind this program is we have a contractor that we hired to renovate our house. In particular, there are some boards in the house that have rotted and need to be yanked out, as well as new boards that need to be nailed in. The contractor will be given a supply of nails, boards to work with and tools to perform the work.<br />
<br />
<span style="background-color: #eeeeee;">&nbsp; <b>Listing 1</b> &nbsp;</span>
<br />
<div style="background-color: #efefef; font-family: 'Courier New', Courier, monospace; font-size: small; overflow-x: scroll; padding: 10px; white-space: nowrap;">
13 // Board represents a surface we can work on.<br />
14 type Board struct {<br />
15 &nbsp; &nbsp; NailsNeeded int<br />
16 &nbsp; &nbsp; NailsDriven int<br />
17 }
</div>
<br />
In listing 1, we have the declaration of the <span style="font-family: &quot;courier new&quot; , &quot;courier&quot; , monospace;">Board</span> type. A <span style="font-family: &quot;courier new&quot; , &quot;courier&quot; , monospace;">Board</span> has two fields, the number of nails the board needs and the current number of nails driven into the board. Now, let’s look at the interfaces that are declared:
<br />
<br />
<span style="background-color: #eeeeee;">&nbsp; <b>Listing 2</b> &nbsp;</span>
<br />
<div style="background-color: #efefef; font-family: 'Courier New', Courier, monospace; font-size: small; overflow-x: scroll; padding: 10px; white-space: nowrap;">
21 // NailDriver represents behavior to drive nails into a board.<br />
22 type NailDriver interface {<br />
23 &nbsp; &nbsp; DriveNail(nailSupply &#42;int, b &#42;Board)<br />
24 }<br />
25<br />
26 // NailPuller represents behavior to remove nails into a board.<br />
27 type NailPuller interface {<br />
28 &nbsp; &nbsp; PullNail(nailSupply &#42;int, b &#42;Board)<br />
29 }<br />
30<br />
31 // NailDrivePuller represents behavior to drive/remove nails into a board.<br />
32 type NailDrivePuller interface {<br />
33 &nbsp; &nbsp; NailDriver<br />
34 &nbsp; &nbsp; NailPuller<br />
35 }
</div>
<br />
Listing 2 shows the interfaces that declare the behavior we need from the tools that may be used by the contractor. The <span style="font-family: &quot;courier new&quot; , &quot;courier&quot; , monospace;">NailDriver</span> interface on line 22 declares behavior to drive a single nail into a board. The method is given a supply of nails and the board to drive the nail into. The <span style="font-family: &quot;courier new&quot; , &quot;courier&quot; , monospace;">NailPuller</span> interface on line 27 declares the opposite behavior. The method is given a supply of nails and the board, but it will pull a nail from the board to place back into the supply.<br />
<br />
These two interfaces, <span style="font-family: &quot;courier new&quot; , &quot;courier&quot; , monospace;">NailDriver</span> and <span style="font-family: &quot;courier new&quot; , &quot;courier&quot; , monospace;">NailPuller</span>, each implement a single, well defined behavior. This is what we want. Being able to break down behavior into individual, simple acts, lends itself to composability, flexibility and readability as you will see.<br />
<br />
The final interface declared on line 32 is named <span style="font-family: &quot;courier new&quot; , &quot;courier&quot; , monospace;">NailDrivePuller</span>:
<br />
<br />
<span style="background-color: #eeeeee;">&nbsp; <b>Listing 3</b> &nbsp;</span>
<br />
<div style="background-color: #efefef; font-family: 'Courier New', Courier, monospace; font-size: small; overflow-x: scroll; padding: 10px; white-space: nowrap;">
32 &nbsp; &nbsp; type NailDrivePuller interface {<br />
33 &nbsp; &nbsp; &nbsp; &nbsp; NailDriver<br />
34 &nbsp; &nbsp; &nbsp; &nbsp; NailPuller<br />
35 &nbsp; &nbsp; }
</div>
<br />
This interface is composed from both the <span style="font-family: &quot;courier new&quot; , &quot;courier&quot; , monospace;">NailDriver</span> and <span style="font-family: &quot;courier new&quot; , &quot;courier&quot; , monospace;">NailPuller</span> interfaces. This is a very common pattern you will find in Go, taking existing interfaces and grouping them into composed behaviors. You will see how this plays into the code later on. For now, any concrete type value that implements both the driver and puller behaviors will also implement the <span style="font-family: &quot;courier new&quot; , &quot;courier&quot; , monospace;">NailDrivePuller</span> interface.<br />
<br />
With the behaviors defined, it is time to declare and implement some tools:<br />
<br />
<span style="background-color: #eeeeee;">&nbsp; <b>Listing 4</b> &nbsp;</span>
<br />
<div style="background-color: #efefef; font-family: 'Courier New', Courier, monospace; font-size: small; overflow-x: scroll; padding: 10px; white-space: nowrap;">
39 // Mallet is a tool that pounds in nails.<br />
40 type Mallet struct{}<br />
41<br />
42 // DriveNail pounds a nail into the specified board.<br />
43 func (Mallet) DriveNail(nailSupply &#42;int, b &#42;Board) {<br />
44 &nbsp; &nbsp; // Take a nail out of the supply.<br />
45 &nbsp; &nbsp; &#42;nailSupply--<br />
46<br />
47 &nbsp; &nbsp; // Pound a nail into the board.<br />
48 &nbsp; &nbsp; b.NailsDriven++<br />
49<br />
50 &nbsp; &nbsp; fmt.Println(&quot;Mallet: pounded nail into the board.&quot;)<br />
51 }
</div>
<br />
In listing 4 on line 40, we have the declaration of a struct type named <span style="font-family: &quot;courier new&quot; , &quot;courier&quot; , monospace;">Mallet</span>. This type is declared as an empty struct since there is no state that needs to be maintained. We only need to implement behavior.<br />
<br />
A mallet is a tool that is used to hammer in nails. So on line 43, the <span style="font-family: &quot;courier new&quot; , &quot;courier&quot; , monospace;">NailDriver</span> interface is implemented via the declaration of the <span style="font-family: &quot;courier new&quot; , &quot;courier&quot; , monospace;">DriveNail</span> method. The implementation of the method is irrelevant, it subtracts a value from the nail supply and adds a value to the board.<br />
<br />
Let’s look at the declaration and implementation of our second tool:<br />
<br />
<span style="background-color: #eeeeee;">&nbsp; <b>Listing 5</b> &nbsp;</span>
<br />
<div style="background-color: #efefef; font-family: 'Courier New', Courier, monospace; font-size: small; overflow-x: scroll; padding: 10px; white-space: nowrap;">
53 // Crowbar is a tool that removes nails.<br />
54 type Crowbar struct{}<br />
55<br />
56 // PullNail yanks a nail out of the specified board.<br />
57 func (Crowbar) PullNail(nailSupply &#42;int, b &#42;Board) {<br />
58 &nbsp; &nbsp; // Yank a nail out of the board.<br />
59 &nbsp; &nbsp; b.NailsDriven--<br />
60<br />
61 &nbsp; &nbsp; // Put that nail back into the supply.<br />
62 &nbsp; &nbsp; &#42;nailSupply++<br />
63<br />
64 &nbsp; &nbsp; fmt.Println(&quot;Crowbar: yanked nail out of the board.&quot;)<br />
65 }
</div>
<br />
In listing 5, we have the declaration of our second tool on line 54. This type represents a crowbar which can be used to pull nails from a board. On line 57, we have the implementation of the <span style="font-family: &quot;courier new&quot; , &quot;courier&quot; , monospace;">NailPuller</span> interface via the declaration of the <span style="font-family: &quot;courier new&quot; , &quot;courier&quot; , monospace;">PullNail</span> method. The implementation once again is irrelevant but you can see how a nail is subtracted from the board and added to the nail supply.<br />
<br />
At this point in the code, we have declared tooling behavior via our interfaces and implemented that behavior via a set of struct types that represent two distinct tools our contractor can use. Now, let’s create a type that represents a contractor who performs the work using these tools:<br />
<br />
<span style="background-color: #eeeeee;">&nbsp; <b>Listing 6</b> &nbsp;</span>
<br />
<div style="background-color: #efefef; font-family: 'Courier New', Courier, monospace; font-size: small; overflow-x: scroll; padding: 10px; white-space: nowrap;">
69 // Contractor carries out the task of securing boards.<br />
70 type Contractor struct{}<br />
71<br />
72 // Fasten will drive nails into a board.<br />
73 func (Contractor) Fasten(<b>d NailDriver</b>, nailSupply &#42;int, b &#42;Board) {<br />
74 &nbsp; &nbsp; for b.NailsDriven &lt; b.NailsNeeded {<br />
75 &nbsp; &nbsp; &nbsp; &nbsp; <b>d.DriveNail(nailSupply, b)</b><br />
76 &nbsp; &nbsp; }<br />
77 }
</div>
<br />
In listing 6, we have the declaration of the <span style="font-family: &quot;courier new&quot; , &quot;courier&quot; , monospace;">Contractor</span> type on line 70. Again, we don’t need any state so we are using an empty struct. Then on line 73, we see the <span style="font-family: &quot;courier new&quot; , &quot;courier&quot; , monospace;">Fasten</span> method, one of the three methods declared against the <span style="font-family: &quot;courier new&quot; , &quot;courier&quot; , monospace;">Contractor</span> type.<br />
<br />
The method <span style="font-family: &quot;courier new&quot; , &quot;courier&quot; , monospace;">Fasten</span> is declared to provide a contractor the behavior to drive the number of nails that are needed into a specified board. The method requires the user to pass as the first parameter a value that implements the <span style="font-family: &quot;courier new&quot; , &quot;courier&quot; , monospace;">NailDriver</span> interface. This value represents the tool the contractor will use to execute this behavior. Using an interface type for the this parameter allows the user of the API to later create and use different tools without the need for the API to change. The user is providing the behavior of the tooling and the <span style="font-family: &quot;courier new&quot; , &quot;courier&quot; , monospace;">Fasten</span> method is providing the workflow for when and how the tool is used.<br />
<br />
Notice we are using the <span style="font-family: &quot;courier new&quot; , &quot;courier&quot; , monospace;">NailDriver</span> interface and not the <span style="font-family: &quot;courier new&quot; , &quot;courier&quot; , monospace;">NailDrivePuller</span> interface for the parameter’s type. This is very important since the only behavior that is needed by the <span style="font-family: &quot;courier new&quot; , &quot;courier&quot; , monospace;">Fasten</span> method is the ability to drive nails. By declaring only the behaviors we need, our code is easier to comprehend while also being easier to use due to minimal coupling. Now, let’s look at the <span style="font-family: &quot;courier new&quot; , &quot;courier&quot; , monospace;">Unfasten</span> method:<br />
<br />
<span style="background-color: #eeeeee;">&nbsp; <b>Listing 7</b> &nbsp;</span>
<br />
<div style="background-color: #efefef; font-family: 'Courier New', Courier, monospace; font-size: small; overflow-x: scroll; padding: 10px; white-space: nowrap;">
79 // Unfasten will remove nails from a board.<br />
80 func (Contractor) Unfasten(<b>p NailPuller</b>, nailSupply &#42;int, b &#42;Board) {<br />
81 &nbsp; &nbsp; for b.NailsDriven &gt; b.NailsNeeded {<br />
82 &nbsp; &nbsp; &nbsp; &nbsp; <b>p.PullNail(nailSupply, b)</b><br />
83 &nbsp; &nbsp; }<br />
84 }
</div>
<br />
The <span style="font-family: &quot;courier new&quot; , &quot;courier&quot; , monospace;">Unfasten</span> method declared in listing 7 provides the contractor the opposite behavior of the <span style="font-family: &quot;courier new&quot; , &quot;courier&quot; , monospace;">Fasten</span> method. This method will remove as many nails as necessary from the specified board and add those back into the supply. This method accepts only tools that implement the <span style="font-family: &quot;courier new&quot; , &quot;courier&quot; , monospace;">NailPuller</span> interface. This is exactly what we want since this is the only behavior required in the implementation of this method.<br />
<br />
The final behavior for a contractor is a method called <span style="font-family: &quot;courier new&quot; , &quot;courier&quot; , monospace;">ProcessBoards</span> which allows the contractor to work on a set of boards at one time:<br />
<br />
<span style="background-color: #eeeeee;">&nbsp; <b>Listing 8</b> &nbsp;</span>
<br />
<div style="background-color: #efefef; font-family: 'Courier New', Courier, monospace; font-size: small; overflow-x: scroll; padding: 10px; white-space: nowrap;">
86 // ProcessBoards works against boards.<br />
87 func (c Contractor) ProcessBoards(<b>dp NailDrivePuller</b>, nailSupply &#42;int, boards []Board) {<br />
88 &nbsp; &nbsp; for i := range boards {<br />
89 &nbsp; &nbsp; &nbsp; &nbsp; b := &amp;boards[i]<br />
90<br />
91 &nbsp; &nbsp; &nbsp; &nbsp; fmt.Printf(&quot;contractor: examining board #%d: %+v\n&quot;, i+1, b)<br />
92<br />
93 &nbsp; &nbsp; &nbsp; &nbsp; switch {<br />
94 &nbsp; &nbsp; &nbsp; &nbsp; case b.NailsDriven &lt; b.NailsNeeded:<br />
95 &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; c.Fasten(<b>dp</b>, nailSupply, b)<br />
96<br />
97 &nbsp; &nbsp; &nbsp; &nbsp; case b.NailsDriven &gt; b.NailsNeeded:<br />
98 &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; c.Unfasten(<b>dp</b>, nailSupply, b)<br />
99 &nbsp; &nbsp; &nbsp; &nbsp; }<br />
100 &nbsp; &nbsp; }<br />
101 }
</div>
<br />
In listing 8, we see the declaration and implementation of the <span style="font-family: &quot;courier new&quot; , &quot;courier&quot; , monospace;">ProcessBoards</span> method. This method accepts as its first parameter only values that implement both the <span style="font-family: &quot;courier new&quot; , &quot;courier&quot; , monospace;">NailDriver</span> and <span style="font-family: &quot;courier new&quot; , &quot;courier&quot; , monospace;">NailPuller</span> interface:<br />
<br />
<span style="background-color: #eeeeee;">&nbsp; <b>Listing 9</b> &nbsp;</span>
<br />
<div style="background-color: #efefef; font-family: 'Courier New', Courier, monospace; font-size: small; overflow-x: scroll; padding: 10px; white-space: nowrap;">
87 func (c Contractor) ProcessBoards(<b>dp NailDrivePuller</b>, nailSupply &#42;int, boards []Board) {
</div>
<br />
Listing 9 shows how the method is declaring the exact behavior it needs via the <span style="font-family: &quot;courier new&quot; , &quot;courier&quot; , monospace;">NailDrivePuller</span> interface type. We want our API’s to specify only the behaviors that are required or are being used. The <span style="font-family: &quot;courier new&quot; , &quot;courier&quot; , monospace;">Fasten</span> and <span style="font-family: &quot;courier new&quot; , &quot;courier&quot; , monospace;">Unfasten</span> methods require a value that implement a single act of behavior but <span style="font-family: &quot;courier new&quot; , &quot;courier&quot; , monospace;">ProcessBoards</span> requires a value that implements two behaviors at the same time:<br />
<br />
<span style="background-color: #eeeeee;">&nbsp; <b>Listing 10</b> &nbsp;</span>
<br />
<div style="background-color: #efefef; font-family: 'Courier New', Courier, monospace; font-size: small; overflow-x: scroll; padding: 10px; white-space: nowrap;">
93 &nbsp; &nbsp; &nbsp; &nbsp; switch {<br />
94 &nbsp; &nbsp; &nbsp; &nbsp; case b.NailsDriven &lt; b.NailsNeeded:<br />
95 &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; c.Fasten(<b>dp</b>, nailSupply, b)<br />
96<br />
97 &nbsp; &nbsp; &nbsp; &nbsp; case b.NailsDriven &gt; b.NailsNeeded:<br />
98 &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; c.Unfasten(<b>dp</b>, nailSupply, b)<br />
99 &nbsp; &nbsp; &nbsp; &nbsp; }</div>
<br />
Listing 10 shows a piece of the implementation of <span style="font-family: &quot;courier new&quot; , &quot;courier&quot; , monospace;">ProcessBoards</span> and how the value of interface type <span style="font-family: &quot;courier new&quot; , &quot;courier&quot; , monospace;">NailDrivePuller</span> is used in the method calls to <span style="font-family: &quot;courier new&quot; , &quot;courier&quot; , monospace;">Fasten</span> and <span style="font-family: &quot;courier new&quot; , &quot;courier&quot; , monospace;">Unfasten</span>. When the call to <span style="font-family: &quot;courier new&quot; , &quot;courier&quot; , monospace;">Fasten</span> is made on line 95, the <span style="font-family: &quot;courier new&quot; , &quot;courier&quot; , monospace;">NailDrivePuller</span> interface value is passed into the method as an interface value of type <span style="font-family: &quot;courier new&quot; , &quot;courier&quot; , monospace;">NailDriver</span>. Let’s look at the declaration of the <span style="font-family: &quot;courier new&quot; , &quot;courier&quot; , monospace;">Fasten</span> method once again:<br />
<br />
<span style="background-color: #eeeeee;">&nbsp; <b>Listing 11</b> &nbsp;</span>
<br />
<div style="background-color: #efefef; font-family: 'Courier New', Courier, monospace; font-size: small; overflow-x: scroll; padding: 10px; white-space: nowrap;">
73 func (Contractor) Fasten(<b>d NailDriver</b>, nailSupply &#42;int, b &#42;Board) {
</div>
<br />
Notice the <span style="font-family: &quot;courier new&quot; , &quot;courier&quot; , monospace;">Fasten</span> method requires a value of interface type <span style="font-family: &quot;courier new&quot; , &quot;courier&quot; , monospace;">NailDriver</span> and we are passing a value of interface type <span style="font-family: &quot;courier new&quot; , &quot;courier&quot; , monospace;">NailDrivePuller</span>. This is possible because the compiler knows that any concrete type value that can be stored inside a <span style="font-family: &quot;courier new&quot; , &quot;courier&quot; , monospace;">NailDrivePuller</span> interface value must also implement the <span style="font-family: &quot;courier new&quot; , &quot;courier&quot; , monospace;">NailDriver</span> interface. Therefore, the compiler accepts the method call and the assignment between these two interface type values.<br />
<br />
The same is true for the method call to <span style="font-family: &quot;courier new&quot; , &quot;courier&quot; , monospace;">Unfasten</span>:<br />
<br />
<span style="background-color: #eeeeee;">&nbsp; <b>Listing 12</b> &nbsp;</span>
<br />
<div style="background-color: #efefef; font-family: 'Courier New', Courier, monospace; font-size: small; overflow-x: scroll; padding: 10px; white-space: nowrap;">
80 func (Contractor) Unfasten(<b>p NailPuller</b>, nailSupply &#42;int, b &#42;Board) 81 {
</div>
<br />
The compiler knows that any concrete type value that is stored inside an interface value of type <span style="font-family: &quot;courier new&quot; , &quot;courier&quot; , monospace;">NailDriverPuller</span> also implements the <span style="font-family: &quot;courier new&quot; , &quot;courier&quot; , monospace;">NailPuller</span> interface. Therefore, passing an interface value of type <span style="font-family: &quot;courier new&quot; , &quot;courier&quot; , monospace;">NailDriverPuller</span> is assignable to an interface value of type <span style="font-family: &quot;courier new&quot; , &quot;courier&quot; , monospace;">NailPuller</span>. Because there is a static relationship between these two interfaces, the compiler is able to forego generating a runtime type assertion and instead generate an interface conversion.<br />
<br />
With the contractor in place, we can now declare a new type that declares a toolbox for use by a contractor:<br />
<br />
<span style="background-color: #eeeeee;">&nbsp; <b>Listing 13</b> &nbsp;</span>
<br />
<div style="background-color: #efefef; font-family: 'Courier New', Courier, monospace; font-size: small; overflow-x: scroll; padding: 10px; white-space: nowrap;">
105 // Toolbox can contains any number of tools.<br />
106 type Toolbox struct {<br />
107 &nbsp; &nbsp; NailDriver<br />
108 &nbsp; &nbsp; NailPuller<br />
109<br />
110 &nbsp; &nbsp; nails int<br />
111 }
</div>
<br />
Every good contractor has a toolbox and in listing 13 we have the declaration of a toolbox. The <span style="font-family: &quot;courier new&quot; , &quot;courier&quot; , monospace;">Toolbox</span> is a struct type that embeds on line 107 an interface value of type <span style="font-family: &quot;courier new&quot; , &quot;courier&quot; , monospace;">NailDriver</span> and on line 108 an interface value of type <span style="font-family: &quot;courier new&quot; , &quot;courier&quot; , monospace;">NailPuller</span>. Then on line 110, a supply of nails is declared via the <span style="font-family: &quot;courier new&quot; , &quot;courier&quot; , monospace;">nails</span> field.<br />
<br />
When embedding a type inside of another type, it is good to think of the new type as the outer type and the type being embedded as the inner type. This is important because then you can see the relationship that embedding a type creates.<br />
<br />
Any type that is embeded always exists as an inner value, inside the outer type value. It never loses its identity and is always there. However, thanks to inner type promotion, everything that is declared within the inner type is promoted to the outer type. This means through a value of the outer type, we can access any field or method associated with the inner type value directly based on the rules of exporting.<br />
<br />
Let’s look at an example of this:<br />
<br />
<span style="background-color: #eeeeee;">&nbsp; <b>Listing 14</b> &nbsp;</span>
<br />
<div style="background-color: #efefef; font-family: 'Courier New', Courier, monospace; font-size: small; overflow-x: scroll; padding: 10px; white-space: nowrap;">
01 package main<br />
02<br />
03 import &quot;fmt&quot;<br />
04 <br />
05 // user defines a user in the program.<br />
06 type user struct {<br />
07 &nbsp; &nbsp; name &nbsp;string<br />
08 &nbsp; &nbsp; email string<br />
09 }<br />
10<br />
11 // notify implements a method that can be called via<br />
12 // a pointer of type user.<br />
13 func (u &#42;user) notify() {<br />
14 &nbsp; &nbsp; fmt.Printf(&quot;Sending user email To %s&lt;%s&gt;\n&quot;,<br />
15 &nbsp; &nbsp; &nbsp; &nbsp; u.name,<br />
16 &nbsp; &nbsp; &nbsp; &nbsp; u.email)<br />
17 }
</div>
<br />
In listing 14, we have the declaration of a type named <span style="font-family: &quot;courier new&quot; , &quot;courier&quot; , monospace;">user</span>. This type contains two <span style="font-family: &quot;courier new&quot; , &quot;courier&quot; , monospace;">string</span> fields and a method named <span style="font-family: &quot;courier new&quot; , &quot;courier&quot; , monospace;">notify</span>. Now, let’s embed this type into another type:<br />
<br />
<span style="background-color: #eeeeee;">&nbsp; <b>Listing 15</b> &nbsp;</span>
<br />
<div style="background-color: #efefef; font-family: 'Courier New', Courier, monospace; font-size: small; overflow-x: scroll; padding: 10px; white-space: nowrap;">
19 // admin represents an admin user with privileges.<br />
20 type admin struct {<br />
21 &nbsp; &nbsp; user &nbsp;// Embedded Type<br />
22 &nbsp; &nbsp; level string<br />
23 }
</div>
<br />
Now we can see the relationship between the inner type and outer type in listing 15. The <span style="font-family: &quot;courier new&quot; , &quot;courier&quot; , monospace;">user</span> type is now an inner type of <span style="font-family: &quot;courier new&quot; , &quot;courier&quot; , monospace;">admin</span>, the outer type. This means that we can call the <span style="font-family: &quot;courier new&quot; , &quot;courier&quot; , monospace;">notify</span> method directly from a value of type <span style="font-family: &quot;courier new&quot; , &quot;courier&quot; , monospace;">admin</span> thanks to inner type promotion. But since the inner type value also exists, in and of itself, we can also call the <span style="font-family: &quot;courier new&quot; , &quot;courier&quot; , monospace;">notify</span> method directly from the inner type value:<br />
<br />
<span style="background-color: #eeeeee;">&nbsp; <b>Listing 16</b> &nbsp;</span>
<br />
<div style="background-color: #efefef; font-family: 'Courier New', Courier, monospace; font-size: small; overflow-x: scroll; padding: 10px; white-space: nowrap;">
25 // main is the entry point for the application.<br />
26 func main() {<br />
27 &nbsp; &nbsp; // Create an admin user.<br />
28 &nbsp; &nbsp; ad := admin{<br />
29 &nbsp; &nbsp; &nbsp; &nbsp; user: user{<br />
30 &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; name: &nbsp;&quot;john smith&quot;,<br />
31 &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; email: &quot;john@yahoo.com&quot;,<br />
32 &nbsp; &nbsp; &nbsp; &nbsp; },<br />
33 &nbsp; &nbsp; &nbsp; &nbsp; level: &quot;super&quot;,<br />
34 &nbsp; &nbsp; }<br />
35<br />
36 &nbsp; &nbsp; // We can access the inner type's method directly.<br />
37 &nbsp; &nbsp; ad.user.notify()<br />
38<br />
39 &nbsp; &nbsp; // The inner type's method is promoted to the outer type.<br />
40 &nbsp; &nbsp; ad.notify()<br />
41 }
</div>
<br />
Listing 16 shows how a value of the outer type <span style="font-family: &quot;courier new&quot; , &quot;courier&quot; , monospace;">admin</span> is created using a struct literal on line 28. Inside the struct literal a second struct literal is used to create and initialize a value for the inner type <span style="font-family: &quot;courier new&quot; , &quot;courier&quot; , monospace;">user</span>. With a value of type <span style="font-family: &quot;courier new&quot; , &quot;courier&quot; , monospace;">admin</span> in place, we can call the <span style="font-family: &quot;courier new&quot; , &quot;courier&quot; , monospace;">notify</span> method directly from the inner type value on line 37 or through the outer type value on line 40.<br />
<br />
One last thing, this is neither subtyping nor subclassing. Values of type <span style="font-family: &quot;courier new&quot; , &quot;courier&quot; , monospace;">admin</span> can’t be used as values of type <span style="font-family: &quot;courier new&quot; , &quot;courier&quot; , monospace;">user</span>. Values of type <span style="font-family: &quot;courier new&quot; , &quot;courier&quot; , monospace;">admin</span> are only values of type <span style="font-family: &quot;courier new&quot; , &quot;courier&quot; , monospace;">admin</span> and values of type <span style="font-family: &quot;courier new&quot; , &quot;courier&quot; , monospace;">user</span> are only values of type <span style="font-family: &quot;courier new&quot; , &quot;courier&quot; , monospace;">user</span>. Thanks to inner type promotion, the fields and methods of the inner type can be accessed directly through a value of the outer type.<br />
<br />
Now back to our toolbox:<br />
<br />
<span style="background-color: #eeeeee;">&nbsp; <b>Listing 17</b> &nbsp;</span>
<br />
<div style="background-color: #efefef; font-family: 'Courier New', Courier, monospace; font-size: small; overflow-x: scroll; padding: 10px; white-space: nowrap;">
105 // Toolbox can contains any number of tools.<br />
106 type Toolbox struct {<br />
107 &nbsp; &nbsp; NailDriver<br />
108 &nbsp; &nbsp; NailPuller<br />
109<br />
110 &nbsp; &nbsp; nails int<br />
111 }
</div>
<br />
We have not embedded a struct type into our <span style="font-family: &quot;courier new&quot; , &quot;courier&quot; , monospace;">Toolbox</span> but two interface types. This means any concrete type value that implements the <span style="font-family: &quot;courier new&quot; , &quot;courier&quot; , monospace;">NailDriver</span> interface can be assigned as the inner type value for the <span style="font-family: &quot;courier new&quot; , &quot;courier&quot; , monospace;">NailDriver</span> embedded interface type. The same holds true for the embedded <span style="font-family: &quot;courier new&quot; , &quot;courier&quot; , monospace;">NailPuller</span> interface type.<br />
<br />
Once a concrete type is assigned, the <span style="font-family: &quot;courier new&quot; , &quot;courier&quot; , monospace;">Toolbox</span> is then guaranteed to implement this behavior. Even more, since the toolbox embeds both a <span style="font-family: &quot;courier new&quot; , &quot;courier&quot; , monospace;">NailDriver</span> and <span style="font-family: &quot;courier new&quot; , &quot;courier&quot; , monospace;">NailPuller</span> interface type, this means a <span style="font-family: &quot;courier new&quot; , &quot;courier&quot; , monospace;">Toolbox</span> also implements the <span style="font-family: &quot;courier new&quot; , &quot;courier&quot; , monospace;">NailDrivePuller</span> interface as well:<br />
<br />
<span style="background-color: #eeeeee;">&nbsp; <b>Listing 18</b> &nbsp;</span>
<br />
<div style="background-color: #efefef; font-family: 'Courier New', Courier, monospace; font-size: small; overflow-x: scroll; padding: 10px; white-space: nowrap;">
31 &nbsp; &nbsp; NailDrivePuller interface {<br />
32 &nbsp; &nbsp; &nbsp; &nbsp; NailDriver<br />
33 &nbsp; &nbsp; &nbsp; &nbsp; NailPuller<br />
34 &nbsp; &nbsp; }</div>
<br />
In listing 18 we see the declaration of the <span style="font-family: &quot;courier new&quot; , &quot;courier&quot; , monospace;">NailDrivePuller</span> interface again. Embedding interface types takes the idea of inner type promotion and interface compliance to the next level.<br />
<br />
Now we are ready to put everything together by implementing the <span style="font-family: &quot;courier new&quot; , &quot;courier&quot; , monospace;">main</span> function:<br />
<br />
<span style="background-color: #eeeeee;">&nbsp; <b>Listing 19</b> &nbsp;</span>
<br />
<div style="background-color: #efefef; font-family: 'Courier New', Courier, monospace; font-size: small; overflow-x: scroll; padding: 10px; white-space: nowrap;">
115 // main is the entry point for the application.<br />
116 func main() {<br />
117 &nbsp; &nbsp; // Inventory of old boards to remove, and the new boards<br />
118 &nbsp; &nbsp; // that will replace them.<br />
119 &nbsp; &nbsp; boards := []Board{<br />
120 &nbsp; &nbsp; &nbsp; &nbsp; // Rotted boards to be removed.<br />
121 &nbsp; &nbsp; &nbsp; &nbsp; {NailsDriven: 3},<br />
122 &nbsp; &nbsp; &nbsp; &nbsp; {NailsDriven: 1},<br />
123 &nbsp; &nbsp; &nbsp; &nbsp; {NailsDriven: 6},<br />
124<br />
125 &nbsp; &nbsp; &nbsp; &nbsp; // Fresh boards to be fastened.<br />
126 &nbsp; &nbsp; &nbsp; &nbsp; {NailsNeeded: 6},<br />
127 &nbsp; &nbsp; &nbsp; &nbsp; {NailsNeeded: 9},<br />
128 &nbsp; &nbsp; &nbsp; &nbsp; {NailsNeeded: 4},<br />
129 &nbsp; &nbsp; }</div>
<br />
The <span style="font-family: &quot;courier new&quot; , &quot;courier&quot; , monospace;">main</span> function starts out on line 116 in listing 19. Here we create a slice of boards and specify what each board needs in terms of nails. Next, we create our toolbox:<br />
<br />
<span style="background-color: #eeeeee;">&nbsp; <b>Listing 20</b> &nbsp;</span>
<br />
<div style="background-color: #efefef; font-family: 'Courier New', Courier, monospace; font-size: small; overflow-x: scroll; padding: 10px; white-space: nowrap;">
131 &nbsp; &nbsp; // Fill a toolbox.<br />
132 &nbsp; &nbsp; tb := Toolbox{<br />
133 &nbsp; &nbsp; &nbsp; &nbsp; NailDriver: Mallet{},<br />
134 &nbsp; &nbsp; &nbsp; &nbsp; NailPuller: Crowbar{},<br />
135 &nbsp; &nbsp; &nbsp; &nbsp; nails: &nbsp; &nbsp; &nbsp;10,<br />
136 &nbsp; &nbsp; }<br />
137<br />
138 &nbsp; &nbsp; // Display the current state of our toolbox and boards.<br />
139 &nbsp; &nbsp; displayState(&amp;tb, boards)</div>
<br />
In listing 20, we create our <span style="font-family: &quot;courier new&quot; , &quot;courier&quot; , monospace;">Toolbox</span> value and create a value of the struct type <span style="font-family: &quot;courier new&quot; , &quot;courier&quot; , monospace;">Mallet</span> and assign it to the inner interface type <span style="font-family: &quot;courier new&quot; , &quot;courier&quot; , monospace;">NailDriver</span>. Then we create a value of struct type <span style="font-family: &quot;courier new&quot; , &quot;courier&quot; , monospace;">Crowbar</span> and assign it to the inner interface type <span style="font-family: &quot;courier new&quot; , &quot;courier&quot; , monospace;">NailPuller</span>. Finally, we add 10 nails to the toolbox.<br />
<br />
Now let’s create the contractor and process some boards:<br />
<br />
<span style="background-color: #eeeeee;">&nbsp; <b>Listing 21</b> &nbsp;</span>
<br />
<div style="background-color: #efefef; font-family: 'Courier New', Courier, monospace; font-size: small; overflow-x: scroll; padding: 10px; white-space: nowrap;">
141 &nbsp; &nbsp; // Hire a contractor and put our contractor to work.<br />
142 &nbsp; &nbsp; var c Contractor<br />
143 &nbsp; &nbsp; c.ProcessBoards(<b>&amp;tb</b>, &amp;tb.nails, boards)<br />
144<br />
145 &nbsp; &nbsp; // Display the new state of our toolbox and boards.<br />
146 &nbsp; &nbsp; displayState(&amp;tb, boards)<br />
147 }
</div>
<br />
On line 142 in listing 21 we create a value of type <span style="font-family: &quot;courier new&quot; , &quot;courier&quot; , monospace;">Contractor</span> and call the <span style="font-family: &quot;courier new&quot; , &quot;courier&quot; , monospace;">ProcessBoard</span> method against it on line 143. Let’s look at the declaration of the <span style="font-family: &quot;courier new&quot; , &quot;courier&quot; , monospace;">ProcessBoards</span> method once more:<br />
<br />
<span style="background-color: #eeeeee;">&nbsp; <b>Listing 22</b> &nbsp;</span>
<br />
<div style="background-color: #efefef; font-family: 'Courier New', Courier, monospace; font-size: small; overflow-x: scroll; padding: 10px; white-space: nowrap;">
87 func (c Contractor) ProcessBoards(<b>dp NailDrivePuller</b>, nailSupply &#42;int, boards []Board) {
</div>
<br />
Once again, we see how the <span style="font-family: &quot;courier new&quot; , &quot;courier&quot; , monospace;">ProcessBoard</span> method takes as its first parameter any concrete type value that implements the <span style="font-family: &quot;courier new&quot; , &quot;courier&quot; , monospace;">NailDrivePuller</span> interface. Thanks to the type embedding of the <span style="font-family: &quot;courier new&quot; , &quot;courier&quot; , monospace;">NailDriver</span> and <span style="font-family: &quot;courier new&quot; , &quot;courier&quot; , monospace;">NailPuller</span> interface types inside the <span style="font-family: &quot;courier new&quot; , &quot;courier&quot; , monospace;">Toolbox</span> struct type, a pointer of type <span style="font-family: &quot;courier new&quot; , &quot;courier&quot; , monospace;">Toolbox</span> implements the <span style="font-family: &quot;courier new&quot; , &quot;courier&quot; , monospace;">NailDrivePuller</span> interface and can be passed through.<br />
<br />
<i><b>Note</b>: The <span style="font-family: &quot;courier new&quot; , &quot;courier&quot; , monospace;">Mallet</span> and <span style="font-family: &quot;courier new&quot; , &quot;courier&quot; , monospace;">Crowbar</span> types implement their respective interfaces with value receivers. Based on the rules for <a href="https://www.ardanlabs.com/blog/2014/05/methods-interfaces-and-embedded-types.html" target="_blank">Method Sets</a>, both values and pointers then satisfy the interface. This is why we can create and assign values of our concrete type values to the embedded interface type values. The call to <span style="font-family: &quot;courier new&quot; , &quot;courier&quot; , monospace;">ProcessBoards</span> in listing 21 on line 143 is using the address of the <span style="font-family: &quot;courier new&quot; , &quot;courier&quot; , monospace;">Toolbox</span> value because we want to share a single <span style="font-family: &quot;courier new&quot; , &quot;courier&quot; , monospace;">Toolbox</span>. However, a value of type <span style="font-family: &quot;courier new&quot; , &quot;courier&quot; , monospace;">Toolbox</span> also satisfies the interface. If the concrete types used pointer receivers to implement the interfaces, then only pointers would have satisfied the interface.</i><br />
<br />
To be complete, here is the implementation of the <span style="font-family: &quot;courier new&quot; , &quot;courier&quot; , monospace;">displayState</span> function:<br />
<br />
<span style="background-color: #eeeeee;">&nbsp; <b>Listing 23</b> &nbsp;</span>
<br />
<div style="background-color: #efefef; font-family: 'Courier New', Courier, monospace; font-size: small; overflow-x: scroll; padding: 10px; white-space: nowrap;">
149 // displayState provide information about all the boards.<br />
150 func displayState(tb &#42;Toolbox, boards []Board) {<br />
151 &nbsp; &nbsp; fmt.Printf(&quot;Box: %#v\n&quot;, tb)<br />
152 &nbsp; &nbsp; fmt.Println(&quot;Boards:&quot;)<br />
153<br />
154 &nbsp; &nbsp; for _, b := range boards {<br />
155 &nbsp; &nbsp; &nbsp; &nbsp; fmt.Printf(&quot;\t%+v\n&quot;, b)<br />
156 &nbsp; &nbsp; }<br />
157<br />
158 &nbsp; &nbsp; fmt.Println()<br />
159 }
</div>
<br />
In conclusion, this example has tried to show how composition can be applied and the things to think about when writing your code. How you declare your types and how they can work together is very important. Here is a summary of the things we touch upon in the post:<br />
<br />
&#42; Declare the set of behaviors as discrete interface types first. Then think about how they can be composed into a larger set of behaviors.<br />
<br />
&#42; Make sure each function or method is very specific about the interface types they accept. Only accept interface types for the behavior you are using in that function or method. This will help dictate the larger interface types that are required.<br />
<br />
&#42; Think about embedding as an inner and outer type relationship. Remember that through inner type promotion, everything that is declared in the inner type is promoted to the outer type. However, the inner type value exists in and of itself as is always accessible based on the rules for exporting.<br />
<br />
&#42; Type embedding is not subtyping nor subclassing. Concrete type values represent a single type and can’t be assigned based on any embedded relationship.<br />
<br />
&#42; The compiler can arrange interface conversions between related interface values.&nbsp;Interface conversion, at compile time, doesn't care about concrete types - it knows what to do merely based on the interface types themselves, not the implementing concrete values they could contain.<br />
<br />
<i>I would like to thank <a href="https://twitter.com/kevingillette" target="_blank">Kevin Gillette</a> for working with me on the code and post and <a href="https://twitter.com/billhathaway" target="_blank">Bill Hathaway</a>&nbsp;for helping with reviews and edits to the post.</i>
