Go_家庭收支软件

12.1 项目开发流程说明

GoGo.PNG

12.2 项目需求

  • 模拟实现基于文本界面的《家庭记账软件》
  • 该软件能够记录家庭的收入,支出,并能够打印收支明细表
  • 项目采用分级菜单方式,主菜单如下

12.3 项目的界面

GoGo.PNG

GoGo.PNG

GoGo.PNG

12.4 项目代码实现

12.4.1 实现基本功能(先使用面向过程,后面改成面向对象)

编写文件 TestMyAccount.go完成基本功能

  • 功能1:先完成可以显示主菜单,并且可以退出
package main
import (
	"fmt"
)

func main() {
	// 声明一个变量,保存接收用户输入的选项
	key := ""
	// 声明一个变量,控制是否退出循环
	loop := true
	// 显示这个主菜单
	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("----------当前收支明细记录----------")
		case "2":
		case "3":
			fmt.Println("登记支出")
		case "4":
			loop = false
		default :
			fmt.Println("请输入正确的选项(1-4)")
		}
		if !loop {
			break
		}
	}
	fmt.Println("你退出了家庭记账软件的使用......")
}
  • 功能2:完成可以显示明细、完成登记收入的功能

思路分析:

1、因为需要显示明细,所以需要我们定义一个变量details string来记录

2、还需要定义 变量来记录 balance余额、每次收支金额money、每次收支的说明note

tL7STx.png

tL7EXd.png

  • 功能3:完成登记支出功能

登记支出和登记收入功能类似,修改部分即可

tLH9Ds.png

12.4.2 项目代码实现改进

1、用户输入4 退出时,给出提示"你确定要退出吗? y/n",必须输入正确的y/n,否则循环输入指令,直到输入y/n

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
			 }			

2、当没有任何收支明细时,提示"当前没有收支明细。。。。。来一笔吧!"

GoGo.PNG

3、在支出时,判断余额是否够,并给出相应的提示。

GoGo.PNG

整体代码

package main
import (
	"fmt"
)

func main() {
	// 声明一个变量,保存接收用户输入的选项
	key := ""
	// 声明一个变量,控制是否退出循环
	loop := true
	// 定义账户余额
	balance := 10000.0
	// 每次收支的金额
	money := 0.0
	// 每次收支的说明
	note := ""
	// 定义一个变量,记录是否有收支行为
	flog := false
	// 收支的详情,使用字符串来记录
	// 当有收支时,只需要对details进行拼接处理即可
	details := "收支\t账户金额\t收支金额\t说明"

	// 显示这个主菜单
	for {
		fmt.Println("\n----------家庭收支记账软件----------")
		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("---------当前收支明细记录---------")
			if flog {
				fmt.Println(details)
			} else {
				fmt.Println("当前没有收支明细。。。。来一笔")
			}
		
		case "2":
			fmt.Println("本次收入金额:")
			fmt.Scanln(&money)
			balance += money  //修改账户余额
			fmt.Println("本次收入说明:")
			fmt.Scanln(&note)
			// 将这个收入情况,拼接到detalis变量
			details += fmt.Sprintf("\n收入\t%v\t%v\t%v", balance, money, note)
			flog = true

		case "3":
			fmt.Println("本次支入金额:")
			fmt.Scanln(&money)
			// 这里需要做一个必要的判断
			if money > balance {
				fmt.Println("余额的金额不足")
				break
			} 
			balance	-= money
			fmt.Println("本次支入说明:")
			fmt.Scanln(&note)			
			// 将这个收入情况,拼接到detalis变量
			details += fmt.Sprintf("\n支入\t%v\t%v\t%v", balance, money, note)
			flog = 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("请输入正确的选项(1-4)")
		}
		if !loop {
			break
		}
	}
	fmt.Println("你退出了家庭记账软件的使用......")
}

4、将面向过程的代码修改成面向对象的方法,编写myFamilyAccount,并使用testMyfamilyAccount去完成测试。

思路分析:

​ 把记录软件的功能,封装到一个结构体中,然后调用该结构体的方法, 来实现记账,显示明细,结构体名字FamilyAccount

​ 在通过main方法中,创建一个结构体 FamilyAccount 实例,实现记账即可

代码规划

GoGo.PNG

factory/main/main.go 代码

package main
import (
	"fmt"
	"go_code/factory/utils"
)
 func main() {
	fmt.Println("这个是面向对象的方式完成~~~~~")
	utils.NewFamilyAccount().MainMenu()
 }

factory/utils/familyAccount.go代码

package utils
import (
	"fmt"
)

type FamilyAccount struct {
	// 声明必要的字段
	// 声明一个字段,保存接收用户输入的选项
	key string
	// 声明一个字段,控制是否退出循环
	loop bool 
	// 定义账户余额
	balance float64
	// 定义每次收支的金额
	money float64
	// 每次收支的说明
	note string
	// 定义一个字段,记录是否有收支行为
	flog bool
	// 收支的详情,使用字符串来记录
	// 当有收支时,只需要对details进行拼接处理即可
	details string
}
// 编写要给工厂模式的构造方法,返回一个*FamilyAccout实例
func NewFamilyAccount() *FamilyAccount {
	return &FamilyAccount {
		key : "",
		loop : true,
		balance : 10000.0,
		money : 0.0,
		note : "",
		flog : false,
		details : "收支\t账户金额\t收支金额\t说明",
	}
}

// 将显示明细写成一个方法
func (this *FamilyAccount) ShowDetails() {
	fmt.Println("---------当前收支明细记录---------")
		if this.flog {
			fmt.Println(this.details)
		} else {
			fmt.Println("当前没有收支明细。。。。来一笔")
		}
}
// 将登记收入写成一个方法,和*FamilyAccount绑定
func (this *FamilyAccount) income(){
	fmt.Println("本次收入金额:")
		fmt.Scanln(&this.money)
		this.balance += this.money  //修改账户余额
		fmt.Println("本次收入说明:")
		fmt.Scanln(&this.note)
		// 将这个收入情况,拼接到detalis变量
		this.details += fmt.Sprintf("\n收入\t%v\t%v\t%v", this.balance, this.money, this.note)
		this.flog = true
}
// 将登记支出写成一个方法,和*FamilyAccount绑定
func (this *FamilyAccount) pay() {
	fmt.Println("本次支入金额:")
		fmt.Scanln(&this.money)
		// 这里需要做一个必要的判断
		if this.money > this.balance {
			fmt.Println("余额的金额不足")
		} 
		this.balance -= this.money
		fmt.Println("本次支入说明:")
		fmt.Scanln(&this.note)			
		// 将这个收入情况,拼接到detalis变量
		this.details += fmt.Sprintf("\n支入\t%v\t%v\t%v", this.balance, this.money, this.note)
		this.flog = true

}
// 将退出写成一个方法,和*FamilyAccount绑定
func (this *FamilyAccount) quite() {
	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("\n----------家庭收支记账软件----------")
		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.quite()
			default : 
				fmt.Println("请输入正确的选项(1-4)")		
		}
		if !this.loop {
			break
		}
	}
}

posted on 2020-06-12 15:25  九酒馆  阅读(146)  评论(0编辑  收藏  举报

导航