小项目:收支记账和客户关系管理 一、收支记账 二、客户关系管理 

小项目:收支记账和客户关系管理
一、收支记账
二、客户关系管理 

1、面向过程实现基本功能

功能1:完成可以显示主菜单,并且可以退出

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)

package main

import "fmt"

func main() {
	//保存接收用户输入的选项
	key := ""

	//控制是否退出for循环
	loop := true

	//定义账户的余额
	balance := 10000.0

	//每次收支的金额
	money := 0.0

	//每次收支的说明
	note := ""

	//收支的详情使用字符串来记录
	//当有收支时,只需要对details进行拼接处理即可
	details := "收支	账户金额	收支金额	说   明"

	//显示主菜单
	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(&note)
			details += fmt.Sprintf("
收入	%v	%v	%v
", balance, money, note)
		case "3":
			fmt.Println("登记支出")
		case "4":
			loop = false
		default:
			fmt.Println("请输入正确的选项")
		}
		if !loop {
			break
		}
	}
	fmt.Println("退出记账收支软件的使用")
}

 功能3:登记支出功能

package main

import "fmt"

func main() {
	//保存接收用户输入的选项
	key := ""

	//控制是否退出for循环
	loop := true

	//定义账户的余额
	balance := 10000.0

	//每次收支的金额
	money := 0.0

	//每次收支的说明
	note := ""

	//收支的详情使用字符串来记录
	//当有收支时,只需要对details进行拼接处理即可
	details := "收支	账户金额	收支金额	说   明"

	//显示主菜单
	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(&note)
			details += fmt.Sprintf("
收入	%v	%v	%v
", balance, money, note)
		case "3":
			fmt.Println("本次支出金额:")
			fmt.Scanln(&money)
			if money > balance {
				fmt.Println("余额的金额不足")
				break
			}
			balance -= money
			fmt.Println("本次支出说明")
			fmt.Scanln(&note)
			details += fmt.Sprintf("
支出	%v	%v	%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)、在支出时,判断余额是否够,并给出相应的提示

package main

import "fmt"

func main() {
	//保存接收用户输入的选项
	key := ""

	//控制是否退出for循环
	loop := true

	//定义账户的余额
	balance := 10000.0

	//每次收支的金额
	money := 0.0

	//每次收支的说明
	note := ""

	//记录是否有收支行为
	flag := false

	//收支的详情使用字符串来记录
	//当有收支时,只需要对details进行拼接处理即可
	details := "收支	账户金额	收支金额	说   明"

	//显示主菜单
	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(&note)
			details += fmt.Sprintf("
收入	%v	%v	%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("
支出	%v	%v	%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

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: "收支	 账户金额	 收支金额	 说 明",
	}
}

//将显示明细写成一个方法
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("
 收入	%v	%v	%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("
 支出	%v	%v	%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("
-----------------家庭收支记账软件-----------------")
		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

package main

import (
	"accountManage/utils"
	"fmt"
)

func main() {
	fmt.Println("面向对象的方式完成收支记账")
	utils.NewMyAccount().MainMenu()
}

二、客户关系管理 

小项目:收支记账和客户关系管理
一、收支记账
二、客户关系管理 

customer.go

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	%v	%v	%v	%v	%v	", this.Id, this.Name, this.Gender, this.Age, this.Phone, this.Email)
	return info
}

customerService.go

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

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("编号	姓名	性别	年龄	电话	邮箱")
	for i := 0; i < len(customers); i++ {
		fmt.Println(customers[i].GetInfo())
	}
	fmt.Printf("
----------------客户列表完成---------------

")
}

//得到用户的输入,信息构建新的客户,并完成添加
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()
}