Golang实现状态设计模式的尝试与探讨

Golang实现状态设计模式的尝试与探讨 你好,我是那种不知道要写什么代码的人,所以我想尝试一下状态设计模式……虽然写出了一些东西,但离真正的设计模式还很远。这没关系,我不理解的是为什么程序没有读取控制台的第二个输入,而这个输入是我在计算器结构的 SetValues() 方法中要求它做的。我应该使用切片读取器的方法吗? [如果格式不好,我表示歉意。]

包中的代码:

package vect

import "fmt"
import "bufio"
import "os"

type Values struct{
	a,b,c int
}

func (v *Values) Loadval(a,b,c int) {
	v.a = a
	v.b= b
	v.c = c
}

func (v Values) Print(){
	fmt.Println(v.a,v.b,v.c)
}

type Programstate interface{
	Load(v Values)
	Display()
	Calculate()
	Control() (bool,bool)
}


type Additor struct{
	val Values
	calc *Programstate
}

func (c *Additor) Load(v Values) {
	c.val.a = v.a
	c.val.b = v.b
	c.val.c = v.c
}

func (c *Additor) Calculate(){
	c.val.c = c.val.a + c.val.b
}

func (c Additor) Display() {
	fmt.Println(c.val)
}

func (c Additor) Control() (bool,bool){
	fmt.Println("New calculation? (y/n)")
	fmt.Println("No entry for ending program")
	reader := bufio.NewReader(os.Stdin)
	text,  _ ,_:= reader.ReadRune()
	fmt.Println(text)
	if text == 'y'{
		return true, true
	}
	if text == 'n'{
		return false, true
	}
	return false, false
}

type Calculator struct{
	calc Programstate
	add Additor
}


func (c *Calculator) StartUp(){
	c.calc = &c.add
}
	

func (c *Calculator) Switch() bool{
	fmt.Println("What calculation do you want to do next?")
	fmt.Println("a for addition")
	reader := bufio.NewReader(os.Stdin)
	text,  _ ,_:= reader.ReadRune()
	if text == 'a'{
		c.calc =  &c.add
		return true
	}	
	return false
}

func (c *Calculator) SetValues() {
	var val Values
	fmt.Println("What first value do you want to calculate?")
	reader := bufio.NewReader(os.Stdin)
	text , _ , _ := reader.ReadRune()
	val.a = int(text -'0')
	fmt.Println("What second value do you want to calculate?")
	text2 , _ , _ := reader.ReadRune()
	val.b = int(text2 - '0')
	fmt.Println("Your two values are:", val.a, val.b)
	c.calc.Load(val)
}

func (c Calculator) Dostuff()  bool {
	c.calc.Calculate()
	c.calc.Display()
	i , _ := c.calc.Control()
	return i
}

主函数中的代码

package main

import(
	"vectors"
)

func main(){
	var C vect.Calculator
	C.StartUp()
	i := true
	for i{
		C.SetValues()
		i=C.Dostuff()
		if i == true{
			i=C.Switch()
		}
		
	}
}

更多关于Golang实现状态设计模式的尝试与探讨的实战教程也可以访问 https://www.itying.com/category-94-b0.html

1 回复

更多关于Golang实现状态设计模式的尝试与探讨的实战系列教程也可以访问 https://www.itying.com/category-94-b0.html


你的问题在于使用了 ReadRune() 来读取控制台输入,这个方法只读取单个字符(包括换行符)。当你在 SetValues() 中读取第一个数字后,换行符仍然留在输入缓冲区中,导致第二个 ReadRune() 直接读取了换行符而不是你输入的数字。

以下是修复后的 SetValues() 方法,使用 ReadString('\n') 来完整读取一行输入:

func (c *Calculator) SetValues() {
    var val Values
    reader := bufio.NewReader(os.Stdin)
    
    fmt.Println("What first value do you want to calculate?")
    input1, _ := reader.ReadString('\n')
    fmt.Println("What second value do you want to calculate?")
    input2, _ := reader.ReadString('\n')
    
    // 转换字符串为整数
    val.a = int(input1[0] - '0')
    val.b = int(input2[0] - '0')
    
    fmt.Println("Your two values are:", val.a, val.b)
    c.calc.Load(val)
}

同时,Control() 方法也需要类似修改:

func (c Additor) Control() (bool, bool) {
    fmt.Println("New calculation? (y/n)")
    fmt.Println("No entry for ending program")
    reader := bufio.NewReader(os.Stdin)
    input, _ := reader.ReadString('\n')
    
    if len(input) > 0 {
        text := input[0]
        if text == 'y' {
            return true, true
        }
        if text == 'n' {
            return false, true
        }
    }
    return false, false
}

Switch() 方法也需要相应修改:

func (c *Calculator) Switch() bool {
    fmt.Println("What calculation do you want to do next?")
    fmt.Println("a for addition")
    reader := bufio.NewReader(os.Stdin)
    input, _ := reader.ReadString('\n')
    
    if len(input) > 0 && input[0] == 'a' {
        c.calc = &c.add
        return true
    }
    return false
}

关于状态设计模式的实现,你的代码结构可以进一步优化。这里是一个更符合状态模式的结构示例:

type State interface {
    Handle(c *Context)
}

type Context struct {
    state State
    values Values
}

func (c *Context) SetState(state State) {
    c.state = state
}

func (c *Context) Request() {
    c.state.Handle(c)
}

type AdditionState struct{}

func (s *AdditionState) Handle(c *Context) {
    fmt.Printf("Calculating addition: %d + %d = %d\n", 
        c.values.a, c.values.b, c.values.a + c.values.b)
    c.values.c = c.values.a + c.values.b
}

这样修改后,你的程序应该能正确读取控制台的多个输入了。

回到顶部