Go学习笔记(11)-面向对象实战练手项目

Go学习笔记(11)

项目 1-家庭收支记账软件项目

项目开发流程说明

项目需求说明

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

项目的界面

其它的界面,我们就直接参考 项目效果图.txt

项目代码实现

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

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

思路分析:

更加给出的界面完成,主菜单的显示, 当用户输入 4 时,就退出该程序

走代码:

功能 2:完成可以显示明细登记收入的功能

思路分析:

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

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

走代码:

功能 3:完成了登记支出的功能

思路分析:

登记支出的功能和登录收入的功能类似,做些修改即可

走代码:

项目代码实现改进

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

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

  1. 在支出时,判断余额是否够,并给出相应的提示

  1. 面 向 过 程 的 代 码 修 改 成 面 向 对 象 的 方 法 , 编 写 myFamilyAccount.go , 并 使 用testMyFamilyAccount.go 去完成测试

思路分析: 把记账软件的功能,封装到一个结构体中,然后调用该结构体的方法,来实现记账,显示明细。结构体的名字 FamilyAccount . 在通过在 main 方法中,创建一个结构体 FamilyAccount 实例,实现记账即可.

代码实现:

代码不需要重写,只需要重写组织一下.

familyaccount/main/main.go

familyaccount/utils/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("-----------------当前收支明细记录-----------------")
    if this.flag {
        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)
    //将这个收入情况,拼接到 details 变量
    //收入 11000 1000 有人发红包
    this.details += fmt.Sprintf("\n 收入\t%v\t%v\t%v", this.balance, this.money, this.note)
    this.flag = true
}

//将登记支出写成一个方法,和*FamilyAccount 绑定
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)
    this.flag = true
}

//将退出系统写成一个方法,和*FamilyAccount 绑定
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("\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
    }
    }
}

对项目的扩展功能的练习

  1. 对上面的项目完成一个转账功能
  2. 在使用该软件前,有一个登录功能,只有输入正确的用户名和密码才能操作.

项目 2-客户信息关系系统

项目需求分析

  1. 模拟实现基于文本界面的《客户信息管理软件》。
  2. 该软件能够实现对客户对象的插入、修改和删除(用切片实现),并能够打印客户明细表

项目的界面设计

主菜单界面

添加客户界面

修改客户界面

删除客户界面

客户列表界面

客户关系管理系统的程序框架图

项目功能实现-显示主菜单和完成退出软件功能

  • 功能的说明

当用户运行程序时,可以看到主菜单,当输入 5 时,可以退出该软件.

  • 思路分析

编写 customerView.go ,另外可以把 customer.go 和 customerService.go 写上.

  • 代码实现

customerManage/model/customer.go

package model

//声明一个 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,
    }
}

customerManage/service/customerService.go

package service
import (
    "go_code/customerManage/model"
)

//该 CustomerService, 完成对 Customer 的操作,包括
//增删改查
type CustomerService struct {
    customers []model.Customer
    //声明一个字段,表示当前切片含有多少个客户
    //该字段后面,还可以作为新客户的 id+1
    customerNum int
}

customerManage/view/customerView.go

package main

import (
	"fmt"
)

type customerView struct {
    //定义必要字段
    key string //接收用户输入...
    loop bool //表示是否循环的显示主菜单
}

//显示主菜单
func (this *customerView) mainMenu() {
    for {
        
    fmt.Println("-----------------客户信息管理软件-----------------")
    fmt.Println(" 1 添 加 客 户")
    fmt.Println(" 2 修 改 客 户")
    fmt.Println(" 3 删 除 客 户")
    fmt.Println(" 4 客 户 列 表")
    fmt.Println(" 5 退 出")
    fmt.Print("请选择(1-5):")
    fmt.Scanln(&this.key)
        
    switch this.key {
        case "1" :
        	fmt.Println("添 加 客 户")
        case "2" :
        	fmt.Println("修 改 客 户")
        case "3" :
        	fmt.Println("删 除 客 户")
        case "4" :
        	fmt.Println("客 户 列 表")
        case "5" :
    		this.loop = false
        default :
			fmt.Println("你的输入有误,请重新输入...")
		}
        if !this.loop {
        	break
        }
	}
	fmt.Println("你退出了客户关系管理系统...")
}

func main() {
    //在 main 函数中,创建一个 customerView,并运行显示主菜单..
    customerView := customerView{
        key : "",
        loop : true,
    }
    //显示主菜单..
    customerView.mainMenu()
}

项目功能实现-完成显示客户列表的功能

功能说明

思路分析

代码实现

customerManage/model/customer.go

customerManage/service/customerService.go[增加了两个方法]

customerManage/view/customerView.go

package main

import (
    "fmt"
    "go_code/customerManage/service"
)

