在编程中,我们经常需要对一个对象进行相关的配置。比如新增员工,我们需要填写姓名、年龄、邮箱等;但是对于座机、性别可能就不是必填选项,如下代码示例:
typeUserstruct{NamestringAgeintEmailstringPhonestring//...OtherSchoolstringGenderstring}
在其他面向对象的语言中,如Java,我们可以通过重载函数解决初始化参数问题。因为 Go 语言不支持重载函数,所以,你得用不同的函数名来应对不同的配置选项。
funcNewDefaultUser(namestring,ageint,emailstring)(*User,error){return&User{Name:name,Age:age,Email:email},nil}funcNewPhoneUser(namestring,ageint,emailstring,phonestring)(*Server,error){return&User{Name:name,Age:age,Email:email,Phone:phone},nil}
Builder 模式
Java 程序员,一定会很自然地使用 Builder 模式。
Useruser=newUser.Builder().name("Moonus").email("moonus@outlook.com").age(18).build();
Functional Options
//UserOption我们定义一个函数类型,类似C#与委托函数ActiontypeUserOptionfunc(*User)复制代码
然后,我们可以使用函数式的方式定义一组如下的函数:
funcPhone(phonestring)UserOption{returnfunc(user*User){user.Phone=phone}}funcSchool(schoolstring)UserOption{returnfunc(user*User){user.School=school}}funcGender(genderstring)UserOption{returnfunc(user*User){user.Gender=gender}}
通过可变参数 options,for-loop 来设置我们的 User 对象。
funcCreateUser(namestring,ageint,emailstring,opt...UserOption)User{user:=User{Name:name,Age:age,Email:email}for_,option:=rangeopt{option(&user)}returnuser}
funcTestUser(t*testing.T){user:=CreateUser("Moonus",18,"Moonus@outlook.com",Phone("110"),func(user2*User){user2.Gender="男"})fmt.Println(user)}
Functional Options通过函数式,可以帮助开发者更加灵活得初始化对象,易于扩展。比如初始化对象我们需要设置默认值,通过该设计能快速解决该问题。