Builder模式,中文名为建造者模式,又名生成器模式、构建者模式等、是创建型设计模式之一。用于将一个复杂对象的构建与它的表示分离,使得同样的构建过程可以创建不同的表示。
1.适用性:对象的创建比较复杂、有多种创建形式时
创建复杂对象的算法与对象内部组成和装配是相对独立的
2.UML类图Builder:定义创建Product各个部件的抽象接口
ConcreteBuilder:继承自Builder,实现创建具体类型的Product所有部件的接口,并提供一个获取最终产品的接口。
Director:借助Builder,内部封装创建产品的具体流程。
3.UML序列图Client创建一个ConcreteBuilder
Client通过传入ConcreteBuilder创建一个Director
Client使用Director构造产品
Client使用ConcreteBuilder组装并获取最终产品
二、实例想象一下,你作为造物主,你需要创造各种各样的动物,比如狗和猫。查看源码
1.在创造前,要先想好狗和猫大体是什么样子,很显然,它们应该有头、身体和脚。
2.动物的基本特征确定了,也就明确了要干什么活儿了——创建动物的头、身体和脚。
interface IAnimalBuilder { void SetHead(); void SetBody(); void SetFoots(); }3.接下来就是考虑狗和猫各部位的创建细节了。不过,别着急编码,先来考虑一件事情:
DogBuilder里面除了需要实现IAnimalBuilder的所有接口外,还需要提供一个GetDog()的方法,用来把创建好的Dog给外部;同样的CatBuilder中也需要提供一个GetCat()方法。这世间动物有多少种?一千?一万?远远不止!在编码的过程中很容易就忘记提供这个方法了。所以我们在抽象Builder和具体Builder中间插入一个抽象层IAnimalBuilder<TAnimal>,所有的ConcreteBuilder都继承自这个接口。
最后,只剩Director了,它来规划Builder要创建哪些东西。
class Director { private readonly IAnimalBuilder _builder; public Director(IAnimalBuilder builder) { _builder = builder; } public void Construct() { _builder.SetHead(); _builder.SetBody(); _builder.SetFoots(); } }大功告成!接下来就尝试一下吧
var dogBuilder = new DogBuilder(); var dogDirector = new Director(dogBuilder); dogDirector.Construct(); dogBuilder.GetAnimal().Display(); var catBuilder = new CatBuilder(); var catDirector = new Director(catBuilder); catDirector.Construct(); catBuilder.GetAnimal().Display(); 三、变种实际开发过程中,经常会遇到一种需求:创建对象时,对象的一些部分可以自由选择设置或不设置,但是对象一旦创建完成,便不能对其进行任何修改。例如:ASP.NET Core框架中WebHost的创建。接下来,我们来模拟一下女娲造人。
1.同样的,我们先设定好人的基本属性
2.接下来,我们来定义IPersonBuilder接口,除了Build方法外,我们都返回了IPersonBuilder,对于习惯于使用Linq的.Net开发人员来说,再熟悉不过了,它最大的好处就是能够让我们使用Fluent的方式来编写代码。
public interface IPersonBuilder { //注意,这里有问题 Person Build(); IPersonBuilder SetName(string name); IPersonBuilder SetGender(int gender); IPersonBuilder SetAge(int age); }