什么是建造者模式?
将一个复杂的对象的构建与它的表示分离,使得同样的构建过程可以创建不同的表示。
实现
// 创建一个表示食物条目,食物包装和价格的接口
type Item interface {
// 获取食物名字
GetName() string
// 获取包装
Packing() Packing
// 获取价格
GetPrice() float32
}
type Packing interface {
// 获取包装类型
GetPack() string
}
// 实现Packing接口的实现类。Wapper为纸盒包装,Bottle为瓶装。
type Wrapper struct {
}
func (this *Wrapper) GetPack() string {
return "纸盒"
}
func NewWrapper() *Wrapper {
return &Wrapper{}
}
type Bottle struct {
}
func (this *Bottle) GetPack() string {
return "纸杯"
}
func NewBottle() *Bottle {
return &Bottle{}
}
// 创建视频类,简单的设为Burger和Drink
type Burger struct {
}
func NewBurger() *Burger {
return &Burger{}
}
func (this *Burger) Packing() Packing {
return NewWrapper()
}
func (this *Burger) GetPrice() float32 {
return 15.0
}
func (this *Burger) GetName() string {
return "汉堡"
}
type Drink struct {
}
func NewDrink() *Drink {
return &Drink{}
}
func (this *Drink) Packing() Packing {
return NewBottle()
}
func (this *Drink) GetPrice() float32 {
return 25.0
}
func (this *Drink) GetName() string {
return "饮品"
}
// 一餐
type Meal struct {
items []Item
}
func NewMeal() *Meal {
return &Meal{}
}
func (this *Meal) AddItem(item Item) {
this.items = append(this.items, item)
}
func (this *Meal) GetCost() float32 {
var cost float32
cost = 0.0
for _, item := range this.items {
cost += item.GetPrice()
}
return cost
}
func (this *Meal) ShowItem() {
for _, item := range this.items {
fmt.Println("餐品:", item.GetName())
fmt.Println("包装:", item.Packing().GetPack())
fmt.Println("价格:", item.GetPrice())
}
}
// 指挥者
type MealBuilder struct {
}
func (this *MealBuilder) order() *Meal {
meal := NewMeal()
meal.AddItem(NewBurger())
meal.AddItem(NewDrink())
return meal
}
func NewMealBuilder() *MealBuilder {
return &MealBuilder{}
}
func TestNewMealBuilder(t *testing.T) {
mealBuilder := NewMealBuilder()
order := mealBuilder.order()
fmt.Println("------order------")
order.ShowItem()
fmt.Println("总额 ", order.GetCost())
}
// === RUN TestNewMealBuilder
// ------order------
// 餐品: 汉堡
// 包装: 纸盒
// 价格: 15
// 餐品: 饮品
// 包装: 纸杯
// 价格: 25
// 总额 40
// --- PASS: TestNewMealBuilder (0.00s)
// PASS
优点:
- 封装性。是客户端不必知道产品内部组成的细节;
- 建造者独立,易扩展;
- 便于控制细节风险。可以对建造过程逐步细化,而不对其他模块产生任何影响;
缺点:
- 产品必须有共同点,范围有限制;
- 如果内部变化复杂,会有很多建造类;
适用场景
- 相同的方法,不同的执行顺序,产生不同的事件结果时;
- 需要生成的对象具有复杂的内部结构时;
- 多个部件或零件,都可以装配到一个对象中,但产生的结果又不相同时。
网友评论