Skip to content

Commit

Permalink
Adding new listings for chapter 10.
Browse files Browse the repository at this point in the history
  • Loading branch information
William Kennedy committed Mar 18, 2016
1 parent dea4814 commit d849e6b
Show file tree
Hide file tree
Showing 4 changed files with 436 additions and 0 deletions.
97 changes: 97 additions & 0 deletions chapter10/listing01/listing01.go
Original file line number Diff line number Diff line change
@@ -0,0 +1,97 @@
// Sample program demonstrating struct composition.
package main

import "fmt"

// Board represents a surface we can work on.
type Board struct {
NailsNeeded int
NailsDriven int
}

// =============================================================================

// Mallet is a tool that pounds in nails.
type Mallet struct{}

// DriveNail pounds a nail into the specified board.
func (Mallet) DriveNail(nailSupply *int, b *Board) {
*nailSupply--
b.NailsDriven++
fmt.Println("Mallet: pounded nail into the board.")
}

// Crowbar is a tool that removes nails.
type Crowbar struct{}

// PullNail yanks a nail out of the specified board.
func (Crowbar) PullNail(nailSupply *int, b *Board) {
b.NailsDriven--
*nailSupply++
fmt.Println("Crowbar: yanked nail out of the board.")
}

// =============================================================================

// Toolbox can contains a Mallet and a Crowbar.
type Toolbox struct {
Mallet
Crowbar

nails int
}

// =============================================================================

// Contractor carries out the task of securing boards.
type Contractor struct{}

// Fasten will drive nails into a board.
func (Contractor) Fasten(m Mallet, nailSupply *int, b *Board) {
for b.NailsDriven < b.NailsNeeded {
m.DriveNail(nailSupply, b)
}
}

// Unfasten will remove nails from a board.
func (Contractor) Unfasten(cb Crowbar, nailSupply *int, b *Board) {
for b.NailsDriven > b.NailsNeeded {
cb.PullNail(nailSupply, b)
}
}

// ProcessBoards works against boards.
func (c Contractor) ProcessBoards(tb *Toolbox, nailSupply *int, boards []Board) {
for i := range boards {
b := &boards[i]

fmt.Printf("Contractor: examining board #%d: %+v\n", i+1, b)

switch {
case b.NailsDriven < b.NailsNeeded:
c.Fasten(tb.Mallet, nailSupply, b)

case b.NailsDriven > b.NailsNeeded:
c.Unfasten(tb.Crowbar, nailSupply, b)
}
}
}

// =============================================================================

// main is the entry point for the application.
func main() {
boards := []Board{
{NailsDriven: 3},
{NailsNeeded: 2},
}

tb := Toolbox{
Mallet: Mallet{},
Crowbar: Crowbar{},
nails: 10,
}

var c Contractor
c.ProcessBoards(&tb, &tb.nails, boards)
}
109 changes: 109 additions & 0 deletions chapter10/listing02/listing02.go
Original file line number Diff line number Diff line change
@@ -0,0 +1,109 @@
// Sample program demonstrating decoupling with interfaces.
package main

import "fmt"

// Board represents a surface we can work on.
type Board struct {
NailsNeeded int
NailsDriven int
}

// =============================================================================

// NailDriver represents behavior to drive nails into a board.
type NailDriver interface {
DriveNail(nailSupply *int, b *Board)
}

// NailPuller represents behavior to remove nails into a board.
type NailPuller interface {
PullNail(nailSupply *int, b *Board)
}

// =============================================================================

// Mallet is a tool that pounds in nails.
type Mallet struct{}

// DriveNail pounds a nail into the specified board.
func (Mallet) DriveNail(nailSupply *int, b *Board) {
*nailSupply--
b.NailsDriven++
fmt.Println("Mallet: pounded nail into the board.")
}

// Crowbar is a tool that removes nails.
type Crowbar struct{}

// PullNail yanks a nail out of the specified board.
func (Crowbar) PullNail(nailSupply *int, b *Board) {
b.NailsDriven--
*nailSupply++
fmt.Println("Crowbar: yanked nail out of the board.")
}

// =============================================================================

// Toolbox can contains a Mallet and a Crowbar.
type Toolbox struct {
Mallet
Crowbar

nails int
}

// =============================================================================

// Contractor carries out the task of securing boards.
type Contractor struct{}

