1.项目开发流程
2.项目需求说明
- 模拟实现基于文本界面的《家庭记账软件》
- 该软件能够记录家庭的收入,支出,并能够打印收支明细表
3.项目的界面
4.项目代码实现
实现基本功能(先使用面向过程,后面改成面向对象)
功能1:先完成可以显示主菜单,并且可以退出
思路分析:
更加给出的界面完成,主菜单的显示,当用户输入4时,就退出该程序
功能2:完成可以显示明细和登记收入的功能
思路分析:
- 因为需要显示明细,我们定义一个变量details string 来记录
- 还需要定义变量来记录余额(balance),每次收支的金额(money),每次收支的说明(note)
代码改进
用户输入4退出时,给出提示“你确定要退出吗?y/n”,必须输入正确的y/n,否则循环输入指令,直到输入y或者n
package main import ( "fmt" ) func main(){ //声明一个变量,保存接收用户输入的选项 key := "" // 声明一个变量,控制是否退出for loop := true // 定义账户的余额 [] balance := 10000.0 // 每次收支的金额 money := 0.0 // 每次收支的说明 note := "" // 定义一个变量,记录是否有收支的行为 flag := false // 收支的详情使用字符串来记录 //当有收支时,只需要对details进行拼接处理即可 details := "收入\t账户金额\t收入金额\t说 明" // 显示这个主菜单 for { fmt.Println("-------家庭收支记账软件---------") fmt.Println(" 1.收支明细") fmt.Println(" 2.登记收入") fmt.Println(" 3.登记支出") fmt.Println(" 4.退出软件") fmt.Println("请选择(1-4):") fmt.Scanln(&key) switch key{ case "1": fmt.Println("\n----------当前收支明细记录-----------") if flag { fmt.Println(details) }else{ fmt.Println("当前没有收支明细... 来一笔吧!") } // fmt.Println(details) case "2": fmt.Println("本次收入金额:") fmt.Scanln(&money) balance += money // 修改账户余额 fmt.Println("本次收入说明:") fmt.Scanln(¬e) // 将这个收入情况,拼接到details变量 details += fmt.Sprintf("\n收入\t%v\t%v\t%v",balance,money,note) flag = true case "3": fmt.Println("登记支出金额:") fmt.Scanln(&money) // 这里需要做一个必要的判断 if money > balance{ fmt.Println("余额的金额不足") break } balance -= money fmt.Println("本次支出说明:") fmt.Scanln(¬e) details += fmt.Sprintf("\n支出\t%v\t%v\t%v",balance,money,note) case "4": fmt.Println("你确定要退出吗?y/n") choice := "" for{ fmt.Scanln(&choice) if choice == "y" || choice == "n"{ break } fmt.Println("你的输入有误,请重新输入y/n") } if choice == "y"{ loop = false } default : fmt.Println("请输入正确的选项..") } if !loop { fmt.Println("你退出家庭账本") break; } } }
将上面的代码改成面向对象的方法,编写myFamilyAccount.go,并使用testMyFamilyAccount.go去完成测试
思路分析
把记账软件的功能,封装到一个结构体中,然后调用该结构体的方法,来实现记账,显示明细。结构体的名字FamilyAccount
在通过main方法中,创建一个结构体FamilyAccount实例,实现记账即可。
// familyAccount.go
package utils import ( "fmt" ) type FamilyAccount struct{ key string // 声明一个字段,控制是否退出for loop bool // 定义账户的余额 [] balance float64 // 每次收支的金额 money float64 // 每次收支的说明 note string // 定义一个变量,记录是否有收支的行为 flag bool // 收支的详情使用字符串来记录 //当有收支时,只需要对details进行拼接处理即可 details string } // 编写一个工厂模式的构造方法,返回一个*FamilyAccount实例 func NewFamilyAccount() *FamilyAccount{ return &FamilyAccount{ key:"", loop:true, balance:10000.0, money:0.0, note:"", flag:false, details:"收入\t账户金额\t收入金额\t说 明" } } // 显示明细方法 func (this *FamilyAccount) showDetails(){ fmt.Println("\n----------当前收支明细记录-----------") if this.flag { fmt.Println(this.details) }else{ fmt.Println("当前没有收支明细... 来一笔吧!") } } // 登记收入方法 func (this *FamilyAccount) income(){ fmt.Println("本次收入金额:") fmt.Scanln(&this.money) this.balance += this.money // 修改账户余额 fmt.Println("本次收入说明:") fmt.Scanln(&this.note) // 将这个收入情况,拼接到details变量 this.details += fmt.Sprintf("\n收入\t%v\t%v\t%v",this.balance,this.money,this.note) this.flag = true } // 登记支出方法 func (this *FamilyAccount) pay(){ fmt.Println("登记支出金额:") fmt.Scanln(&this.money) // 这里需要做一个必要的判断 if this.money > this.balance{ fmt.Println("余额的金额不足") break } this.balance -= this.money fmt.Println("本次支出说明:") fmt.Scanln(&this.note) this.details += fmt.Sprintf("\n支出\t%v\t%v\t%v",this.balance,this.money,this.note) } // 退出方法 func (this *FamilyAccount) exit(){ fmt.Println("你确定要退出吗?y/n") choice := "" for{ fmt.Scanln(&choice) if choice == "y" || choice == "n"{ break } fmt.Println("你的输入有误,请重新输入y/n") } if choice == "y"{ this.loop = false } } //给该结构体绑定相应的方法 // 显示主菜单 func (this *FamilyAccount) MainMenu(){ for { fmt.Println("-------家庭收支记账软件---------") fmt.Println(" 1.收支明细") fmt.Println(" 2.登记收入") fmt.Println(" 3.登记支出") fmt.Println(" 4.退出软件") fmt.Println("请选择(1-4):") fmt.Scanln(&this.key) switch this.key{ case "1": this.showDetails() case "2": this.income() case "3": this.pay() case "4": this.exit() default : fmt.Println("请输入正确的选项..") } if !this.loop { break; } } }
// main.go
package main import ( "go_code/familyaccount/utils" ) func main(){ fmt.Println("这个是面向对象的方式完成~~") utils.NewFamilyAccount().MainMenu() }
感谢大家观看,我们下次见