type customerView struct {
    //定义必要字段
    key string //接收用户输入...
    loop bool //表示是否循环的显示主菜单
    //增加一个字段 customerService
    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].Id,"\t", customers[i].Name...)
    fmt.Println(customers[i].GetInfo())
    }
    fmt.Printf("\n-------------------------客户列表完成-------------------------\n\n")
}

//显示主菜单
func (this *customerView) mainMenu() {
    for {
        
        fmt.Println("-----------------客户信息管理软件-----------------")
        fmt.Println(" 1 添 加 客 户")
        fmt.Println(" 2 修 改 客 户")
        fmt.Println(" 3 删 除 客 户")
        fmt.Println(" 4 客 户 列 表")
        fmt.Println(" 5 退 出")
        fmt.Print("请选择(1-5):")
        fmt.Scanln(&this.key)
        
        switch this.key {
            case "1" :
            	fmt.Println("添 加 客 户")
            case "2" :
            	fmt.Println("修 改 客 户")
            case "3" :
            	fmt.Println("删 除 客 户")
            case "4" :
            	this.list()
            case "5" :
            	this.loop = false
            default :
            	fmt.Println("你的输入有误,请重新输入...")
        }
        if !this.loop {
            break
        }
   }
fmt.Println("你退出了客户关系管理系统...")
}


func main() {
    
    //在 main 函数中,创建一个 customerView,并运行显示主菜单..
    customerView := customerView{
        key : "",
        loop : true,
    }
    
    //这里完成对 customerView 结构体的 customerService 字段的初始化
    customerView.customerService = service.NewCustomerService()
    //显示主菜单..
    customerView.mainMenu()
}

项目功能实现-添加客户的功能

功能说明

思路分析

代码实现

customerManage/model/customer.go

customerManage/service/customerService.go

customerManage/service/customerView.go

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

项目功能实现-完成删除客户的功能

功能说明

思路分析

代码实现

customerManage/model/customer.go [没有变化]

customerManage/service/customerService.go

customerManage/view/customerView.go

项目功能实现-完善退出确认功能(课后作业)

  • 功能说明:

    要求用户在退出时提示 " 确认是否退出(Y/N):",用户必须输入 y/n, 否则循环提示。

  • 思路分析:

    需要编写 customerView.go

  • 代码实现:

客户关系管理系统-课后练习

customerManage/service/customerService.go

添加修改方法

func (customerService *CustomerService) Update(id int) bool {
	index := customerService.FindById(id)
	if index == -1 {
		return false
	}
	customer := customerService.customers[index]
	// var name string
	// var gender string
	// var age int
	// var phone string
	// var email string
	fmt.Print("姓名("+customer.Name+"):")
	fmt.Scanln(&customerService.customers[index].Name)
	// customerService.customers[index].Name = name
	fmt.Print("性别("+customer.Gender+"):")
	fmt.Scanln(&customerService.customers[index].Gender)
	// customerService.customers[index].Gender = gender
	fmt.Printf("年龄(%d):",customer.Age)
	fmt.Scanln(&customerService.customers[index].Age)
	// customerService.customers[index].Age = age
	fmt.Print("电话("+customer.Phone+"):")
	fmt.Scanln(&customerService.customers[index].Phone)
	// customerService.customers[index].Phone = phone
	fmt.Print("邮箱("+customer.Email+"):")
	fmt.Scanln(&customerService.customers[index].Email)
	// customerService.customers[index].Email = email

	return true
}

customerManage/view/customerView.go

func (view *customerView) update() {
	fmt.Println("-----修改用户-----")
	fmt.Println("请选择待修改的客户编号(-1退出): ")
	id := -1
	fmt.Scanln(&id)
	if id == -1 {
		return
	}
	
	if view.customerService.Update(id) {
		fmt.Println("-----修改完成-----")
	} else {
		fmt.Println("-----修改失败,未找到为此id的用户-----")
	}
}

完整代码如下:

customerManage/model/customer.go

package model

import "fmt"

type Customer struct {
	Id     int
	Name   string
	Gender string
	Age    int
	Phone  string
	Email  string
}

func (customer Customer) GetInfo() string {
	info := fmt.Sprintf("%v\t%v\t%v\t%v\t%v\t%v\t",customer.Id,
		customer.Name,customer.Gender,customer.Age,customer.Phone,customer.Email)
	return info
}

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,
	}
}

customerManage/service/customerService.go

package service

import (
	"fmt"
	"go_code/customerManage/model"
)

type CustomerService struct{
	customers []model.Customer
	customerNum int
}


func NewCustomerService() *CustomerService {
	customerService := &CustomerService{}
	customerService.customerNum = 1
	customer := model.NewCustomer(1,"张三","男",20,"112","zs@sohu.com")
	customerService.customers = append(customerService.customers, customer)
	return customerService
}

func (customerService *CustomerService) List() []model.Customer {
	return customerService.customers
}

func (customerService *CustomerService) Add(customer model.Customer) bool {
	customerService.customerNum++
	customer.Id = customerService.customerNum
	customerService.customers =append(customerService.customers, customer)
	return true
}

