第十二章 Golang家庭收支记账软件项目
创始人
2024-03-25 09:59:32
0

1.项目开发流程

在这里插入图片描述

2.项目需求说明

  1. 模拟实现基于文本界面的《家庭记账软件》
  2. 该软件能够记录家庭的收入,支出,并能够打印收支明细表

3.项目的界面

在这里插入图片描述

在这里插入图片描述

4.项目代码实现

实现基本功能(先使用面向过程,后面改成面向对象)
功能1:先完成可以显示主菜单,并且可以退出
思路分析:
更加给出的界面完成,主菜单的显示,当用户输入4时,就退出该程序
功能2:完成可以显示明细和登记收入的功能
思路分析:

  1. 因为需要显示明细,我们定义一个变量details string 来记录
  2. 还需要定义变量来记录余额(balance),每次收支的金额(money),每次收支的说明(note)

代码改进
用户输入4退出时,给出提示“你确定要退出吗?y/n”,必须输入正确的y/n,否则循环输入指令,直到输入y或者n

package main 
import ("fmt"
)func main(){//声明一个变量,保存接收用户输入的选项key := ""// 声明一个变量,控制是否退出forloop := 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 -= moneyfmt.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// 声明一个字段,控制是否退出forloop 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.moneyfmt.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() 
}

感谢大家观看,我们下次见

相关内容

热门资讯

前端-session、jwt 目录:   (1)session (2&#x...
linux入门---制作进度条 了解缓冲区 我们首先来看看下面的操作: 我们首先创建了一个文件并在这个文件里面添加了...
关于测试,我发现了哪些新大陆 关于测试 平常也只是听说过一些关于测试的术语,但并没有使用过测试工具。偶然看到编程老师...
前缀和与对数器与二分法 1. 前缀和 假设有一个数组,我们想大量频繁的去访问L到R这个区间的和,...
nodejs:本地安装nvm实... 一、背景-使用不同版本node的原因 vue3+ts、nuxt3版本,node...
JAVA集合知识整理 Java集合知识整理 HashMap相关 HashMap的底层数据结构:jdk1.8之...
无刷直流电机介绍及单片机控制实... 无刷直流电机介绍及单片机控制实例前言基本概念优势与劣势使用寿命基本结构使用单片机控制实例电子调速器&...
fwdiary(2) dp2 1.传纸条  AcWing 275. 传纸条 - AcWing 走两条路,走一条最大的...
常用的DOS命令 常用的DOS命令 DOS(Disk Operating System,磁...
<C++> 类和对象(下) 1.const成员函数将const修饰的“成员函数”称之为const成员函数,cons...