寒假总结

Git的使用

Git的工作方式

分为集中式工作流、功能分支工作流、Gitflow工作流和Forking,其中集中式工作流和功能分支工作流是已经使用过的,Gitflow和Forking两种工作流暂时没有使用过。

  1. 集中式工作流:一个远程仓库,一个主分支master,团队每个成员都有一个本地仓库,在本地仓库中进行代码的编辑、暂存和提交工作:

    git add <some file> 或 git add .>
    //`some file`代表要暂存的文件,`.`代表工作目录下的所有文件
    gie commit -m "一些描述"
    //提交文,描述指的是本次提交修改了什么功能或者修改了什么bug,方便以后的查看
    git push origin master
    //发布本地仓库到远程的中央仓库中,origin是远程仓库名,master是参数告诉Git的分支,master代表主分支,当然分支可以不是主分支

    注意:在一种情况下push命令会出错,即如果小明第一次发布代码到远程仓库,此时小红在本地开发自己的功能,那么在小红push自己的本地库到远程的时候会报错,原因是小红的本地库和远程库有分歧,需要先pull远程库到本地,与本地库合并之后再push到远程库。

  2. 功能分支工作流:在集中式工作流的基础上,为各个新功能分配一个专门的分支来开发,即在master主分支外在创建一个分支,程序员开发的新功能全部push到此分支上,等到功能成熟的时候再把此分支合并到主分支master上

    git checkout -b newbranch master
    //checkout代表创建切换带新分支newbranch
    //-b代表如果新分支不存在则会创建一个新分支
    //最后的master代表新分支是基于主分支创建的

    新分支创建之后,对其的编辑、暂存和提交工作与之前一样,对其push的命令变为git push origin newbranch,等到新功能完善之后,通过以下命令:

    git checkout master
    git pull
    git pull origin newbranch
    git push

    首先git checkout master切换到主分支,然后执行git pull把本地仓库的主分支上传到远程库,再执行git pull origin newbranch保证合并newbranch分支和已经和远程一致的本地master分支,你可以使用简单git merge marys-feature命令,但前面的命令可以保证总是最新的新功能分支。 最后把更新的master分支重新push到远程库。

  3. Gitflow工作流:除了有master主分支(用于存储正式发布的历史)外,还有一个作为功能集成分支的develop分支。

    • 当初始化完成后,某个程序员想要开发一个性能,并不是直接从master分支上拉出新分支,而是使用develop分支作为父分支,当新功能完成后,再合并会父分支,新功能的提交并不与master分支直接交互
  4. Forking工作流:是分布式工作流,充分利用了Git在分支和克隆上的优势,既可以管理大团队的开发者(developer)和接受不信任贡献者(contributor)的提交。这种工作流使得每个开发者都有一个服务端仓库(此仓库只有自己可以push,但是所有人都可以pull修改),每个程序员都push代码到自己的服务端仓库,但不能push到正式仓库,只有项目维护者才能push到正式仓库,这样项目维护者可以接受任何开发者的提交,但无需给他正式代码库的写权限。

    • 这种工作流适合网上开源社区的开源项目,大家统一对项目做贡献,但是有一个人或一个团队作为开发者来管理项目,所有的贡献者的代码由开发者审核,其功能完善之后再由开发者push到正式仓库中。

Pull Request

  • Pull Request是一个为讨论提交功能的专门论坛,是一个友好的web界面(在个人github项目中也有这样一个选项),大家在其中做一些Code Review的工作,把结果反馈到Pull Request中,还可以在其中push新的提交微调功能,等到讨论结束后醒目维护者合并所有的功能到官方仓库中,关闭Pull Request。
  • 发起一个Pull Request,就是要请求另一个开发者来pull自己仓库的一个分支到它的仓库中,因此需要提供四个信息:源仓库、源分支、目的仓库、目的分支。
  • Pull Request可以用于上述除了集中式工作流的其他三种工作流,因为其要求要么分支不同,要么仓库不同,而集中式工作流只有一个仓库,一个master分支。

重构代码

  • 在寒假和第一周的时间里,自己从头开始,使用golang+beego写了一个自己的博客系统,通过重写一遍后台管理系统的过程中,参考别人的成熟并优雅的设计,对自己以前的代码重构有着一些想法。

