无论是在现实世界中还是在软件系统中,都存在一些复杂的对象,他们拥有多个组成部分,以汽车??为例,它包括车轮、方向盘、发动机等部件。对于用户而言,无须知道这些部件的装配细节,它几乎不会使用单独部件,而是使用一辆完整的汽车,可以通过生成器模式对其进行设计与描述,生成器模式可以将部件和其组装过程分开,一步一步创建一个复杂的对象。用户只需要指定复杂对象的类型就可以得到该对象,而无须知道其内部构造细节。
在软件开发中,也存在大量类似汽车一样的复杂对象,而对象的属性相当于汽车的部件,建造产品的过程就相当于组合部件的过程。由于组合部件的过程很复杂,因此,这些部件的组合过程往往被“外部化”到一个称作生成器的对象里,生成器返回给客户端的是一个已经建造完毕的完整产品对象,而用户无须关心该对象所包含的属性以及他们的组装方式,这就是生成器模式的愿景。
生成器模式(Builder Pattern):将一个复杂对象的构建与它的表示分离,使得同样的构建过程可以创建不同的表示
生成器模式是一步一步创建一个复杂的对象,它允许用户只通过制定复杂对象的类型和内容就可以构建他们,用户不需要知道内部的具体构建细节,建造者模式属于对象创建型。
当对象拥有好几种属性,且需要避免构造器伸缩时使用,与工厂模式运用场景不同之处在于:当创建过程仅仅一步到位,使用工厂模式,如果需要分步进行,则考虑使用生成器模式。
生成器模式的本质,就是将构造函数中的参数列表方法化,长长的参数列表,无论是面向对象还是函数式编程,都是大忌,该模式主要就是为了解决该问题。
#include <iostream>
class FriedRice {
public:
class FriedRiceBuilder;
void showFlavors() {
std::cout << _size;
if (_egg) std::cout << "-egg";
if (_beef) std::cout << "-beef";
if (_onion) std::cout << "-onion";
std::cout << std::endl;
}
private:
FriedRice(int size):_size(size){}
int _size = 0;
bool _egg = false;
bool _beef = false;
bool _onion = false;
};
class FriedRice::FriedRiceBuilder {
public:
FriedRiceBuilder(int size) {_friedrice = new FriedRice(size);}
FriedRiceBuilder& AddEgg() {_friedrice->_egg = true; return *this;}
FriedRiceBuilder& AddBeef() {_friedrice->_beef = true; return *this;}
FriedRiceBuilder& AddOnion() {_friedrice->_onion = true; return *this;}
FriedRice* Build() {return _friedrice;}
private:
FriedRice* _friedrice;
};
int main() {
FriedRice* friedRice = FriedRice::FriedRiceBuilder(7).AddEgg().AddBeef().AddOnion().Build();
friedRice->showFlavors();
return 0;
}
package builder
type Builder interface {
part1()
part2()
part3()
}
type Director struct {
builder Builder
}
func NewDirector(b Builder) *Director {
return &Director{builder: b}
}
func (d *Director) Constructor() {
d.builder.part1()
d.builder.part2()
d.builder.part3()
}
type FirstBuilder struct {
result string
}
func (fb *FirstBuilder) part1() {
fb.result += "1"
}
func (fb *FirstBuilder) part2() {
fb.result += "2"
}
func (fb *FirstBuilder) part3() {
fb.result += "3"
}
func (fb *FirstBuilder) Result() string {
return fb.result
}
type SecondBuilder struct {
result string
}
func (sb *SecondBuilder) part1() {
sb.result += "11"
}
func (sb *SecondBuilder) part2() {
sb.result += "22"
}
func (sb *SecondBuilder) part3() {
sb.result += "33"
}
func (sb *SecondBuilder) Result() string {
return sb.result
}
测试用例
package builder
import (
"reflect"
"testing"
)
func TestFirstBuilder_Result(t *testing.T) {
fb := FirstBuilder{}
d := NewDirector(&fb)
d.Constructor()
if reflect.ValueOf(d.builder).Interface().(*FirstBuilder).Result() != "123" {
t.Error("first builder test failed")
}
}
func TestSecondBuilder_Result(t *testing.T) {
sb := SecondBuilder{}
d := NewDirector(&sb)
d.Constructor()
if reflect.ValueOf(d.builder).Interface().(*SecondBuilder).Result() != "112233" {
t.Error("second builder test failed")
}
}
测试结果
go test -v .
=== RUN TestFirstBuilder_Result
--- PASS: TestFirstBuilder_Result (0.00s)
=== RUN TestSecondBuilder_Result
--- PASS: TestSecondBuilder_Result (0.00s)
PASS
ok design-patterns/builder 0.521s
原文:https://www.cnblogs.com/jingliming/p/11814231.html