一、为何需要建造者模式(Builder)?
在软件系统中,会存在一个复杂的对象,复杂在于该对象包含了很多不同的功能模块。该对象里的各个部分都是按照一定的算法组合起来的。
为了要使得复杂对象里的各个部分的独立性,以及将它们组合在一起的算法需要保持固定(不会轻易改变其算法逻辑),不会随着新需求改变从而改变原有的逻辑。此时就需要用建造者模式了。
特点:
将一个复杂对象的构建和其各个部分之间分离,在同一个算法组合里可以创建出不同的对象。
- 部件的算法组合、对象的构建、部件的实现之间进行分离。
结构
- 产品类(Product):存在产品的所有部件属性,需要用来创建的复杂对象。
- 建造创建者类(Builder):抽象类,定义复杂对象的部件创建的规范(抽象方法)。
- 具体创建类(ConCreateBuilder):实现 Builder 接口方法,完成具体产品的创建。
- 指挥者类(Director):由指挥者类来调用具体创建者类的方法按照一定的顺序来组装,返回完整的对象产品。
适合应用场景的特点:
- 产品类里具有不同型号产品的共同属性。(如下文例子中的渐变颜色,形状)
- 部件的型号不同,创建的逻辑也很可能不相同。(如有不同的代码逻辑来创建形状Point)
- 部件的组合方式是固定的。(如设置渐变颜色和形状的组合算法是固定的)
二、例子
需求:
实现一个画图程序。根据不同形状和不同渐变颜色来创建一个图形。比如,创建一个红橙按比例 50:100 渐变的矩形;创建一个白灰黑按比例 50:70:100 渐变的三角形。(为了方便理解,下面例子不写得过于复杂,就不使用 Graphics 和 Pen 的复杂方式绘图,而使用 Point 数组进行简单绘图)
1、产品:
c
//产品类里具有不同型号产品的共同属性。
public sealed class Sharp
{
public Point[] point { get; private set; }
public List<Colors> colors { get; private set; }
public void setPoint(Point[] p) { point = p; }
public void setColors(List<Colors> colors) { this.colors = colors; }
}
//Sharp 属性:形状
public struct Point
{
public double x;
public double y;
}
//Sharp 属性:渐变颜色
public class Colors
{
public string Rgb { get; set; }
public double GradientValue { get; set; }
public Colors(string rgb,double gradient)
{
Rgb = rgb;
GradientValue = gradient;
}
}
2、抽象建造者:
c
public abstract class Builder
{
protected Sharp Sharp { get; set; }
public Builder()
{
Sharp = new Sharp();
}
public Sharp GetSharp()
{
return Sharp;
}
//部件的组合方式是固定的
public abstract void BuilderSharp();
public abstract void BuilderColors();
}
3、构造建造者(具体创建者):
c
//矩形构造者
public class RectSharpBuilder : Builder
{
//部件的型号不同,创建的逻辑也很可能不相同。同下
public override void BuilderSharp()
{
Point[] point = new Point[4];
point[0].x = 0; point[0].y = 0;
point[1].x = 0; point[1].y = 10;
point[2].x = 10; point[2].y = 0;
point[3].x = 10; point[3].y = 10;
Sharp.setPoint(point);
}
public override void BuilderColors()
{
List<Colors> colors = new List<Colors>()
{
new Colors("Red",50),
new Colors("Orange",100)
};
Sharp.setColors(colors);
}
}
//三角形构造者
public class TriangleSharpBuilder : Builder
{
public override void BuilderSharp()
{
Point[] point = new Point[3];
point[0].x = 0; point[0].y = 10;
point[1].x = 5; point[1].y = 0;
point[2].x = 10; point[2].y = 10;
Sharp.setPoint(point);
}
public override void BuilderColors()
{
List<Colors> colors = new List<Colors>()
{
new Colors("White",50),
new Colors("Gray",70),
new Colors("Black",100)
};
Sharp.setColors(colors);
}
}
4、指导者:
c
public class Director
{ //部件的组合方式是固定的
public Sharp BuildSharp(Builder builder)
{
builder.BuilderSharp();
builder.BuilderColors();
return builder.GetSharp();
}
}
5、主程序:
c
class Program
{
static void Main(string[] args)
{
Director director = new Director();
Builder RectSharp = new RectSharpBuilder();
Builder TriangleSharp = new TriangleSharpBuilder();
director.BuildSharp(RectSharp);
director.BuildSharp(TriangleSharp);
Console.ReadLine();
}
}