Go言語入門 / golang 入門 デザインパターンCommand

f:id:nasust:20161122141513p:plain The Go gopher was designed by Renee French. (http://reneefrench.blogspot.com/) CC3.0

こんにちはnasustです。 TechScoreの「 22.Commandパターン | TECHSCORE(テックスコア) 」を参考にGo言語 / golangでCommandパターンを実装してみました。

TechScoreではCommandはAbstractクラスでしたが、Go言語 / golangでは構造体の埋め込みとinterface型で実現しています。

package main

import "fmt"

type Beaker struct {
    water  float64
    salt   float64
    melted bool
}

func NewBeaker(water, salt float64) *Beaker {
    beaker := &Beaker{
        water: water,
        salt:  salt,
    }
    return beaker
}

func (self *Beaker) AddSalt(salt float64) {
    self.salt += salt
}

func (self *Beaker) AddWater(water float64) {
    self.water += water
}

func (self *Beaker) Mix() {
    if (self.salt/(self.salt+self.water))*100 < 26.4 {
        self.melted = true
    } else {
        self.melted = false
    }
}

func (self *Beaker) GetSalt() float64 {
    return self.salt
}

func (self *Beaker) GetWater() float64 {
    return self.water
}

func (self *Beaker) IsMelted() bool {
    return self.melted
}

func (self *Beaker) Note() {
    fmt.Println("Water: ", self.water, "g")
    fmt.Println("Salt: ", self.salt, "g")
    fmt.Println("Concentration: ", (self.salt/(self.water+self.salt))*100, "%")

}

type Command interface {
    Execute()
}

type BeakerSetter struct {
    beaker *Beaker
}

type AddSaltCommand struct {
    BeakerSetter
}

func (self *AddSaltCommand) Execute() {
    for self.beaker.IsMelted() {
        self.beaker.AddSalt(1)
        self.beaker.Mix()
    }
    self.beaker.Note()
}

type AddWaterCommand struct {
    BeakerSetter
}

func (self *AddWaterCommand) Execute() {
    for !self.beaker.IsMelted() {
        self.beaker.AddWater(10)
        self.beaker.Mix()
    }
    self.beaker.Note()
}

type MakeSaltWaterCommand struct {
    BeakerSetter
}

func (self *MakeSaltWaterCommand) Execute() {
    self.beaker.Mix()
    self.beaker.Note()
}

type MakeSaltWaterAddSaltCommand struct {
    BeakerSetter
    commands []Command
}

func NewMakeSaltWaterAddSaltCommand() *MakeSaltWaterAddSaltCommand {
    return &MakeSaltWaterAddSaltCommand{
        commands: []Command{},
    }
}

func (self *MakeSaltWaterAddSaltCommand) Execute() {
    for _, command := range self.commands {
        command.Execute()
    }
    self.beaker.Note()
}

func (self *MakeSaltWaterAddSaltCommand) AddCommand(command Command) {
    self.commands = append(self.commands, command)
}

func main() {
    makeSaltWater := &MakeSaltWaterCommand{}
    addSalt := &AddSaltCommand{}
    makeSaltWaterAddSalt := NewMakeSaltWaterAddSaltCommand()

    beaker := NewBeaker(90, 10)
    makeSaltWater.beaker = beaker
    addSalt.beaker = beaker
    makeSaltWaterAddSalt.beaker = beaker

    makeSaltWaterAddSalt.AddCommand(makeSaltWater)
    makeSaltWaterAddSalt.AddCommand(addSalt)

    makeSaltWaterAddSalt.Execute()
}

Go言語 / golang 入門 目次に戻る

広告を非表示にする