目录
建造者模式描述
建造者模式,也叫作生成器模式,是一种创建型设计模式,使你能够分步骤创建复杂对象。该模式允许你使用相同的创建代码生成不同类型和形式的对象。
建造者模式存在的问题
假设有这样一个复杂对象,在对其进行构造时需要对诸多成员变量和嵌套对象进行繁复的初始化工作。这些初始化代码通常深藏于一个包含众多参数且让人基本看不懂的构造函数中;甚至还有更糟糕的情况,那就是这些代码散落在客户端代码的多个位置。
例如, 我们来思考如何创建一个 房屋House对象。 建造一栋简单的房屋, 首先你需要建造四面墙和地板, 安装房门和一套窗户, 然后再建造一个屋顶。 但是如果你想要一栋更宽敞更明亮的房屋, 还要有院子和其他设施 (例如暖气、 排水和供电设备), 那又该怎么办呢?
最简单的方法是扩展 房屋基类, 然后创建一系列涵盖所有参数组合的子类。 但最终你将面对相当数量的子类。 任何新增的参数 (例如门廊类型) 都会让这个层次结构更加复杂。
另一种方法则无需生成子类。 你可以在 房屋基类中创建一个包括所有可能参数的超级构造函数, 并用它来控制房屋对象。 这种方法确实可以避免生成子类, 但它却会造成另外一个问题。
通常情况下, 绝大部分的参数都没有使用, 这使得对于构造函数的调用十分不简洁,例如, 只有很少的房子有游泳池, 因此与游泳池相关的参数十之八九是毫无用处的。
解决方案
生成器模式建议将对象构造代码从产品类中抽取出来, 并将其放在一个名为生成器的独立对象中。
使用场景
1.使用生成器模式可避免 “重叠构造函数 (telescoping constructor)” 的出现。
2.当你希望使用代码创建不同形式的产品 (例如石头或木头房屋) 时, 可使用生成器模式。
3.使用生成器构造组合树或其他复杂对象。
优缺点对比
优点 | 缺点 |
你可以分步创建对象, 暂缓创建步骤或递归运行创建步骤 | 由于该模式需要新增多个类, 因此代码整体复杂程度会有所增加 |
生成不同形式的产品时, 你可以复用相同的制造代码 | |
单一职责原则。 你可以将复杂构造代码从产品的业务逻辑中分离出来 |
图示表达
分3部分记忆,具体产品product,构造器builder和指导者director 。
代码
1.建立一个控制台程序,代码文件总览。
2.具体产品,Product
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Threading.Tasks;
namespace ConsoleApp3
{
public class Product //产品类
{
List<string> parts = new List<string>();
public void Add(string part) //产品的方法
{
parts.Add(part);
}
public void Show() //产品的方法
{
Console.WriteLine(" Product Parts -------");
foreach (string part in parts)
Console.WriteLine(part);
}
}
}
3.构造器,Builder
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Threading.Tasks;
namespace ConsoleApp3
{
public abstract class Builder //建造者类,创建不同的部件的方法
{
abstract public void BuildPartA(); //定义创建A方法
abstract public void BuildPartB(); //定义创建B方法
abstract public Product GetResult(); //定义创建Product的GetResult方法
}
}
4.具体构造者,ConcreteBuilder1
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Threading.Tasks;
namespace ConsoleApp3
{
public class ConcreteBuilder1 : Builder //具体建造者1,继承建造者
{
private Product product; //定义字段
public override void BuildPartA() //实现方法
{
product = new Product();
product.Add("PartA1");
}
public override void BuildPartB() //实现方法
{
product.Add("PartB1");
}
public override Product GetResult() //实现方法,返回Product类
{
return product;
}
}
}
5.具体构造者,ConcreteBuilder2
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Threading.Tasks;
namespace ConsoleApp3
{
public class ConcreteBuilder2 : Builder //具体建造者2,继承建造者
{
private Product product; //定义字段
public override void BuildPartA() //实现方法
{
product = new Product();
product.Add("PartA2");
}
public override void BuildPartB() //实现方法
{
product.Add("PartB2");
}
public override Product GetResult() //实现方法,返回Product类
{
return product;
}
}
}
6.指导者,Director
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Threading.Tasks;
namespace ConsoleApp3
{
public class Director //指导者类,自己没有能力建造,可以让建造者去做
{
public void Construct(Builder builder) //初始化构造(就是依赖注入)
{
builder.BuildPartA();
builder.BuildPartB();
}
}
}
7.使用
using System;
using System.Threading;
using System.Threading.Tasks;
namespace ConsoleApp3
{
class Program
{
static void Main(string[] args)
{
Director director = new Director(); //定义指导者
Builder b1 = new ConcreteBuilder1(); //定义建造者1
Builder b2 = new ConcreteBuilder2(); //定义建造者2
director.Construct(b1); //指导者指挥建造者
Product p1 = b1.GetResult(); //建造者建造一个产品
p1.Show(); //获得产品的方法
director.Construct(b2);
Product p2 = b2.GetResult();
p2.Show();
Console.WriteLine("结束");
}
}
}
8.效果