第十二章 Golang家庭收支记账软件项目

简介: 第十二章 Golang家庭收支记账软件项目

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 := ""
  // 声明一个变量,控制是否退出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(&note)
        // 将这个收入情况,拼接到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(&note)
        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() 
}

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

目录
相关文章
|
7月前
|
Go 数据库
Golang 语言编写 gRPC 实战项目
Golang 语言编写 gRPC 实战项目
67 0
|
关系型数据库 MySQL Linux
Docker(三)实战:-Docker部署Golang项目并关联Mysql容器
Dockerfile 文件是用于定义 Docker 镜像生成流程的配置文件,文件内容是一条条指令,每一条指令构建一层,因此每一条指令的内容,就是描述该层应当如何构建;这些指令应用于基础镜像并最终创建一个新的镜像
1031 0
Docker(三)实战:-Docker部署Golang项目并关联Mysql容器
|
5天前
|
Go
golang学习3,golang 项目中配置gin的web框架
golang学习3,golang 项目中配置gin的web框架
|
5天前
|
Go 开发者
Golang深入浅出之-Go语言项目构建工具:Makefile与go build
【4月更文挑战第27天】本文探讨了Go语言项目的构建方法,包括`go build`基本命令行工具和更灵活的`Makefile`自动化脚本。`go build`适合简单项目,能直接编译Go源码,但依赖管理可能混乱。通过设置`GOOS`和`GOARCH`可进行跨平台编译。`Makefile`适用于复杂构建流程,能定义多步骤任务,但编写较复杂。在选择构建方式时,应根据项目需求权衡,从`go build`起步,逐渐过渡到Makefile以实现更高效自动化。
29 2
|
5天前
|
存储 测试技术 Go
Golang框架实战-KisFlow流式计算框架(2)-项目构建/基础模块-(上)
KisFlow项目源码位于<https://github.com/aceld/kis-flow,初始阶段涉及项目构建和基础模块定义。首先在GitHub创建仓库,克隆到本地。项目目录包括`common/`, `example/`, `function/`, `conn/`, `config/`, `flow/`, 和 `kis/`。`go.mod`用于包管理,`KisLogger`接口定义了日志功能,提供不同级别的日志方法。默认日志对象`kisDefaultLogger`打印到标准输出。
623 1
Golang框架实战-KisFlow流式计算框架(2)-项目构建/基础模块-(上)
|
6月前
|
传感器 数据采集 物联网
Golang硬件控制:将软件力量扩展到物理世界
Golang硬件控制:将软件力量扩展到物理世界
|
6月前
|
Cloud Native 安全 Java
构建高性能云原生应用:使用Golang的实践指南(邮件/短信发送、人脸识别、云点播、云直播项目)
构建高性能云原生应用:使用Golang的实践指南(邮件/短信发送、人脸识别、云点播、云直播项目)
|
7月前
|
Go 网络安全 开发工具
在golang中引入私有git仓库的pkg包?引入私有Git仓库的包:在Go语言项目中轻松实现
在golang中引入私有git仓库的pkg包?引入私有Git仓库的包:在Go语言项目中轻松实现
104 0
在golang中引入私有git仓库的pkg包?引入私有Git仓库的包:在Go语言项目中轻松实现
|
10月前
|
Go
golang的Fan模式在项目中实战,我后悔了
golang的Fan模式在项目中实战,我后悔了
|
10月前
|
设计模式 Go
golang去else最佳项目实践-责任链模式
golang去else最佳项目实践-责任链模式