一、代码实现分析
1、第1步 — 实现Customer结构体
- 按照设计要求编写Customer结构体,并编译
- 在Customer 结构体中临时添加一个main方法中,作为单元测试方法。
在方法中创建Customer对象,并调用对象的各个方法,以测试该类是否编写正确。
2、第2步 — 实现CustomerService结构体
- 按照设计要求编写CustomerService结构体,并编译
- 在CustomerService结构体中临时添加一个main方法中,作为单元测试方法。
- 在方法中创建CustomerService对象(最多存放5个客户对象),然后分别用模拟数据调用以下各个方法,以测试各方法是否编写正确:
– addCustomer
– replaceCustomer
– deleteCustomer
– getAllCustomers
– getCustomer
- 进一步测试以下情况,以验证该类是否编写正确:
– 调用addCustomer方法,添加至5个以上客户对象时
– 当数组中客户对象数量为0时,仍然调用replaceCustomer方法替换对象
– 当数组中客户对象数量为0时,仍然调用deleteCustomer方法删除对象
– 对于replaceCustomer、 deleteCustomer和getCustomer的调用,当参数index的值无效时(例如-1或6)
– getAllCustomers方法返回的数组长度是否与实际的客户对象数量一致
3、第3步 — 实现CustomerView
- 按照设计要求编写CustomerView,逐一实现各个方法,并编译
- 执行main方法中,测试以下功能:
– 主菜单显示及操作是否正确
– “添加客户”操作是否正确,给用户的提示是否明确合理;测试当添加的客户总数超过10时,运行是否正确
– “修改客户”操作是否正确,给用户的提示是否明确合理;
– “删除客户”操作是否正确,给用户的提示是否明确合理;
– “客户列表”操作是否正确,表格是否规整;
- 数据保存:
– 当软件退出时,将所有客户信息长久保存,以便在下一次运行软件时继续使用。
二、完整代码
control/server.go
package control
import (
_"strings"
_"fmt"
"go_code/softwaredev/customer/code/model"
)
//CustomerService结构体用于处理Model数据
type CustomerService struct{
//新建Customer切片存储客户信息
customers []model.Customer
num int
}
func (this *CustomerService) GetID() []model.Customer {
return this.customers
}
//新建 CustomerService方法,便于view使用
func CreateCustomerService() *CustomerService {
var cs CustomerService
//初始化一个数据
cs.num++
initCustomer := model.CreateCustomer(cs.num, "张三", "男", 20, "110", "zs@sohu.com")
cs.customers = append(cs.customers,initCustomer)
return &cs
}
func (this *CustomerService)UserLists() []model.Customer{
return this.customers
}
func (this *CustomerService)QuaryUserByID(id int) (flag bool,cs model.Customer) {
id = this.findIDByIndex(id)
if id == -1 {
flag = false
}else{
flag = true
cs = this.customers[id]
}
return
}
func (this *CustomerService)QuaryUserByName(isbulrry bool,name string) (flag bool,cs []model.Customer) {
r :=[]rune(name)
if isbulrry {//模糊查询 [u4e00-u9fa5]
for _,value:= range this.customers {
//搜索中文
res := value.GetName()
for _,val:= range res {
// fmt.Println("val=",val)
// fmt.Println("name=",[]rune(name))
for i := 0; i < len(r); i++ {
// fmt.Println("r[i]=",r[i])
if val == r[i] {
flag = true
break
}else{
flag = false
}
}
if flag {
break
}
}
if flag {
cs = append(cs,value)
}
//只能搜索英文
// if strings.Contains(value.GetName(),name) {
// cs = append(cs,value)
// flag = true
// }else{
// flag = false
// }
}
}else{//标准查询
for _,value:= range this.customers {
if value.GetName() == name {
cs = append(cs,value)
flag = true
break
}else{
flag = false
}
}
}
return
}
func (this *CustomerService)DeleteUser(index int) bool {
index = this.findIDByIndex(index)
if index == -1 {
return false
}else{
this.customers = append(this.customers[:index],this.customers[index+1:]...)
return true
}
}
func (this *CustomerService)UpdateUser1(newCustomer *model.Customer) bool {
index := newCustomer.GetID()
index = this.findIDByID(index)
this.customers[index] = *newCustomer
return true
}
func (this *CustomerService)UpdateUser(newCustomer *model.Customer) bool {
index := newCustomer.GetID()
// fmt.Println("index:",index)
index = this.findIDByID(index)
// fmt.Println("index:",index)
if index == -1 {
return false
}else{
name := newCustomer.GetName()
if name != "" {
this.customers[index].SetName(name)
}
gender := newCustomer.GetGender()
if gender != "" {
this.customers[index].SetGender(gender)
}
age := newCustomer.GetAge()
if age != 0 {
this.customers[index].SetAge(age)
}
email := newCustomer.GetEmail()
if email != "" {
this.customers[index].SetEmail(email)
}
phone := newCustomer.GetPhone()
if phone != "" {
this.customers[index].SetPhone(phone)
}
return true
}
}
func (this *CustomerService)AddUser(newCustomer *model.Customer) bool {
this.num++
newCustomer.SetID(this.num)
this.customers = append(this.customers,*newCustomer)
return true
}
func (this *CustomerService)findIDByIndex(index int) (id int) {
for key,value:= range this.customers {
// fmt.Println("value:",value.GetID())
if value.GetID() == index {
id = key
break
}else{
id = -1
}
}
return
}
func (this *CustomerService)findIDByID(index int) (id int) {
res := -1
for key,value:= range this.customers {
// fmt.Println("value:",value.GetID())
res =value.GetID()
if res == index {
id = key
break
}else{
id = -1
}
}
return
}
model/Customer.go
package model
import (
"fmt"
)
//Customer结构体
type Customer struct {
Id int
Name string
Gender string
Age int
Phone string
Email string
}
//新建结构体的方法,相当于Java中构造函数
func CreateCustomer(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,
}
}
//客户信息显示,相当于Java中tosting 方法
func (this *Customer) CustomerInforShow() string {
str := 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 str
}
/*各个字段的get set方法*/
func (this *Customer) GetID() int {
return this.Id
}
func (this *Customer) SetID(id int) {
this.Id = id
}
func (this *Customer) GetName() string {
return this.Name
}
func (this *Customer) SetName(name string) {
this.Name = name
}
func (this *Customer) GetAge() int {
return this.Age
}
func (this *Customer) SetAge(age int) {
this.Age =age
}
func (this *Customer) GetGender() string {
return this.Gender
}
func (this *Customer) SetGender(gender string) {
this.Gender = gender
}
func (this *Customer) GetPhone() string {
return this.Phone
}
func (this *Customer) SetPhone(phone string) {
this.Phone = phone
}
func (this *Customer) GetEmail() string {
return this.Email
}
func (this *Customer) SetEmail(email string) {
this.Email = email
}
view/view.go
package view
import (
"encoding/json"
"io/ioutil"
"os"
"go_code/softwaredev/customer/code/model"
"go_code/softwaredev/customer/code/control"
"fmt"
"strings"
)
/*主界面实现:
1、主界面
-----------------客户信息管理软件-----------------
1 添 加 客 户
2 修 改 客 户
3 删 除 客 户
4 客 户 列 表
5 退 出
请选择(1-5):_
需求分析:
每个客户的信息被保存在Customer对象中。
以一个Customer类型的数组来记录当前所有的客户
每次“添加客户”(菜单1)后,客户(Customer)对象被添加到数组中。
每次“修改客户”(菜单2)后,修改后的客户(Customer)对象替换数组中原对象。
每次“删除客户”(菜单3)后,客户(Customer)对象被从数组中清除。
执行“客户列表 ”(菜单4)时,将列出数组中所有客户的信息
*/
/*
分析:
1、menu() 显示界面
2、for 循环实现重复执行的逻辑
3、switch 实现功能切换
*/
//CustomerView结构体,调用service的方法
type CustomerView struct{
cs *control.CustomerService
loop bool //功能选择
key string //是否退出系统标志
}
func CreateCustomerView() *CustomerView {
return &CustomerView{
cs : control.CreateCustomerService(),
loop : true ,
}
}
func (this *CustomerView)CustomerInforManger() {
for {
menuShow()
fmt.Scanln(&this.key)
switch this.key {
case "1":
this.addUser()
case "2":
// updateUser(this)
this.updateUser1()
case "3":
this.deleteUser()
case "4":
this.userList()
case "5":
this.quaryUser()
case "7":
this.saveExist()
case "8":
this.restoreData()
case "6":
this.exit()
default:
fmt.Println("输入有误!!!")
}
if !this.loop {
fmt.Println("你退出了客户关系管理系统...")
break
}
}
}
func (this *CustomerView)restoreData() {
customerData := restoreFileData()
// fmt.Println(str)
// this.details = str
// fmt.Println(len(customerData))
for _ ,value := range customerData {
this.cs.AddUser(&value)
}
}
func (this *CustomerView)saveExist() {
// 这里加入 提示是否退出,并要求是y/n
fmt.Println("你确定要退出吗? y/n")
var choice string
for {
fmt.Scanln(&choice)
//判断choice 是不是 y/n [Y/n]
choice = strings.ToLower(choice)
if choice == "y" || choice == "n" {
break
}
fmt.Println("你确定要退出吗? y/n")
}
if choice == "y" {
this.loop = false
customerData := this.cs.UserLists()
data, err := json.Marshal(&customerData)
if err != nil {
fmt.Println("序列化失败 err=", err)
return
}
// fmt.Println("序列化的字符串 = ",string(data))
// saveFileData(data)
SaveDBData(data)
}
}
//退出
func (this *CustomerView) exit() {
// 这里加入 提示是否退出,并要求是y/n
fmt.Println("你确定要退出吗? y/n")
var choice string
for {
fmt.Scanln(&choice)
//判断choice 是不是 y/n [Y/n]
choice = strings.ToLower(choice)
if choice == "y" || choice == "n" {
break
}
fmt.Println("你确定要退出吗? y/n")
}
//这里再去判断choice
if choice == "y" {
this.loop = false
}
}
func (this *CustomerView)deleteUser() {
index := -1
var isDelete string
fmt.Println("---------------------删除客户---------------------")
fmt.Println("请选择待删除客户编号(-1退出):")
fmt.Scanln(&index)
if index == -1 {
return
}
fmt.Println("确认是否删除(Y/N):")
for {
fmt.Scanln(&isDelete)
if strings.ToLower(isDelete) != "y" || strings.ToLower(isDelete) != "n" {
break
}
fmt.Println("确认是否删除(Y/N):")
}
if strings.ToLower(isDelete) == "y" {
if this.cs.DeleteUser(index) {
fmt.Println("---------------------删除完成---------------------")
}else {
fmt.Println("---------------------删除失败---------------------")
}
}else{
fmt.Println("---------------------删除失败---------------------")
}
}
func (this *CustomerView)quaryUser() {
fmt.Println("---------------------查询客户---------------------")
key := -1
fmt.Println("请选择查询客户方式(-1 退出, 0(ID)/1(name)):")
for {
fmt.Scanln(&key)
if key == 0 || key == 1 || key == -1{
break
}
fmt.Println("请选择查询客户方式(0(ID)/1(name)):")
}
if key == 0 {
index := -1
fmt.Println("请选择待查询客户编号:")
for {
fmt.Scanln(&index)
if index != -1 {
break
}
fmt.Println("请选择待查询客户编号:")
}
if index != -1{
flag,customerData := this.cs.QuaryUserByID(index)
if flag {
fmt.Println("编号\t姓名\t性别\t年龄\t电话\t邮箱")
fmt.Println(customerData.CustomerInforShow())
fmt.Println("---------------------查询客户完成---------------------")
}else {
fmt.Println("---------------------查询客户失败---------------------")
}
}
}
if key ==1 {
name := ""
isBlurry := "n"
fmt.Println("确认模糊查询(Y/N):")
for {
fmt.Scanln(&isBlurry)
if strings.ToLower(isBlurry) != "y" || strings.ToLower(isBlurry) != "n" {
break
}
fmt.Println("确认确认模糊查询(Y/N):")
}
flag := false
if strings.ToLower(isBlurry) =="y" {
flag = true
}
fmt.Println("请选择待查询客户姓名:")
for {
fmt.Scanln(&name)
if name != "" {
break
}
fmt.Println("请选择待查询客户姓名:")
}
isSucced,customerData := this.cs.QuaryUserByName(flag,name)
if isSucced {
fmt.Println("编号\t姓名\t性别\t年龄\t电话\t邮箱")
for _ ,value := range customerData {
fmt.Println(value.CustomerInforShow())
}
fmt.Println("---------------------查询客户完成---------------------")
}else{
fmt.Println("---------------------查询客户失败---------------------")
}
}
}
func (this *CustomerView)updateUser() {
index := -1
fmt.Println("---------------------修改客户---------------------")
fmt.Println("请选择待修改客户编号(-1退出):")
fmt.Scanln(&index)
if index == -1 {
return
}
var name,gender,phone,email string
var age int
fmt.Println("请输入姓名")
fmt.Scanln(&name)
fmt.Println("请输入性别(男/女)")
fmt.Scanln(&gender)
fmt.Println("请输入年龄")
fmt.Scanln(&age)
fmt.Println("请输入电话")
fmt.Scanln(&phone)
fmt.Println("请输入邮箱")
fmt.Scanln(&email)
Customers := model.CreateCustomer(index,name,gender,age,phone,email)
if this.cs.UpdateUser(&Customers) {
fmt.Println("---------------------修改完成---------------------")
}else{
fmt.Println("---------------------修改失败---------------------")
}
}
func (this *CustomerView)updateUser1() {
index := -1
fmt.Println("---------------------修改客户---------------------")
fmt.Println("请选择待修改客户编号(-1退出):")
fmt.Scanln(&index)
if index == -1 {
return
}
var name,gender,phone,email string
var age int
fmt.Println("请输入姓名")
fmt.Scanln(&name)
fmt.Println("请输入性别(男/女)")
fmt.Scanln(&gender)
fmt.Println("请输入年龄")
fmt.Scanln(&age)
fmt.Println("请输入电话")
fmt.Scanln(&phone)
fmt.Println("请输入邮箱")
fmt.Scanln(&email)
_,customerData := this.cs.QuaryUserByID(index)
if name == "" {
name =customerData.GetName()
}
if gender == "" {
gender = customerData.GetGender()
}
if age == 0 {
age = customerData.GetAge()
}
if email == "" {
email = customerData.GetEmail()
}
if phone == "" {
phone = customerData.GetPhone()
}
Customers := model.CreateCustomer(customerData.GetID(),name,gender,age,phone,email)
if this.cs.UpdateUser1(&Customers) {
fmt.Println("---------------------修改完成---------------------")
}else{
fmt.Println("---------------------修改失败---------------------")
}
}
func (this *CustomerView)addUser() {
fmt.Println("---------------------添加客户---------------------")
var name,gender,phone,email string
var age int
fmt.Println("请输入姓名")
fmt.Scanln(&name)
fmt.Println("请输入性别(男/女)")
fmt.Scanln(&gender)
fmt.Println("请输入年龄")
fmt.Scanln(&age)
fmt.Println("请输入电话")
fmt.Scanln(&phone)
fmt.Println("请输入邮箱")
fmt.Scanln(&email)
Customers := model.CreateCustomer(0,name,gender,age,phone,email)
if this.cs.AddUser(&Customers) {
fmt.Println("---------------------添加完成---------------------")
}else{
fmt.Println("---------------------添加失败---------------------")
}
}
func (this *CustomerView)userList() {
fmt.Println("---------------------------客户列表---------------------------")
fmt.Println("编号\t姓名\t性别\t年龄\t电话\t邮箱")
customerData := this.cs.UserLists()
for _ ,value := range customerData {
fmt.Println(value.CustomerInforShow())
}
fmt.Println("-------------------------客户列表完成-------------------------")
fmt.Print("\n\n")
}
func menuShow() {
fmt.Println("------------客户信息管理软件------------")
fmt.Println(" 1、添加用户")
fmt.Println(" 2、修改用户")
fmt.Println(" 3、删除用户")
fmt.Println(" 4、客户列表")
fmt.Println(" 5、用户查询")
fmt.Println(" 6、退出系统")
fmt.Println(" 7、保存客户信息退出")
fmt.Println(" 8、恢复客户信息")
fmt.Println(" 请选择(1-8)")
fmt.Println("--------------------------------------")
}
func saveFileData(details []byte)(){
filePath := "customer.txt"
//1、打开文件
file, err := os.OpenFile(filePath, os.O_RDWR | os.O_APPEND | os. O_CREATE,066) // For read access.
//2、关闭文件
defer file.Close()
CheckError(err)
// 3、写入数据
err = ioutil.WriteFile(filePath,details,066)
CheckError(err)
}
func restoreFileData() (customers []model.Customer){
filePath := "customer.txt"
//1、打开文件
file, err := os.OpenFile(filePath, os.O_RDWR | os.O_APPEND | os. O_CREATE,066) // For read access.
//2、关闭文件
defer file.Close()
CheckError(err)
//4、读取文件
res, err := ioutil.ReadFile(filePath)
CheckError(err)
res = ReadDBData()
err = json.Unmarshal(res, &customers)
if err != nil {
fmt.Println("unmarshal err=", err)
}
// fmt.Printf("反序列化struct: monster=%v\n", customers)
return
}
view/redis.go
package view
import (
"fmt"
"log"
"github.com/garyburd/redigo/redis"
_"log"
_"fmt"
)
func SaveDBData(data []byte) {
//1. 链接到redis
conn, err := redis.Dial("tcp", "localhost:6379")
CheckError(err)
defer conn.Close()
//2、通过go 向redis写入数据 string类型数据
fmt.Println(string(data))
_, err = conn.Do("set","customer",data)
CheckError(err)
}
func ReadDBData() (data []byte) {
//1. 链接到redis
conn, err := redis.Dial("tcp", "localhost:6379")
CheckError(err)
defer conn.Close()
//3. 通过go 向redis读取数据string类型数据
data, err = redis.Bytes(conn.Do("get","customer"))
CheckError(err)
fmt.Println(string(data))
return
}
//错误检查
func CheckError(err error) {
if err != nil {
log.Fatal(err)
panic(err)
}
}
main/main.go
package main
import (
"go_code/softwaredev/customer/code/view"
)
func main() {
var vcv *view.CustomerView
vcv = view.CreateCustomerView()
vcv.CustomerInforManger()
}