models文件夹

初始化文件init.go
  • 此文件包含了beego的Orm初始化,包括:
//set defalut database
orm.RegisterDataBase("default", _DB_DRIVER, _DB_CONNECT_STR)

// register model
orm.RegisterModel(new(User), new(Article), new(Label))

// create table
orm.RunSyncdb("default", false, true)

其中_DB_DRIVER = "mysql",是数据库名字,_DB_CONNECT_STR="root:golang@/myblog?charset=utf8",root代表mysql的用户名,golang为其密码,@/之后的myblog为mysql中此项目的数据库名字,charset=utf8代表编码方式为utf8。注意:此时如果数据库中有关于时间相关的字段存入时,会发现存入的时间与实际的时间出入8个小时,原因见 Beego的ORM插入Mysql后,时区不一致的解决方案

  • 由于是初始化文件,因此最好包含初始化部分,为别人的使用留下方便,因为别人第一次使用你的系统的时候,首先他的数据库是空的,即user表中没有数据,其次对你的用户添加模式并不了解。下载的模板就是看了半天才发现其初始化是怎么做的。

  • 如何使其生效?在main.go中写初始化函数,在此函数中调用它。

func init() {
    models.Init()
}
其余文件(以user.go为例)
  • 最主要的是增删改查功能(以查找函数为例)
//以前的做法
//通过用户名查找用户
func (this *User) GetByUserName(UserName string) (*User, error) {
    user := &User{}
    o := orm.NewOrm()
    err := o.QueryTable(_USER_TABLE).Filter("UserName", UserName).One(user)
    if err != nil {
        return nil, err
    }
    return user, nil
}
//通过用户Id查找用户
func (this *User) UserGetById(Id int64) (*User, error) {
    user := new(User)
    err := orm.NewOrm().QueryTable(_USER_TABLE).Filter("id", Id).One(user)
    if err != nil {
        return nil, err
    }
    return user, nil
}
//现在的做法
func (u *User) Read(fields ...string) error {
    if err := orm.NewOrm().Read(u, fields...); err != nil {
        return err
    }
    return nil
}

通过以上的函数可以看出来,以前的做法是先构造一个用户(可能是通过前端的信息获得,也可能是通过Session获得登录用户),再通过其用户名或者用户Id与数据库中的数据比对,再去判断是否有此用户,有则返回此用户,错误为空;否则用户为空,错误非空。
而现在更成熟的做法是:构造一个用户之后,直接调用user.Read()函数,如果返回为空,证明此用户是合法的,直接对其进行后续的操作就可以了,否则此用户不合法,进行相应处理。

if uesr.Read()==nil{
  //用户合法
} else {
  //用户不合法,重新登录
}
  • mysql的表之间的关联:之前是利用Orm的便利,直接利用orm:"rel(m2m)"orm:"reverse(many)"来表示关联表,但其实mysql本身的索引index也可以实现相应的功能,但是这样的话中间表需要自己手动建立,这方面的知识留待后续了解使用。

controllers文件夹

  • 所有的控制文件都以*Controller.go结尾,用以和models中的同名文件冲突,例如BaseController.go等。
  • 写一个BaseController.go文件,其中的控制器BaseController继承beego.Controller,剩余的所有控制器都继承此控制器,这样做的好处是可以把一些公共的,大家都用得到的函数写到里面,比如说CheckLogin()函数,即登录验证,这样就不用每个控制函数里面都写一个登录验证函数了。其调用部分写在BaseController.go文件的Prepare()里面,这样就不用在每个控制器函数文件中调用了,真正的一劳永逸。

views文件夹

  • 根据页面功能的不同,可以将HTML文件放入到不同的文件夹中去,这样寻找起来就非常方便。
  • 不必每个HTML文件都完全的有headbody等,这些有多个页面同时共享的部分都可以写到一个页面layout.html中,然后在相应的控制器函数中多写一句this.Layout="layout.html"即可,可以使得页面的HTML文件大大简化,也使得其修改变得很方便beego的Layout设计
  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值