douba7784 2016-06-28 14:30
浏览 41
已采纳

Golang。 重构|| 图案|| 任何解决方案

Problem: There is a list of tables associated keys. It is necessary to implement CRUD for each table + some functional on the specifics of the table (pagination, etc.). Troubles: duplicated in each of the functional implementation for each table About 50% of the code. Question: What are the ways on the specifics of the language, of the optimization / refactoring / use similar code patterns?

Example code part

//------------------------------------------------------------------
//  user
//----------------------------------------------------------------------
func (d *Database) UserCreate(email, password, username string, role int) *Answer {
    //variables
    answer := d.initCall("UserCreate")
    user := new(User)
    //check exist user
    if userExist := d.DB.Find(&User{}, &User{Email:email}).Error; userExist == nil {
        answer.AnswerJSON.ErrorAnswer.Message = "[usercreate] user already exist"
        answer.AnswerJSON.Result = nil
        answer.AnswerJSON.Status = false
    } else {

        userinfo := UserInfo{Data:time.Now()}
        session := Session{Data:time.Now()}
        cook := Cook{}

        //make support  tables object
        //userinfo object
        userinfo.Password = password
        userinfo.Username = username
        //cook object
        cook.SessionID = session.ID
        cook.Cookie = d.cookgeneratenew("somesaltforcooksgenerate")
        cook.Status = true
        cook.Lastconnect = time.Now()
        cook.CountConnect += 1

        //user object
        user.Email = email
        user.Session = session
        user.UserInfo = userinfo
        user.Cook = cook
        user.Role = int64(role)

        //make request + //serizlizations to json answer
        if err := d.DB.Create(user).Error; err != nil {
            answer.AnswerJSON.ErrorAnswer.Message = err.Error()
            answer.AnswerJSON.Status = false
        } else {
            answer.AnswerJSON.Result = user
            answer.AnswerJSON.Status = true
        }
    }
    d.serilize(answer)
    return answer
}
func (d *Database) UserDelete(userid int64) *Answer {
    answer := d.initCall("UserDelete")
    user := new(User)
    //check exists
    if userExists := d.DB.Find(user, "ID = ?", userid).Error; userExists == nil {
        if userDelete := d.DB.Delete(user).Error; userDelete != nil {
            answer.AnswerJSON.ErrorAnswer.Message = userExists.Error()
            answer.AnswerJSON.Status = false
        } else {
            answer.AnswerJSON.Status = true
            answer.AnswerJSON.ErrorAnswer = nil
        }
    } else {
        answer.AnswerJSON.ErrorAnswer.Message = userExists.Error()
        answer.AnswerJSON.Status = false
    }
    d.serilize(answer)
    return answer
}
func (d *Database) UserRead(userid int64) *Answer {
    answer := d.initCall("UserRead")
    user := new(User)
    if userExists := d.DB.Find(user, "ID = ?", userid).Error; userExists != nil {
        answer.AnswerJSON.ErrorAnswer.Message = userExists.Error()
        answer.AnswerJSON.Status = false
    } else {
        if rel := d.DB.Model(user).Related(&user.Session).Error; rel != nil {
            answer.AnswerJSON.Result = nil
            answer.AnswerJSON.ErrorAnswer.Message = rel.Error()
            answer.AnswerJSON.Status = false
        } else if rel = d.DB.Model(user).Related(&user.UserInfo).Error; rel != nil {
            answer.AnswerJSON.Result = nil
            answer.AnswerJSON.ErrorAnswer.Message = rel.Error()
            answer.AnswerJSON.Status = false
        } else if rel = d.DB.Model(user).Related(&user.Cook).Error; rel != nil {
            answer.AnswerJSON.Result = nil
            answer.AnswerJSON.ErrorAnswer.Message = rel.Error()
            answer.AnswerJSON.Status = false
        } else {
            answer.AnswerJSON.Result = user
            answer.AnswerJSON.ErrorAnswer = nil
            answer.AnswerJSON.Status = true
        }
    }
    d.serilize(answer)
    return answer
}
func (d *Database) UserReadAll() *Answer {
    answer := d.initCall("UserReadAll")
    users := []User{}

    if usersGet := d.DB.Find(&users).Error; usersGet != nil {
        answer.AnswerJSON.ErrorAnswer.Message = usersGet.Error()
        answer.AnswerJSON.Status = false
    } else {
        for _, user := range users {
            d.DB.Model(user).Related(&user.Session)
            d.DB.Model(user).Related(&user.UserInfo)
            d.DB.Model(user).Related(&user.Cook)
        }
        answer.AnswerJSON.Result = users
        answer.AnswerJSON.ErrorAnswer = nil
        answer.AnswerJSON.Status = true
    }
    d.serilize(answer)
    return answer
}
func (d *Database) UserUpdate(userid int64, uu *UserUpdateStruct) *Answer {
    answer := d.initCall("UserUpdate")
    user := new(User)

    if userExists := d.DB.Find(user, "ID = ?", userid).Error; userExists != nil {
        answer.AnswerJSON.ErrorAnswer.Message = userExists.Error()
        answer.AnswerJSON.Status = false
    } else {
        //get relevating struct info
        d.DB.Model(user).Related(&user.Session)
        d.DB.Model(user).Related(&user.UserInfo)
        d.DB.Model(user).Related(&user.Cook)

        //update columns
        if uu.Email != "" {
            user.Email = uu.Email
        }
        if uu.Avatar > 0 {
            user.UserInfo.Avatar = uu.Avatar
        }
        if uu.Birthday != "" {
            user.UserInfo.Birthday = uu.Birthday
        }
        if uu.Location != "" {
            user.UserInfo.Location = uu.Location
        }
        if uu.Male != "" {
            user.UserInfo.Male = uu.Male
        }
        if uu.Password != "" {
            user.UserInfo.Password = uu.Password
        }
        if uu.Role > 0 {
            if roleErr := d.DB.Find(&Role{}).Error; roleErr != nil {
                //role not found
                fmt.Printf("[userupdate] role not found `%d`
", uu.Role)
            } else {
                user.Role = uu.Role
            }
        }

        //update
        if errUpdate := d.DB.Save(user).Error; errUpdate != nil {
            answer.AnswerJSON.ErrorAnswer.Message = errUpdate.Error()
            answer.AnswerJSON.Status = false
        } else {
            answer.AnswerJSON.Result = user
            answer.AnswerJSON.ErrorAnswer = nil
            answer.AnswerJSON.Status = true
        }
    }
    d.serilize(answer)
    return answer
}
func (d *Database) UserPaginate(page, countPage int) *Answer {
    answer := d.initCall("UserPaginate")
    result := []*User{}
    if errPag := d.DB.Limit(countPage).Offset((page * countPage) - countPage).Find(&result).Error; errPag != nil {
        answer.AnswerJSON.ErrorAnswer.Message = errPag.Error()
        answer.AnswerJSON.Status = false
    } else {
        for _, user := range result {
            d.DB.Model(&user).Related(&user.Session)
            d.DB.Model(&user).Related(&user.UserInfo)
            d.DB.Model(&user).Related(&user.Cook)
        }
        answer.AnswerJSON.Result = result
        answer.AnswerJSON.ErrorAnswer = nil
        answer.AnswerJSON.Status = true
    }
    d.serilize(answer)
    return answer
}
//-------------------------------------------------------------------
//  category
//--------------------------------------------------------------------
func (d *Database) CategoryCreate(name string) *Answer {
    //variables
    answer := d.initCall("CategoryCreate")
    cat := new(Category)
    //check exist user
    if catExist := d.DB.Find(&Category{}, &Category{Name:name}).Error; catExist == nil {
        answer.AnswerJSON.ErrorAnswer.Message = "[categorycreate] category already exist"
        answer.AnswerJSON.Result = nil
        answer.AnswerJSON.Status = false
    } else {
        cat.Name = name
        //make request + //serizlizations to json answer
        if err := d.DB.Create(cat).Error; err != nil {
            answer.AnswerJSON.ErrorAnswer.Message = err.Error()
            answer.AnswerJSON.Status = false
        } else {
            answer.AnswerJSON.Result = cat
            answer.AnswerJSON.Status = true
        }
    }
    d.serilize(answer)
    return answer
}
func (d *Database) CategoryDelete(catid int64) *Answer {
    answer := d.initCall("CategoryDelete")
    cat := new(Category)
    //check exists
    if catExists := d.DB.Find(cat, "ID = ?", catid).Error; catExists == nil {
        if catDelete := d.DB.Delete(cat).Error; catDelete != nil {
            answer.AnswerJSON.ErrorAnswer.Message = catExists.Error()
            answer.AnswerJSON.Status = false
        } else {
            answer.AnswerJSON.Status = true
            answer.AnswerJSON.ErrorAnswer = nil
        }
    } else {
        answer.AnswerJSON.ErrorAnswer.Message = catExists.Error()
        answer.AnswerJSON.Status = false
    }
    d.serilize(answer)
    return answer
}
func (d *Database) CategoryRead(catid int64) *Answer {
    answer := d.initCall("CategoryRead")
    cat := new(Category)
    if catExists := d.DB.Find(cat, "ID = ?", catid).Error; catExists != nil {
        answer.AnswerJSON.ErrorAnswer.Message = catExists.Error()
        answer.AnswerJSON.Status = false
    } else {
        if rel := d.DB.Model(cat).Related(&cat.Post).Error; rel != nil {
            answer.AnswerJSON.Result = nil
            answer.AnswerJSON.ErrorAnswer.Message = rel.Error()
            answer.AnswerJSON.Status = false
        } else {
            for x, p := range cat.Post {
                d.DB.Model(&p).Related(&p.Comment)
                d.DB.Model(&p).Related(&p.PostSeo)
                cat.Post[x] = p
            }
            answer.AnswerJSON.Result = cat
            answer.AnswerJSON.ErrorAnswer = nil
            answer.AnswerJSON.Status = true
        }
    }
    d.serilize(answer)
    return answer
}
func (d *Database) CategoryReadAll() *Answer {
    answer := d.initCall("CategoryReadAll")
    cats := []Category{}

    if catsGet := d.DB.Find(&cats).Error; catsGet != nil {
        answer.AnswerJSON.ErrorAnswer.Message = catsGet.Error()
        answer.AnswerJSON.Status = false
    } else {
        //categorys
        for _, cat := range cats {
            d.DB.Model(cat).Related(&cat.Post)
            //get relete POST
            for x, p := range cat.Post {
                d.DB.Model(&p).Related(&p.Comment)
                d.DB.Model(&p).Related(&p.PostSeo)
                cat.Post[x] = p
            }
        }
        answer.AnswerJSON.Result = cats
        answer.AnswerJSON.ErrorAnswer = nil
        answer.AnswerJSON.Status = true
    }
    d.serilize(answer)
    return answer
}
func (d *Database) CategoryUpdate(catid int64, name string) *Answer {
    answer := d.initCall("CategoryUpdate")
    cat := new(Category)

    if catExists := d.DB.Find(cat, "ID = ?", catid).Error; catExists != nil {
        answer.AnswerJSON.ErrorAnswer.Message = catExists.Error()
        answer.AnswerJSON.Status = false
    } else {
        //get relevating struct info
        d.DB.Model(cat).Related(&cat.Post)

        //update columns
        if name != "" {
            cat.Name = name
        }
        //update
        if errUpdate := d.DB.Save(cat).Error; errUpdate != nil {
            answer.AnswerJSON.ErrorAnswer.Message = errUpdate.Error()
            answer.AnswerJSON.Status = false
        } else {
            answer.AnswerJSON.Result = cat
            answer.AnswerJSON.ErrorAnswer = nil
            answer.AnswerJSON.Status = true
        }
    }
    d.serilize(answer)
    return answer
}
func (d *Database) CategoryPaginate(page, countPage int) *Answer {
    answer := d.initCall("CategoryPaginate")
    result := []*Category{}
    if errPag := d.DB.Limit(countPage).Offset((page * countPage) - countPage).Find(&result).Error; errPag != nil {
        answer.AnswerJSON.ErrorAnswer.Message = errPag.Error()
        answer.AnswerJSON.Status = false
    } else {
        for _, cat := range result {
            d.DB.Model(&cat).Related(&cat.Post)
            //get relete POST
            for x, p := range cat.Post {
                d.DB.Model(&p).Related(&p.Comment)
                d.DB.Model(&p).Related(&p.PostSeo)
                cat.Post[x] = p
            }
        }
        answer.AnswerJSON.Result = result
        answer.AnswerJSON.ErrorAnswer = nil
        answer.AnswerJSON.Status = true
    }
    d.serilize(answer)
    return answer
}
  • 写回答

2条回答 默认 最新

  • dongmiyu8979 2016-06-28 14:48
    关注

    I can see you have a lot of redundancy in your code. Few months back I had a same problem and have great answer. Take a look at here: How to return dynamic type struct in Golang?.

    Basically you will have same three functions(add/edit/delete/count) like this (i do not know what db are you using I use NoSql Rethinkdb, but the principle is same):

    func (c Main) Get(modelname string) interface{} {
    
       //your query here for getting stuff from model name and return interface
    
       rows, err := rethink.Table(modelname).OrderBy(rethink.Asc("sortNo")).Run(c.DB)
       if err != nil {
           log.Println(err)
           return nil
       }
    
       if (modelType == "brand") {
    
           var brands  []*models.Brand
           rows.All(&brands)
    
           return brands
    
       }
       //rest of your models here or use some switch
    })
    

    I usually put all my functions that are doing stuff with database in some helper (this is mostly because of tests).

    I think this is good directions because like this you code is easy to maintain and you will be changing only helper functions instead of going to million fictions that are doing add/delete/update for every model.

    本回答被题主选为最佳回答 , 对您是否有帮助呢?
    评论
查看更多回答(1条)

报告相同问题?

悬赏问题

  • ¥15 全部备份安卓app数据包括密码,可以复制到另一手机上运行
  • ¥15 Python3.5 相关代码写作
  • ¥20 测距传感器数据手册i2c
  • ¥15 RPA正常跑,cmd输入cookies跑不出来
  • ¥15 求帮我调试一下freefem代码
  • ¥15 matlab代码解决,怎么运行
  • ¥15 R语言Rstudio突然无法启动
  • ¥15 关于#matlab#的问题:提取2个图像的变量作为另外一个图像像元的移动量,计算新的位置创建新的图像并提取第二个图像的变量到新的图像
  • ¥15 改算法,照着压缩包里边,参考其他代码封装的格式 写到main函数里
  • ¥15 用windows做服务的同志有吗