手撸golang 创建型设计模式 建造者模式

手撸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)

你可能感兴趣的:(golang设计模式建造者模式)