程序员社区

Golang建造者模式之-建造者参数

Golang建造者模式之-建造者参数插图

原文地址
在之前的博客中,我们讨论了建造者模式的结构。在这篇博客中,让我们来了解一下建造者参数。

为什么需要建造者参数

建造者参数帮助我们直接限制结构体属性和函数的使用。有时我们希望限制用户直接访问结构体的属性和函数。 我们为它们提供api。

直接上代码

假设,我们需要创建一个可以发送邮件的新功能,你不希望你的开发者破坏你的邮件对象。你用建造者参数隐藏它。

//RunBuilderParamter example
func RunBuilderParamter() {
    SendEmail(func(b *EmailBuilder) {
        b.
            To("World@gmail.com").
            From("me@gmail.com").
            Subject("Hello world").
            Body("Sample body for a dummy email")
    })
}

以上代码,我们使用一个辅助函数SendEmail,它接受一个func (action)作为参数,并执行一些成员函数,如To(value string),From(value string)等。

另外,请注意,我们不能访问email结构体,也不能访问发送电子邮件的实际发送函数。

我们首先创建一个私有结构体和一个私有函数:

type email struct {
    from, to, subject, body string
}

func sendEmail(email *email) {
    // logic to send email
    fmt.Println("email sent ...")
    fmt.Printf("To:%s,\nSubject:%s\n%s\nRegards,\n%s\n", email.to, email.subject, email.body, email.from)
}

现在我们定义建造者结构和辅助函数:

//EmailBuilder struct
type EmailBuilder struct {
    email email
}

type action func(builder *EmailBuilder)

//SendEmail function is for client to send email
func SendEmail(action action) {
    builder := EmailBuilder{}
    action(&builder)
    sendEmail(&builder.email)
}

最后,定义成员函数:

//To sets the email's "To" address
func (eb *EmailBuilder) To(value string) *EmailBuilder {
    //basic validation
    if !strings.Contains(value, "@") {
        panic("Invalid email")
    }
    eb.email.to = value
    return eb

}

//From sets the email's "From" address
func (eb *EmailBuilder) From(value string) *EmailBuilder {
    //basic validation
    if !strings.Contains(value, "@") {
        panic("Invalid email")
    }
    eb.email.from = value
    return eb
}

//Body sets the email's "Body"
func (eb *EmailBuilder) Body(value string) *EmailBuilder {
    eb.email.body = value
    return eb
}

//Subject sets the email's "Subject"
func (eb *EmailBuilder) Subject(value string) *EmailBuilder {
    eb.email.subject = value
    return eb
}

完整代码如下:

package main

import (
    "fmt"
    "strings"
)

// Example - Builder Parameter

type email struct {
    from, to, subject, body string
}

type action func(builder *EmailBuilder)

//EmailBuilder struct
type EmailBuilder struct {
    email email
}

func sendEmail(email *email) {
    // logic to send email
    fmt.Println("email sent ...")
    fmt.Printf("To:%s,\nSubject:%s\n%s\nRegards,\n%s\n", email.to, email.subject, email.body, email.from)
}

//SendEmail function is for client to send email
func SendEmail(action action) {
    builder := EmailBuilder{}
    action(&builder)
    sendEmail(&builder.email)
}

//To sets the email's "To" address
func (eb *EmailBuilder) To(value string) *EmailBuilder {
    //basic validation
    if !strings.Contains(value, "@") {
        panic("Invalid email")
    }
    eb.email.to = value
    return eb

}

//From sets the email's "From" address
func (eb *EmailBuilder) From(value string) *EmailBuilder {
    //basic validation
    if !strings.Contains(value, "@") {
        panic("Invalid email")
    }
    eb.email.from = value
    return eb
}

//Body sets the email's "Body"
func (eb *EmailBuilder) Body(value string) *EmailBuilder {
    eb.email.body = value
    return eb
}

//Subject sets the email's "Subject"
func (eb *EmailBuilder) Subject(value string) *EmailBuilder {
    eb.email.subject = value
    return eb
}

//RunBuilderParamter example
func RunBuilderParamter() {
    SendEmail(func(b *EmailBuilder) {
        b.
            To("World@gmail.com").
            From("me@gmail.com").
            Subject("Hello world").
            Body("Sample body for a dummy email")
    })
}

说明

当调用SendEmail函数的时候,会创建一个建造者对象EmailBuilder,并将这个对象的引用,作为参数传给action匿名函数。匿名函数会调用建造者的成员函数To、From、Subject和Body完成私有email对象创建,最后调用私有函数sendEmail发送邮件。

用户可以使用这个API,而不必担心创建复杂对象的实现和验证逻辑。

赞(0) 打赏
未经允许不得转载:IDEA激活码 » Golang建造者模式之-建造者参数

一个分享Java & Python知识的社区