zoukankan      html  css  js  c++  java
  • Golang设计模式学习笔记--建造者模式

    建造者模式

    在软件开发中有时需要创建一个复杂的对象,这个对象有很多小对象按照一定的步骤组成,例如计算机是由主板、内存、cpu、硬盘、显卡等组件组成,采购员不可能自己组装计算机,而是将计算机的配置要求告诉计算机销售公司,计算机销售公司再安排技术人员组装计算机,再交给采购员

    生活中这种例子也有很多,比如游戏中不同角色的性格、能力、脸型,体型、发型、服装等各有差异,汽车的方向盘,轮胎、发动机、轮胎、也有多钟多样。每封邮件的主题,内容附件等内容也各不相同。

    建造者模式的定义

    是指将一个复杂的对象的构造与表象分离,使得同样的构造过程可以创建不同的表示,他将变与不变分离,即使产品的组成部分是不变的,但是每一部分是可以灵活选择的。

    建造者模式的优点

    • 封装性好,构建和表示分离
    • 扩展性好,各个不同的建造者相互独立,有利于系统的解耦
    • 调用者不必知道产品的内部组成细节,建造者可以对创建过程逐步细化,也不会影响到其他模块

    建造者模式的缺点

    • 产品的组成部分必须相同,限制了其使用范围
    • 如果产品的内部变化过大,则建造者也要同步进行修改,后期维护成本比较大

    建造者模式和工厂模式关注点不同,建造者模式更关注零部件的组装过程,而工厂模式更关注的是创建过程。但是两者可以结合使用

    这里可以理解为:每个零件需要工厂来生产,但是实际负责组装的工厂,这里叫做建造者。

    建造者模式的要素

    建造者模式由产品(Product)、指挥者(Director)、抽象创建者(Builder)、具体创建者(Concrete Builder)4个要素组成

    具体代码分析

    • 产品
      包含getter setter方法
    // Product 是产品 
    type Product struct {
    	partA string
    	partB string
    	partC string
    }
    
    func (p *Product) PartA() string {
    	return p.partA
    }
    
    func (p *Product) SetPartA(partA string) {
    	p.partA = partA
    }
    
    func (p *Product) PartB() string {
    	return p.partB
    }
    
    func (p *Product) SetPartB(partB string) {
    	p.partB = partB
    }
    
    func (p *Product) PartC() string {
    	return p.partC
    }
    
    func (p *Product) SetPartC(partC string) {
    	p.partC = partC
    }
    
    • 指挥者
      包含一个建造函数Construct()返回产品
    // Director 是指挥者
    type Director struct {
    	builder Builder
    }
    
    func (d *Director)Construct() interface{} {
    	d.builder.newProduct()
    	d.builder.buildPartA()
    	d.builder.buildPartB()
    	d.builder.buildPartC()
    	return d.builder.getResult()
    }
    
    func NewDirector(builder Builder) *Director {
    	return &Director{
    		builder: builder,
    	}
    }
    
    • 抽象建造者
    // Builder 是一个抽象建造者
    type Builder interface {
    	// 创建新产品
    	newProduct()
    	buildPartA()
    	buildPartB()
    	buildPartC()
    	// 返回产品对象
    	getResult() interface{}
    }
    
    • 具体建造者
      实现Builder接口
    // ConcreteBuilder 是具体的建造者
    type ConcreteBuilder struct {
    	product *Product
    }
    
    func (cb *ConcreteBuilder)newProduct() {
    	cb.product = &Product{}
    }
    
    func (cb *ConcreteBuilder)buildPartA() {
    	cb.product.SetPartA("A部分已构建")
    }
    func (cb *ConcreteBuilder) buildPartB() {
    	cb.product.SetPartB("B部分已构建")
    }
    
    func (cb *ConcreteBuilder)buildPartC() {
    	cb.product.SetPartC("C部分已构建")
    }
    // 返回产品对象
    func (cb *ConcreteBuilder)getResult() interface{} {
    	return cb.product
    }
    
    • 实际调用
    b:= &builder.ConcreteBuilder{}
    director := builder.NewDirector(b)
    product := director.Construct()
    

    适用场景

    • 相同的方法,不同的执行顺序,产生不同的结果。
    • 多个部件或零件,都可以装配到一个对象中,但是产生的结果又不相同。
    • 产品类非常复杂,或者产品类中不同的调用顺序产生不同的作用。
    • 初始化一个对象特别复杂,参数多,而且很多参数都具有默认值。

    完整代码传送门

  • 相关阅读:
    HDU 3853:LOOPS(概率DP)
    HDU 4405:Aeroplane chess(概率DP入门)
    中国剩余定理模板
    HDU 5768:Lucky7(中国剩余定理 + 容斥原理)
    欧几里得和拓展欧几里得模板
    HDU 5025:Saving Tang Monk(BFS + 状压)
    HDU 1728:逃离迷宫(BFS)
    HDU 5795:A Simple Nim(博弈)
    HDU 5724:Chess(博弈 + 状压)
    HDU 5818:Joint Stacks(stack + deque)
  • 原文地址:https://www.cnblogs.com/Kingram/p/15148962.html
Copyright © 2011-2022 走看看