设计模式 - 单例模式
设计模式 - 原型模式

设计模式 - 建造者模式

violet posted @ Jul 07, 2020 06:20:54 AM in 笔记 with tags Design Pattern , 221 阅读

意图:将一个复杂的构建与其表示相分离,使得同样的构建过程可以创建不同的表示。

主要解决:主要解决在软件系统中,有时候面临着"一个复杂对象"的创建工作,其通常由各个部分的子对象用一定的算法构成;由于需求的变化,这个复杂对象的各个部分经常面临着剧烈的变化,但是将它们组合在一起的算法却相对稳定。

何时使用:一些基本部件不会变,而其组合经常变化的时候。

如何解决:将变与不变分离开。

关键代码:建造者:创建和提供实例,导演:管理建造出来的实例的依赖关系。

应用实例: 1、去肯德基,汉堡、可乐、薯条、炸鸡翅等是不变的,而其组合是经常变化的,生成出所谓的"套餐"。 2、JAVA 中的 StringBuilder。

优点: 1、建造者独立,易扩展。 2、便于控制细节风险。

缺点: 1、产品必须有共同点,范围有限制。 2、如内部变化复杂,会有很多的建造类。

使用场景: 1、需要生成的对象具有复杂的内部结构。 2、需要生成的对象内部属性本身相互依赖。

注意事项:与工厂模式的区别是:建造者模式更加关注与零件装配的顺序。

package main

import "fmt"

type Item interface {
	GetName() string
	Packing() string
	GetPrice() int
}

type Packing interface {
	Pack() string
}

type Wrapper struct{}
type Bottle struct{}

func (w *Wrapper) Pack() string {
	return "Wrapper"
}

func (b *Bottle) Pack() string {
	return "Bottle"
}

type Burger struct {
	packing Packing
}

func NewBurger() *Burger {
	return &Burger{&Wrapper{}}
}

func (b *Burger) Packing() string {
	return b.packing.Pack()
}

func (b *Burger) GetName() string {
	return "burger"
}

func (b *Burger) GetPrice() int {
	return 1
}

type ColdDrink struct {
	packing Packing
}

func NewColdDrink() *ColdDrink {
	return &ColdDrink{&Bottle{}}
}

func (c *ColdDrink) Packing() string {
	return c.packing.Pack()
}

func (c *ColdDrink) GetName() string {
	return "cold drink"
}

func (c *ColdDrink) GetPrice() int {
	return 2
}

type VegBurger struct {
	Burger *Burger
}

func (v *VegBurger) GetName() string {
	return "veg burger"
}

func (v *VegBurger) GetPrice() int {
	return v.Burger.GetPrice()
}

func (v *VegBurger) Packing() string {
	return v.Burger.Packing()
}

type ChickenBurger struct {
	Burger *Burger
}

func (c *ChickenBurger) GetName() string {
	return "chicken burger"
}

func (c *ChickenBurger) GetPrice() int {
	return c.Burger.GetPrice()
}

func (c *ChickenBurger) Packing() string {
	return c.Burger.Packing()
}

type Coke struct {
	ColdDrink *ColdDrink
}

func (c *Coke) GetName() string {
	return "coke"
}

func (c *Coke) GetPrice() int {
	return 2
}

func (c *Coke) Packing() string {
	return c.ColdDrink.Packing()
}

type Pepsi struct {
	ColdDrink *ColdDrink
}

func (p *Pepsi) GetName() string {
	return "pepsi"
}

func (p *Pepsi) GetPrice() int {
	return 3
}

func (p *Pepsi) Packing() string {
	return p.ColdDrink.Packing()
}

type Meal struct {
	Items []Item
}

func (m *Meal) AddItem(item Item) {
	m.Items = append(m.Items, item)
}

func (m *Meal) GetCost() int {
	sum := 0
	for _, i := range m.Items {
		sum += i.GetPrice()
	}

	return sum
}

func (m *Meal) ShowItems() {
	for _, i := range m.Items {
		fmt.Println("item: ", i.GetName())
		fmt.Println("packing with: ", i.Packing())
		fmt.Println("price: ", i.GetPrice())
	}
}

func main() {
	meal := &Meal{Items: []Item{}}
	meal.AddItem(&VegBurger{Burger: NewBurger()})
	meal.AddItem(&ChickenBurger{Burger: NewBurger()})
	meal.AddItem(&ChickenBurger{Burger: NewBurger()})
	meal.AddItem(&Coke{ColdDrink: NewColdDrink()})
	meal.AddItem(&Pepsi{ColdDrink: NewColdDrink()})

	fmt.Println("total cost: ", meal.GetCost())
	meal.ShowItems()
}
  • 无匹配

登录 *


loading captcha image...
(输入验证码)
or Ctrl+Enter