建造者模式(Builder Pattern)使用多个简单的对象一步一步构建成一个复杂的对象
定义: Separate the construction of a complex object from its
representation sothat the same construction process can create
different representations.(将一个复杂对象的构建与它的表示分离,使得同样的构建过程可以创建不同的表示。)
主要解决: 主要解决在软件系统中,有时候面临着"一个复杂对象"的创建工作,其通常由各个部分的子对象用一定的算法构成;由于需求的变化,这个复杂对象的各个部分经常面临着剧烈的变化,但是将它们组合在一起的算法却相对稳定。
何时使用: 一些基本部件不会变,而其组合经常变化的时候。
如何解决: 将变与不变分离开。
关键代码:
建造者:创建和提供实例,
导演:管理建造出来的实例的依赖关系。
Product:产品类,通常是实现了模板方法模式,也就是有模板方法和基本方法
Builder:抽象建造者(抽象类或接口),规范产品的组件,一般是由子类实现
ConcreteBuilder: 具体建造者,实现抽象建造者定义的所有方法,并且返回一个组件好的对象
Director: 导演类,负责安排已有模块的顺序,然后告诉Builder开始建造
如果我们要组装一批iPhone手机和OPPO手机:
倘若组装过程主要分为两部:组装、外观设计
而这两种手机的步骤不太一样
iPhone:组装、外观设计(印品牌logo、外观上色)
OPPO:组装、外观设计(外观上色、印品牌logo)
class PhoneBuilder{ public: virtual void Package() = 0; virtual void Design() = 0; std::string GetResult(){ return _phone; } protected: void Logo() ; void Color() ; protected: std::string _phone; }; class iPhone :public PhoneBuilder{ public: void Package(){ _phone += "packing\n"; } void Design(){ Logo(); Color(); } std::string GetResult(){ return _phone; } protected: void Logo(){ _phone += "Logo iPhone\n"; } void Color(){ _phone += "Set Red color\n"; } }; class OPPO :public PhoneBuilder{ public: void Package(){ _phone += "Packing\n"; } void Design(){ Color(); Logo(); } std::string GetResult(){ return _phone; } protected: void Logo(){ _phone += "Logo OPPO\n"; } void Color(){ _phone += "Set white color\n"; } }; class PhoneDirector{ public: void Package(PhoneBuilder* o){ o->Package(); o->Design(); } };
PhoneDirector pd; PhoneBuilder* o=new OPPO; pd.Package(o); std::cout << o->GetResult() << std::endl; PhoneBuilder* i = new iPhone; pd.Package(i); std::cout << i->GetResult() << std::endl;
package Builder type PhoneBuilder interface{ Package() Design() GetResult()string } type phone struct{ _phone string } func (p *phone)GetResult()string{ return p._phone } type IPhone struct{ phone } func (p *IPhone)Package(){ p._phone +="Packaging iPhone\n" } func (p *IPhone)Design(){ p.logo() p.color() } func (p *IPhone)logo(){ p._phone +="Logo iPhone\n" } func (p *IPhone)color(){ p._phone += "Set red color\n" } type OPPO struct{ phone } func (p *OPPO)Package(){ p._phone +="Packaging OPPO\n" } func (p *OPPO)Design(){ p.logo() p.color() } func (p *OPPO)logo(){ p._phone +="Logo OPPO\n" } func (p *OPPO)color(){ p._phone += "Set white color\n" } type PhoneDirectorInterface interface{ Produce(pb PhoneBuilder) } type PhoneDirectorStruct struct{ } func (p *PhoneDirectorStruct)Produce(pb PhoneBuilder){ pb.Package() pb.Design() }
package main import ( "fmt" b "Builder" ) func main(){ pd :=b.PhoneDirectorStruct{} fmt.Println("Produce iPhone") iphone :=&b.IPhone{} pd.Produce(iphone) fmt.Println(iphone.GetResult()) fmt.Println("Produce OPPO") oppo :=&b.OPPO{} pd.Produce(oppo) fmt.Println(oppo.GetResult()) }
优点:
1、建造者独立,易扩展。
2、便于控制细节风险。
由于具体的建造者是独立的,因此对建造过程逐步细化,不会对其他模块产生任何影响
缺点:
1、产品必须有共同点,范围有限制。
2、如内部变化复杂,会有很多的建造类。
1、需要生成的对象具有复杂的内部结构。
2、需要生成的对象内部属性本身相互依赖。
注意事项:
与工厂模式的区别是:建造者模式更加关注与零件装配的顺序。