小项目:收支记账和客户关系管理
一、收支记账
1、面向过程实现基本功能
功能1:完成可以显示主菜单,并且可以退出
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 | package main import "fmt" func main() { //保存接收用户输入的选项 key := "" //控制是否退出for循环 loop := true //显示主菜单 for { fmt.Println( "--------------收支记账-----------------" ) fmt.Println( " 1 收支明细" ) fmt.Println( " 2 登记收入" ) fmt.Println( " 3 登记支出" ) fmt.Println( " 4 退出软件" ) fmt.Print( "请选择(1-4):" ) fmt.Scanln(&key) switch key { case "1" : fmt.Println( "----------------当前收支明细记录------------------" ) case "2" : case "3" : fmt.Println( "登记支出" ) case "4" : loop = false default : fmt.Println( "请输入正确的选项" ) } if !loop { break } } fmt.Println( "退出记账收支软件的使用" ) } |
功能2:显示明细和登记收入
变量details string来记录明细
记录余额(balance)、每次收支的金额(money), 每次收支的说明(note)
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 | package main import "fmt" func main() { //保存接收用户输入的选项 key := "" //控制是否退出for循环 loop := true //定义账户的余额 balance := 10000.0 //每次收支的金额 money := 0.0 //每次收支的说明 note := "" //收支的详情使用字符串来记录 //当有收支时,只需要对details进行拼接处理即可 details := "收支\t账户金额\t收支金额\t说 明" //显示主菜单 for { fmt.Println( "--------------收支记账-----------------" ) fmt.Println( " 1 收支明细" ) fmt.Println( " 2 登记收入" ) fmt.Println( " 3 登记支出" ) fmt.Println( " 4 退出软件" ) fmt.Print( "请选择(1-4):" ) fmt.Scanln(&key) switch key { case "1" : fmt.Println( "----------------当前收支明细记录------------------" ) fmt.Println(details) case "2" : fmt.Println( "本次收入金额:" ) fmt.Scanln(&money) balance += money fmt.Println( "本次收入说明:" ) fmt.Scanln(¬e) details += fmt.Sprintf( "\n收入\t%v\t%v\t%v\n" , balance, money, note) case "3" : fmt.Println( "登记支出" ) case "4" : loop = false default : fmt.Println( "请输入正确的选项" ) } if !loop { break } } fmt.Println( "退出记账收支软件的使用" ) } |
功能3:登记支出功能
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 | package main import "fmt" func main() { //保存接收用户输入的选项 key := "" //控制是否退出for循环 loop := true //定义账户的余额 balance := 10000.0 //每次收支的金额 money := 0.0 //每次收支的说明 note := "" //收支的详情使用字符串来记录 //当有收支时,只需要对details进行拼接处理即可 details := "收支\t账户金额\t收支金额\t说 明" //显示主菜单 for { fmt.Println( "--------------收支记账-----------------" ) fmt.Println( " 1 收支明细" ) fmt.Println( " 2 登记收入" ) fmt.Println( " 3 登记支出" ) fmt.Println( " 4 退出软件" ) fmt.Print( "请选择(1-4):" ) fmt.Scanln(&key) switch key { case "1" : fmt.Println( "----------------当前收支明细记录------------------" ) fmt.Println(details) case "2" : fmt.Println( "本次收入金额:" ) fmt.Scanln(&money) balance += money fmt.Println( "本次收入说明:" ) fmt.Scanln(¬e) details += fmt.Sprintf( "\n收入\t%v\t%v\t%v\n" , balance, money, note) 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" : loop = false default : fmt.Println( "请输入正确的选项" ) } if !loop { break } } fmt.Println( "退出记账收支软件的使用" ) } |
项目代码实现改进:
(1)、用户输入4退出时,给出提示“确定要退出吗?y/n”,必须输入正确的y/n,否则循环输入指令,直到输入y或者n
(2)、当没有任何收支明细是,提示“当前没有收支明细...来一笔吧!”
(3)、在支出时,判断余额是否够,并给出相应的提示
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 | 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.Print( "请选择(1-4):" ) fmt.Scanln(&key) switch key { case "1" : fmt.Println( "----------------当前收支明细记录------------------" ) if flag { fmt.Println(details) } else { fmt.Println( "当前没有收支明细...来一笔吧" ) } case "2" : fmt.Println( "本次收入金额:" ) fmt.Scanln(&money) balance += money fmt.Println( "本次收入说明:" ) fmt.Scanln(¬e) 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) flag = true 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 { break } } fmt.Println( "退出记账收支软件的使用" ) } |
2、面向对象实现基本功能
将面向过程的代码修改成面向对象的方法,编写myAccount.go ,并使用testMyAccount.go去完成测试。
把记账软件的功能,封装到一个结构体中,然后调用该结构体的方法,来实现记账,显示明细。
myAccount.go
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 101 102 103 104 105 106 107 108 109 110 111 112 113 114 | package utils import "fmt" type MyAccount struct { //声明必须的字段 //声明一个字段,保存接收用户输入的选项 key string //声明一个字段,控制是否退出 for loop bool //定义账户的余额 [] balance float64 //每次收支的金额 money float64 //每次收支的说明 note string //定义个字段,记录是否有收支的行为 flag bool //收支的详情使用字符串来记录 //当有收支时,只需要对 details 进行拼接处理即可 details string } //编写要给工厂模式的构造方法,返回一个*MyAccount 实例 func NewMyAccount() *MyAccount { return &MyAccount{key: "" , loop: true, balance: 10000.0, money: 0.0, note: "" , flag: false, details: "收支\t 账户金额\t 收支金额\t 说 明" , } } //将显示明细写成一个方法 func (this *MyAccount) showDetails() { fmt.Println( "-----------------当前收支明细记录-----------------" ) if this.flag { fmt.Println(this.details) } else { fmt.Println( "当前没有收支明细... 来一笔吧!" ) } } //将登记收入写成一个方法,和*MyAccount 绑定 func (this *MyAccount) 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 } //将登记支出写成一个方法,和*MyAccount 绑定 func (this *MyAccount) 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) this.flag = true } //将退出系统写成一个方法,和*MyAccount 绑定 func (this *MyAccount) 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 *MyAccount) MainMenu() { for { fmt.Println( "\n-----------------家庭收支记账软件-----------------" ) fmt.Println( " 1 收支明细" ) fmt.Println( " 2 登记收入" ) fmt.Println( " 3 登记支出" ) fmt.Println( " 4 退出软件" ) fmt.Print( "请选择(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 } } } |
testMyAccount.go
1 2 3 4 5 6 7 8 9 10 11 | package main import ( "accountManage/utils" "fmt" ) func main() { fmt.Println( "面向对象的方式完成收支记账" ) utils.NewMyAccount().MainMenu() } |
二、客户关系管理
customer.go
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 | package model import "fmt" //声明一个Customer结构体,表示一个客户信息 type Customer struct { Id int Name string Gender string Age int Phone string Email string } //使用一个工厂模式,返回一个Customer实例 func NewCustomer(id int, name string, gender string, age int, phone string, email string) Customer { return Customer{ Id: id, Name: name, Gender: gender, Age: age, Phone: phone, Email: email, } } func NewCustomer2(name string, gender string, age int, phone string, email string) Customer { return Customer{ Name: name, Gender: gender, Age: age, Phone: phone, Email: email, } } //返回用户的信息 func (this Customer) GetInfo() string { info := fmt.Sprintf( "%v\t%v\t%v\t%v\t%v\t%v\t" , this.Id, this.Name, this.Gender, this.Age, this.Phone, this.Email) return info } |
customerService.go
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 | package service import "customerManage/model" //该CustomerService,完成对Customer的操作,包括增删改查 type CustomerService struct { customers []model.Customer //声明一个字段,表示当前切片含有多少个客户 //该字段后面还可以作为新客户的id+1 customerNum int } //编写一个方法,可以返回*CustomerService func NewCustomerService() *CustomerService { //为了能够看到有客户在切片中,初始化一个客户 customerService := &CustomerService{} customerService.customerNum = 1 customer := model.NewCustomer(1, "张三" , "男" , 20, "112" , "zs@163.com" ) customerService.customers = append(customerService.customers, customer) return customerService } //返回客户切片 func (this *CustomerService) List() []model.Customer { return this.customers } //添加客户到customers切片 func (this *CustomerService) Add(customer model.Customer) bool { //分配ID的规则:添加的顺序 this.customerNum++ customer.Id = this.customerNum this.customers = append(this.customers, customer) return true } //根据ID删除客户(从切片中删除) func (this *CustomerService) Delete(id int) bool { index := this.FindById(id) if index == -1 { return false } this.customers = append(this.customers[:index], this.customers[index+1:]...) return true } //根据ID查找客户在切片中对应下标,如果没有该客户,返回-1 func (this *CustomerService) FindById(id int) int { index := -1 //遍历this.customers切片 for i := 0; i < len(this.customers); i++ { if this.customers[i].Id == id { index = i } } return index } |
customerView.go
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 101 102 103 104 105 106 107 108 109 110 111 112 113 114 115 116 117 118 119 120 121 122 123 124 125 126 127 128 129 130 131 132 133 134 135 136 137 138 | package main import ( "customerManage/model" "customerManage/service" "fmt" ) type customerView struct { //定义必要字段 key string //接收用户输入 loop bool //表示是否循环的显示主菜单 customerService *service.CustomerService } //显示所有的客户信息 func (this *customerView) list() { //获取到当前所有的客户信息(在切片中) customers := this.customerService.List() //显示 fmt.Println( "----------------客户列表------------------" ) fmt.Println( "编号\t姓名\t性别\t年龄\t电话\t邮箱" ) for i := 0; i < len(customers); i++ { fmt.Println(customers[i].GetInfo()) } fmt.Printf( "\n----------------客户列表完成---------------\n\n" ) } //得到用户的输入,信息构建新的客户,并完成添加 func (this *customerView) add() { fmt.Println( "-------------------添加客户------------------" ) fmt.Println( "姓名" ) name := "" fmt.Scanln(&name) fmt.Println( "性别" ) gender := "" fmt.Scanln(&gender) fmt.Println( "年龄" ) age := 0 fmt.Scanln(&age) fmt.Println( "电话" ) phone := "" fmt.Scanln(&phone) fmt.Println( "邮件" ) email := "" fmt.Scanln(&email) //构建一个新的Customer实例 //注意:id号,没有让用户输入,id是惟一的,需要系统分配 customer := model.NewCustomer2(name, gender, age, phone, email) if this.customerService.Add(customer) { fmt.Println( "---------------添加成功----------------" ) } else { fmt.Println( "---------------添加失败----------------" ) } } //得到用户的输入ID,删除该ID对应的客户 func (this *customerView) delete() { fmt.Println( "----------------删除客户-----------------" ) fmt.Println( "请选择待删除客户编号(输入-1退出)" ) id := -1 fmt.Scanln(&id) if id == -1 { return //放弃删除操作 } fmt.Println( "确认是否删除(Y/N):" ) choice := "" fmt.Scanln(&choice) if choice == "y" || choice == "Y" { if this.customerService.Delete(id) { fmt.Println( "--------------删除成功-------------------" ) } else { fmt.Println( "--------------删除失败,输入的ID号不存在-------------------" ) } } } //退出软件 func (this *customerView) exit() { fmt.Println( "确认是否退出(Y/N):" ) for { fmt.Scanln(&this.key) if this.key == "Y" || this.key == "y" || this.key == "N" || this.key == "n" { break } fmt.Println( "输入有误,确认是否退出(Y/N)" ) } if this.key == "Y" || this.key == "y" { this.loop = false } } func (cv *customerView) mainMenu() { for { fmt.Println( "----------------客户信息管理软件---------------------" ) fmt.Println( " 1 添 加 客 户" ) fmt.Println( " 2 修 改 客 户" ) fmt.Println( " 3 删 除 客 户" ) fmt.Println( " 4 客 户 列 表" ) fmt.Println( " 5 退 出" ) fmt.Println( "请选择(1-5): " ) fmt.Scanln(&cv.key) switch cv.key { case "1" : cv.add() case "2" : fmt.Println( "修 改 客 户" ) case "3" : cv.delete() case "4" : cv.list() case "5" : cv.exit() default : fmt.Println( "你的输入有误,请重新输入" ) } if !cv.loop { break } } fmt.Println( "你退出了客户关系管理系统" ) } func main() { //在main函数中,创建一个customerView,并允许显示主菜单 customerView := customerView{ key: "" , loop: true, } //完成对customerService结构体的customerService字段的初始化 customerView.customerService = service.NewCustomerService() customerView.mainMenu() } |
【推荐】编程新体验,更懂你的AI,立即体验豆包MarsCode编程助手
【推荐】凌霞软件回馈社区,博客园 & 1Panel & Halo 联合会员上线
【推荐】抖音旗下AI助手豆包,你的智能百科全书,全免费不限次数
【推荐】博客园社区专享云产品让利特惠,阿里云新客6.5折上折
【推荐】轻量又高性能的 SSH 工具 IShell:AI 加持,快人一步
· 用 C# 插值字符串处理器写一个 sscanf
· Java 中堆内存和栈内存上的数据分布和特点
· 开发中对象命名的一点思考
· .NET Core内存结构体系(Windows环境)底层原理浅谈
· C# 深度学习:对抗生成网络(GAN)训练头像生成模型
· 趁着过年的时候手搓了一个低代码框架
· 本地部署DeepSeek后,没有好看的交互界面怎么行!
· 为什么说在企业级应用开发中,后端往往是效率杀手?
· 用 C# 插值字符串处理器写一个 sscanf
· 乌龟冬眠箱湿度监控系统和AI辅助建议功能的实现
2018-04-07 187 Repeated DNA Sequences 重复的DNA序列
2018-04-07 179 Largest Number 把数组排成最大的数
2018-04-07 174 Dungeon Game 地下城游戏
2018-04-07 173 Binary Search Tree Iterator 二叉搜索树迭代器
2018-04-07 172 Factorial Trailing Zeroes 阶乘后的零
2018-04-07 171 Excel Sheet Column Number Excel表列序号 26进制转10进制
2018-04-07 169 Majority Element 求众数 数组中出现次数超过一半的数字