func (customerService *CustomerService) FindById(id int) int {
	index := -1
	for i := 0; i < len(customerService.customers); i++ {
		if customerService.customers[i].Id == id {
			index = i
		}
	}
	return index
}

func (customerService *CustomerService) Delete(id int) bool {
	index := customerService.FindById(id)
	if index == -1 {
		return false
	}

	customerService.customers = append(customerService.customers[:index],customerService.customers[index+1:]...)
	return true
}

func (customerService *CustomerService) Update(id int) bool {
	index := customerService.FindById(id)
	if index == -1 {
		return false
	}
	customer := customerService.customers[index]
	// var name string
	// var gender string
	// var age int
	// var phone string
	// var email string
	fmt.Print("姓名("+customer.Name+"):")
	fmt.Scanln(&customerService.customers[index].Name)
	// customerService.customers[index].Name = name
	fmt.Print("性别("+customer.Gender+"):")
	fmt.Scanln(&customerService.customers[index].Gender)
	// customerService.customers[index].Gender = gender
	fmt.Printf("年龄(%d):",customer.Age)
	fmt.Scanln(&customerService.customers[index].Age)
	// customerService.customers[index].Age = age
	fmt.Print("电话("+customer.Phone+"):")
	fmt.Scanln(&customerService.customers[index].Phone)
	// customerService.customers[index].Phone = phone
	fmt.Print("邮箱("+customer.Email+"):")
	fmt.Scanln(&customerService.customers[index].Email)
	// customerService.customers[index].Email = email

	return true
}

customerManage/view/customerView.go

package main

import (
	"fmt"
	"go_code/customerManage/model"
	"go_code/customerManage/service"
)

type customerView struct {
	key string
	loop bool
	customerService *service.CustomerService
	
}

func (view *customerView) list() {
	customers := view.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 (view *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 := model.NewCustomer2(name,gender,age,phone,email)

	if view.customerService.Add(customer) {
		fmt.Println("-----添加完成-----")
	} else {
		fmt.Println("-----添加失败-----")
	}
}

func (view *customerView) update() {
	fmt.Println("-----修改用户-----")
	fmt.Println("请选择待修改的客户编号(-1退出): ")
	id := -1
	fmt.Scanln(&id)
	if id == -1 {
		return
	}
	
	if view.customerService.Update(id) {
		fmt.Println("-----修改完成-----")
	} else {
		fmt.Println("-----修改失败,未找到为此id的用户-----")
	}
}

func (view *customerView) delete() {
	fmt.Println("-----删除客户-----")
	fmt.Println("请选择待删除客户的编号(-1退出):")
	id := -1
	fmt.Scanln(&id)
	if id == -1 {
		return
	}
	
	choice := ""
	for {
		fmt.Println("确认是否删除(Y/N): ")
		fmt.Scanln(&choice)
		if choice == "y" || choice == "Y" {
			if view.customerService.Delete(id) {
				fmt.Println("-----删除完成-----")
				return
			} else {
				fmt.Println("----删除失败,输入的id号不存在-----")
				return
			}
		} else if choice == "n" || choice == "N"  {
			fmt.Println("-----取消删除-----")
			return
		} else {
			continue
		}
	}
}


func (view *customerView) exit() {
	fmt.Println("确认是否退出(Y/N): ")
	for {
		fmt.Scanln(&view.key)
		if view.key == "Y" || view.key == "y" || view.key == "N" || view.key == "n" {
			break	
		}
		fmt.Println("你的输入有误,确认是否退出(Y/N): ")
	}
	if view.key == "Y" || view.key == "y" {
		view.loop = false
	}
}

func (view *customerView) mainMenu() {
	for {
		fmt.Println("----客户信息管理软件----")
		fmt.Println(" 1 添加客户")
		fmt.Println(" 2 修改客户")
		fmt.Println(" 3 删除客户")
		fmt.Println(" 4 客户列表")
		fmt.Println(" 5 退 出")
		fmt.Print("请选择(1-5): ")
		fmt.Scanln(&view.key)

		switch view.key {
		case "1":
			view.add()
		case "2":
			view.update()
		case "3":
			view.delete()
		case "4":
			view.list()
		case "5":
			view.exit()
		default:
			fmt.Println("你的输入有误,请重新输入")	
		}
		if !view.loop {
			break
		}
	}
	fmt.Println("你退出了客户关系管理系统..")
}

func main() {
	customerView := customerView {
		key: "",
		loop: true,
	}
	customerView.customerService = service.NewCustomerService()

	customerView.mainMenu()
}
end
  • 作者:AWhiteElephant(联系作者)
  • 发表时间:2022-05-26 15:56
  • 版权声明:自由转载-非商用-非衍生-保持署名(创意共享3.0许可证)
  • 转载声明:如果是转载栈主转载的文章,请附上原文链接
  • 评论