设计模式之建造者模式——Builder

Builder模式,中文名为建造者模式,又名生成器模式、构建者模式等、是创建型设计模式之一。用于将一个复杂对象的构建与它的表示分离,使得同样的构建过程可以创建不同的表示。

1.适用性:

对象的创建比较复杂、有多种创建形式时

创建复杂对象的算法与对象内部组成和装配是相对独立的

2.UML类图

设计模式之建造者模式——Builder

Builder:定义创建Product各个部件的抽象接口

ConcreteBuilder:继承自Builder,实现创建具体类型的Product所有部件的接口,并提供一个获取最终产品的接口。

Director:借助Builder,内部封装创建产品的具体流程。

3.UML序列图

设计模式之建造者模式——Builder

Client创建一个ConcreteBuilder

Client通过传入ConcreteBuilder创建一个Director

Client使用Director构造产品

Client使用ConcreteBuilder组装并获取最终产品

二、实例

想象一下,你作为造物主,你需要创造各种各样的动物,比如狗和猫。查看源码

1.在创造前,要先想好狗和猫大体是什么样子,很显然,它们应该有头、身体和脚。

abstract class Animal { public string Head { get; set; } public string Body { get; set; } public string Foots { get; set; } public abstract void Display(); } class Dog : Animal { public override void Display() { Console.WriteLine("-------------- 狗的基本信息 -------------------"); Console.WriteLine($"头:{Head}"); Console.WriteLine($"身体:{Body}"); Console.WriteLine($"脚:{Foots}"); } } class Cat : Animal { public override void Display() { Console.WriteLine("-------------- 猫的基本信息 -------------------"); Console.WriteLine($"头:{Head}"); Console.WriteLine($"身体:{Body}"); Console.WriteLine($"脚:{Foots}"); } }

2.动物的基本特征确定了,也就明确了要干什么活儿了——创建动物的头、身体和脚。

interface IAnimalBuilder { void SetHead(); void SetBody(); void SetFoots(); }

3.接下来就是考虑狗和猫各部位的创建细节了。不过,别着急编码,先来考虑一件事情:

  DogBuilder里面除了需要实现IAnimalBuilder的所有接口外,还需要提供一个GetDog()的方法,用来把创建好的Dog给外部;同样的CatBuilder中也需要提供一个GetCat()方法。这世间动物有多少种?一千?一万?远远不止!在编码的过程中很容易就忘记提供这个方法了。所以我们在抽象Builder和具体Builder中间插入一个抽象层IAnimalBuilder<TAnimal>,所有的ConcreteBuilder都继承自这个接口。

interface IAnimalBuilder<TAnimal> : IAnimalBuilder where TAnimal : Animal { TAnimal GetAnimal(); } class DogBuilder : IAnimalBuilder<Dog> { private readonly Dog _dog = new Dog(); public void SetHead() { _dog.Head = "狗的头"; } public void SetBody() { _dog.Body = "狗的身体"; } public void SetFoots() { _dog.Foots = "狗的脚"; } public Dog GetAnimal() { return _dog; } } class CatBuilder : IAnimalBuilder<Cat> { private readonly Cat _cat = new Cat(); public void SetHead() { _cat.Head = "猫的头"; } public void SetBody() { _cat.Body = "猫的身体"; } public void SetFoots() { _cat.Foots = "猫的脚"; } public Cat GetAnimal() { return _cat; } }

最后,只剩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();

设计模式之建造者模式——Builder

三、变种

实际开发过程中,经常会遇到一种需求:创建对象时,对象的一些部分可以自由选择设置或不设置,但是对象一旦创建完成,便不能对其进行任何修改。例如:ASP.NET Core框架中WebHost的创建。接下来,我们来模拟一下女娲造人。

1.同样的,我们先设定好人的基本属性

class Person { public string Name { get; set; } public int Gender { get; set; } public int Age { get; set; } }

2.接下来,我们来定义IPersonBuilder接口,除了Build方法外,我们都返回了IPersonBuilder,对于习惯于使用Linq的.Net开发人员来说,再熟悉不过了,它最大的好处就是能够让我们使用Fluent的方式来编写代码。

public interface IPersonBuilder { //注意,这里有问题 Person Build(); IPersonBuilder SetName(string name); IPersonBuilder SetGender(int gender); IPersonBuilder SetAge(int age); }

内容版权声明:除非注明,否则皆为本站原创文章。

转载注明出处:https://www.heiqu.com/wsxdpy.html