手撸golang 创建型设计模式 建造者模式
缘起
最近复习设计模式
拜读谭勇德的<<设计模式就该这样学>>
本系列笔记拟采用golang练习之
建造者模式
建造者模式(Builder Pattern)将一个复杂对象的构建过程与它的表示分离,使得同样的构建过程可以创建不同的表示,属于创建型设计模式。
_
场景
- 某业务系统, 希望使用SQLQuery类动态构造复杂SQL查询语句
- SQLQuery类的各种属性组合情况很多, 因此创建SQLQueryBuilder作为SQLQuery的建造者
builder_test.go
测试用例
package patterns
import (
"fmt"
bd "learning/gooop/creational_patterns/builder"
"testing"
)
func Test_Builder(t *testing.T) {
builder := bd.NewSQLQueryBuilder()
builder = builder.WithTable("product")
builder = builder.AddField("id").AddField("name").AddField("price")
builder = builder.AddCondition("enabled=1")
builder = builder.WithOrderBy("price desc")
query := builder.Build()
fmt.Println(query.ToSQL())
}
测试输出
$ go test -v builder_test.go
=== RUN Test_Builder
select id,name,price from product where enabled=1 order by price desc
--- PASS: Test_Builder (0.00s)
PASS
ok command-line-arguments 0.002s
ISQLQuery.go
定义SQL查询表达式的接口
package builder
type ISQLQuery interface {
ToSQL() string
}
ISQLQueryBuilder.go
定义SQL查询表达式的建造者接口, 该接口定义了一系列步骤去创建复杂查询语句
package builder
type ISQLQueryBuilder interface {
WithTable(table string) ISQLQueryBuilder
AddField(field string) ISQLQueryBuilder
AddCondition(condition string) ISQLQueryBuilder
WithOrderBy(orderBy string) ISQLQueryBuilder
Build() ISQLQuery
}
tSQLQuery.go
tSQLQuery实现了ISQLQuery接口, 根据各种参数生成复杂SQL语句
package builder
import "strings"
type tSQLQuery struct {
table string
fields []string
conditions []string
orderBy string
}
func newSQLQuery() *tSQLQuery {
return &tSQLQuery{
table: "",
fields: make([]string, 0),
conditions: make([]string, 0),
orderBy: "",
}
}
func (me *tSQLQuery) ToSQL() string {
b := &strings.Builder{}
b.WriteString("select ")
for i, it := range me.fields {
if i > 0 {
b.WriteRune(',')
}
b.WriteString(it)
}
b.WriteString(" from ")
b.WriteString(me.table)
if len(me.conditions) > 0 {
b.WriteString(" where ")
for i, it := range me.conditions {
if i > 0 {
b.WriteString(" and ")
}
b.WriteString(it)
}
}
if len(me.orderBy) > 0 {
b.WriteString(" order by ")
b.WriteString(me.orderBy)
}
return b.String()
}
tSQLQueryBuilder.go
tSQLQueryBuilder实现了ISQLQueryBuilder接口, 为各种参数设置提供了方法
package builder
type tSQLQueryBuilder struct {
query *tSQLQuery
}
func NewSQLQueryBuilder() ISQLQueryBuilder {
return &tSQLQueryBuilder {
query : newSQLQuery(),
}
}
func (me *tSQLQueryBuilder) WithTable(table string) ISQLQueryBuilder {
me.query.table = table
return me
}
func (me *tSQLQueryBuilder) AddField(field string) ISQLQueryBuilder {
me.query.fields = append(me.query.fields, field)
return me
}
func (me *tSQLQueryBuilder) AddCondition(condition string) ISQLQueryBuilder {
me.query.conditions = append(me.query.conditions, condition)
return me
}
func (me *tSQLQueryBuilder) WithOrderBy(orderBy string) ISQLQueryBuilder {
me.query.orderBy = orderBy
return me
}
func (me *tSQLQueryBuilder) Build() ISQLQuery {
return me.query
}
建造者模式小结
建造者模式的优点
(1)封装性好,构建和表示分离。
(2)扩展性好,建造类之间独立,在一定程度上解耦。
(3)便于控制细节,建造者可以对创建过程逐步细化,而不对其他模块产生任何影响。
建造者模式的缺点
(1)需要多创建一个IBuilder对象。
(2)如果产品内部发生变化,则建造者也要同步修改,后期维护成本较大。
(end)
有疑问加站长微信联系(非本文作者)