一、為何需要建造者模式(Builder)?
在軟件系統中,會存在一個復雜的對象,復雜在于該對象包含了很多不同的功能模塊。該對象里的各個部分都是按照一定的算法組合起來的。
為了要使得復雜對象里的各個部分的獨立性,以及將它們組合在一起的算法需要保持固定(不會輕易改變其算法邏輯),不會隨著新需求改變從而改變原有的邏輯。此時就需要用建造者模式了。
特點:
將一個復雜對象的構建和其各個部分之間分離,在同一個算法組合里可以創建出不同的對象。
- 部件的算法組合、對象的構建、部件的實現之間進行分離。
結構
- 產品類(Product):存在產品的所有部件屬性,需要用來創建的復雜對象。
- 建造創建者類(Builder):抽象類,定義復雜對象的部件創建的規范(抽象方法)。
- 具體創建類(ConCreateBuilder):實現 Builder 接口方法,完成具體產品的創建。并且
- 指揮者類(Director):由指揮者類來調用具體創建者類的方法按照一定的順序來組裝,返回完整的對象產品。
適合應用場景的特點:
- 產品類里具有不同型號產品的共同屬性。(如下文例子中的漸變顏色,形狀)
- 部件的型號不同,創建的邏輯也很可能不相同。(如有不同的代碼邏輯來創建形狀Point)
- 部件的組合方式是固定的。(如設置漸變顏色和形狀的組合算法是固定的)
二、例子
需求:
實現一個畫圖程序。根據不同形狀和不同漸變顏色來創建一個圖形。比如,創建一個紅橙按比例 50:100 漸變的矩形;創建一個白灰黑按比例 50:70:100 漸變的三角形。(為了方便理解,下面例子不寫得過于復雜,就不使用 Graphics 和 Pen 的復雜方式繪圖,而使用 Point 數組進行簡單繪圖)
1、產品:
//產品類里具有不同型號產品的共同屬性。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、抽象建造者:
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、構造建造者(具體創建者):
//矩形構造者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、指導者:
public class Director{ public Sharp BuildSharp(Builder builder){builder.BuilderSharp();builder.BuilderColors();return builder.GetSharp();}}
5、主程序:
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();}}