在GO中使用构建器的继承

在GO中使用构建器的继承,第1张

在GO中使用构建器的继承

SOLID 的第一条原则说一段代码应该只承担一个责任。

发生在该背景下,它确实是没有意义的,任何

builder
关心
copy
zip
构建过程的一部分。这超出了
builder
责任。即使使用合成(嵌入)也不够整洁。

Builder
顾名思义,缩小范围,其核心职责是构建代码。但更具体地说,
Builder
的责任是在路径上构建代码。什么路 最惯用的方法是
当前路径工作目录 。这会在接口中添加两个方法:
Path() string
返回 当前路径
ChangePath(newPath string) error
更改 当前路径
。该方法很简单,保留一个字符串字段,因为当前路径通常可以完成此工作。而且它可以轻松地扩展到某些远程过程。

如果我们仔细地看一下,这无疑是两个 构建 概念。一个是整个构建 过程 ,从制作temp目录到将其复制回去,全部五个步骤。另一个是build
命令 ,这是该过程的第三步。

那是非常鼓舞人心的。就像传统的程序编程一样,过程是作为功能呈现的过程。因此,我们编写了一个

Build
函数。它序列化了所有5个步骤,简单而又简单。

码:

package mainimport (    "io/ioutil")//A builder is what used to build the language. It should be able to change working dir.type Builder interface {    Build() error //Build builds the pre at current dir. It returns an error if failed.    Path() string //Path returns the current working dir.    ChangePath(newPath string) error //ChangePath changes the working dir to newPath.}//TempDirFunc is what generates a new temp dir. Golang woould requires it in GOPATH, so make it changable.type TempDirFunc func() stringvar DefualtTempDirFunc = func() string {    name,_ := ioutil.TempDir("","BUILD")    return name}//Build builds a language. It copies the pre to a temp dir generated by mkTempdir//and call the Builder.ChangePath to change the working dir to the temp dir. After//the copy, it use the Builder to build the pre, and then zip it in the tempfile,//copying the zip file to `toPath`.func Build(b Builder, toPath string, mkTempDir TempDirFunc) error {    if mkTempDir == nil {        mkTempDir = DefaultTempDirFunc    }    path,newPath:=b.Path(),mkTempDir()    defer removeDir(newPath) //clean-up    if err:=copyDir(path,newPath); err!=nil {        return err    }    if err:=b.ChangePath(newPath) !=nil {        return err    }    if err:=b.Build(); err!=nil {        return err    }    zipName,err:=zipDir(newPath) // I don't understand what is `dep`.    if err!=nil {         return err    }    zipPath:=filepath.Join(newPath,zipName)    if err:=copyFile(zipPath,toPath); err!=nil {        return err    }    return nil}//zipDir zips the `path` dir and returns the name of zip. If an error occured, it returns an empty string and an error.func zipDir(path string) (string,error) {}//All other funcs is very trivial.

大部分的东西都涵盖在评论,我真的很砍伐懒得所有写那些

copyDir
/
removeDir
东西。在设计部分中没有提到的一件事是
mkTempDir
功能。如果代码位于
/tmp/xxx/
之外
GOPATH
,那么Golang会感到不满意,并且由于更改代码
GOPATH
会破坏导入路径服务,因此更改时会遇到更多麻烦,因此golang需要使用唯一的函数才能在中生成临时目录
GOPATH

编辑:

哦,我忘了说一件事。像这样处理错误是非常丑陋和不负责任的。但是这个想法就在那里,而且更体面的错误处理主要需要使用内容。因此,请自己进行更改,记录日志,出现紧急情况或您想要的任何内容。

编辑2:

您可以按以下方式重新使用您的npm示例。

type Node struct {    path string}func (n Node) Build(path string) error {    //e.g. Run npm install which build's nodejs project    command := exec.Command("npm", "install")    command.Dir = n.path    Combined, err := command.CombinedOutput()    if err != nil {        log.Println(err)    }    log.Printf("%s", Combined)    return nil}func (n *Node) ChangePath(newPath string) error {    n.path = newPath}func (n Node) Path() string {    return n.path}

并将其与其他语言结合在一起:

func main() {    path := GetPathFromInput()    switch GetLanguageName(path) {    case "Java":        Build(&Java{path},targetDirForJava(),nil)    case "Go":        Build(&Golang{path,cgoOptions},targetDirForGo(),GoPathTempDir()) //You can disable cgo compile or something like that.    case "Node":        Build(&Node{path},targetDirForNode(),nil)    }}

一种技巧是获取语言名称。

GetLanguageName
应该返回代码
path
所使用的语言的名称。这可以通过使用
ioutil.ReadDir
检测文件名来完成。

还要注意,尽管我使

Node
结构非常简单,只存储一个
path
字段,但是您可以轻松扩展它。就像
Golang
部分一样,您可以在此处添加构建选项。

编辑3:

关于包装结构:

首先,我实际上认为所有内容:

Build
函数,语言构建器和其他util /
helpers应该放在一个包中。它们都是为一项任务而工作:建立一种语言。没有必要,几乎没有期望将任何代码段隔离为另一个(子)程序包。

因此,这意味着一个目录。剩下的确实是一些非常个人化的风格,但我会分享我的:

我会将函数

Build
和接口
Builder
放入一个名为的文件中
main.go
。如果前端代码极少且可读性强,我也会将它们放入其中
main.go
,但是如果前端代码很长且具有某些ui逻辑,则根据实际代码将其放入
front-end.go
or
cli.go
ui.go
or中。

接下来,对于每种语言,我将

.go
使用语言代码创建一个文件。这清楚表明我可以在哪里检查它们。或者,如果代码真的很小,那么将它们全部组合到一个中也不是坏主意
builders.go
。毕竟,现代编辑器不仅仅具有定义结构和类型的能力。

最后,所有的

copyDir
zipDir
功能都到了
util.go
。这很简单-它们是实用程序,大多数时候我们只是不想打扰它们。



欢迎分享,转载请注明来源:内存溢出

原文地址: https://outofmemory.cn/zaji/5010254.html

(0)
打赏 微信扫一扫 微信扫一扫 支付宝扫一扫 支付宝扫一扫
上一篇 2022-11-14
下一篇 2022-11-14

发表评论

登录后才能评论

评论列表(0条)

保存