// Fasten will drive nails into a board.
func (Contractor) Fasten(d NailDriver, nailSupply *int, b *Board) {
for b.NailsDriven < b.NailsNeeded {
d.DriveNail(nailSupply, b)
}
}

// Unfasten will remove nails from a board.
func (Contractor) Unfasten(p NailPuller, nailSupply *int, b *Board) {
for b.NailsDriven > b.NailsNeeded {
p.PullNail(nailSupply, b)
}
}

// ProcessBoards works against boards.
func (c Contractor) ProcessBoards(tb *Toolbox, nailSupply *int, boards []Board) {
for i := range boards {
b := &boards[i]

fmt.Printf("Contractor: examining board #%d: %+v\n", i+1, b)

switch {
case b.NailsDriven < b.NailsNeeded:
c.Fasten(tb.Mallet, nailSupply, b)

case b.NailsDriven > b.NailsNeeded:
c.Unfasten(tb.Crowbar, nailSupply, b)
}
}
}

// =============================================================================

// main is the entry point for the application.
func main() {
boards := []Board{
{NailsDriven: 3},
{NailsNeeded: 2},
}

tb := Toolbox{
Mallet: Mallet{},
Crowbar: Crowbar{},
nails: 10,
}

var c Contractor
c.ProcessBoards(&tb, &tb.nails, boards)
}
115 changes: 115 additions & 0 deletions chapter10/listing03/listing03.go
Original file line number Diff line number Diff line change
@@ -0,0 +1,115 @@
// Sample program demonstrating interface composition.
package main

import "fmt"

// Board represents a surface we can work on.
type Board struct {
NailsNeeded int
NailsDriven int
}

// =============================================================================

// NailDriver represents behavior to drive nails into a board.
type NailDriver interface {
DriveNail(nailSupply *int, b *Board)
}

// NailPuller represents behavior to remove nails into a board.
type NailPuller interface {
PullNail(nailSupply *int, b *Board)
}

// NailDrivePuller represents behavior to drive and remove nails into a board.
type NailDrivePuller interface {
NailDriver
NailPuller
}

// =============================================================================

// Mallet is a tool that pounds in nails.
type Mallet struct{}

// DriveNail pounds a nail into the specified board.
func (Mallet) DriveNail(nailSupply *int, b *Board) {
*nailSupply--
b.NailsDriven++
fmt.Println("Mallet: pounded nail into the board.")
}

// Crowbar is a tool that removes nails.
type Crowbar struct{}

// PullNail yanks a nail out of the specified board.
func (Crowbar) PullNail(nailSupply *int, b *Board) {
b.NailsDriven--
*nailSupply++
fmt.Println("Crowbar: yanked nail out of the board.")
}

// =============================================================================

// Toolbox can contains a Mallet and a Crowbar.
type Toolbox struct {
Mallet
Crowbar

nails int
}

// =============================================================================

// Contractor carries out the task of securing boards.
type Contractor struct{}

// Fasten will drive nails into a board.
func (Contractor) Fasten(d NailDriver, nailSupply *int, b *Board) {
for b.NailsDriven < b.NailsNeeded {
d.DriveNail(nailSupply, b)
}
}

// Unfasten will remove nails from a board.
func (Contractor) Unfasten(p NailPuller, nailSupply *int, b *Board) {
for b.NailsDriven > b.NailsNeeded {
p.PullNail(nailSupply, b)
}
}

// ProcessBoards works against boards.
func (c Contractor) ProcessBoards(dp NailDrivePuller, nailSupply *int, boards []Board) {
for i := range boards {
b := &boards[i]

fmt.Printf("Contractor: examining board #%d: %+v\n", i+1, b)

switch {
case b.NailsDriven < b.NailsNeeded:
c.Fasten(dp, nailSupply, b)

case b.NailsDriven > b.NailsNeeded:
c.Unfasten(dp, nailSupply, b)
}
}
}

// =============================================================================

// main is the entry point for the application.
func main() {
boards := []Board{
{NailsDriven: 3},
{NailsNeeded: 2},
}

tb := Toolbox{
Mallet: Mallet{},
Crowbar: Crowbar{},
nails: 10,
}

var c Contractor
c.ProcessBoards(&tb, &tb.nails, boards)
}
Loading

0 comments on commit d849e6b

Please sign in to comment.