缘起
最近复习设计模式
拜读谭勇德的<<设计模式就该这样学>>
本系列笔记拟采用golang练习之
建造者模式
建造者模式(Builder Pattern)将一个复杂对象的构建过程与它的表示分离,使得同样的构建过程可以创建不同的表示,属于创建型设计模式。
_
场景
- 某业务系统, 希望使用SQLQuery类动态构造复杂SQL查询语句
- SQLQuery类的各种属性组合情况很多, 因此创建SQLQueryBuilder作为SQLQuery的建造者
builder_test.go
测试用例
package patternsimport ("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_Builderselect id,name,price from product where enabled=1 order by price desc--- PASS: Test_Builder (0.00s)PASSok command-line-arguments 0.002s
ISQLQuery.go
定义SQL查询表达式的接口
package buildertype ISQLQuery interface {ToSQL() string}
ISQLQueryBuilder.go
定义SQL查询表达式的建造者接口, 该接口定义了一系列步骤去创建复杂查询语句
package buildertype ISQLQueryBuilder interface {WithTable(table string) ISQLQueryBuilderAddField(field string) ISQLQueryBuilderAddCondition(condition string) ISQLQueryBuilderWithOrderBy(orderBy string) ISQLQueryBuilderBuild() ISQLQuery}
tSQLQuery.go
tSQLQuery实现了ISQLQuery接口, 根据各种参数生成复杂SQL语句
package builderimport "strings"type tSQLQuery struct {table stringfields []stringconditions []stringorderBy 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 buildertype tSQLQueryBuilder struct {query *tSQLQuery}func NewSQLQueryBuilder() ISQLQueryBuilder {return &tSQLQueryBuilder {query : newSQLQuery(),}}func (me *tSQLQueryBuilder) WithTable(table string) ISQLQueryBuilder {me.query.table = tablereturn 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 = orderByreturn me}func (me *tSQLQueryBuilder) Build() ISQLQuery {return me.query}
建造者模式小结
建造者模式的优点
(1)封装性好,构建和表示分离。
(2)扩展性好,建造类之间独立,在一定程度上解耦。
(3)便于控制细节,建造者可以对创建过程逐步细化,而不对其他模块产生任何影响。
建造者模式的缺点
(1)需要多创建一个IBuilder对象。
(2)如果产品内部发生变化,则建造者也要同步修改,后期维护成本较大。
