7,创建型模式-建造者模式
7.1 基础知识
学习难度:4
使用频率:2
总分:4
定义
建造者模式(Builder Pattern)将一个复杂对象的构建与它的表示分离,使得同样的构建过程可以创建不同的表示。
说人话
建造者拆分建造产品的过程,指挥者指挥建造者如何建造,最终得到产品对象。
结构图
实现步骤
- 产品类:定义产品属性和展示产品方法
- 建造者接口:定义建造产品属性方法和返回产品方法
- 具体建造者类:实现建造者接口,定义实例化的私有产品对象
- 指挥者类:定义建造者对象在构造函数传入初始化,定义构建产品方法,指挥建造者对象如何建造产品属性
- 客户端:创建具体建造者,创建指挥者传入具体建造者,指挥者构建的产品,具体建造者得到产品,展示产品
说明
建造者模式常用于构建复杂对象,当一个对象的构建过程比较复杂,而且对象的各个部分之间存在着复杂的构建顺序或依赖关系时,可以考虑使用建造者模式。通过建造者模式,可以将构建过程分解成多个简单的步骤,使得构建过程更加灵活,同时也易于扩展和维护。
7.2 模版代码
产品类
// 产品类
class Product
{
public string Part1 { get; set; }
public string Part2 { get; set; }
public void Show()
{
Console.WriteLine($"展示产品 Part1: {Part1}, Part2: {Part2}");
}
}
建造者接口和具体建造者
// 建造者接口
interface IBuilder
{
void BuildPart1();
void BuildPart2();
Product GetResult();
}
// 具体建造者类
class ConcreteBuilder : IBuilder
{
private Product product = new Product();
public void BuildPart1()
{
product.Part1 = "我是ConcreteBuilder创建的Part1";
}
public void BuildPart2()
{
product.Part2 = "我是ConcreteBuilder创建的Part2";
}
public Product GetResult()
{
return product;
}
}
指挥官
// 指挥者类
class Director
{
private IBuilder builder;
public Director(IBuilder builder)
{
this.builder = builder;
}
public void Construct()
{
builder.BuildPart1();
builder.BuildPart2();
}
}
客户端
class Program
{
static void Main(string[] args)
{
// 创建具体建造者
IBuilder builder = new ConcreteBuilder();
// 创建指挥官传入具体建造者
Director director = new Director(builder);
// 指挥官构建的产品
director.Construct();
// 具体建造者得到产品
Product product = builder.GetResult();
// 展示产品
product.Show();//展示产品 Part1: 我是ConcreteBuilder创建的Part1, Part2: 我是ConcreteBuilder创建的Part2
}
}
7.3 CSharp实践
实践需求
使用建造者模式建造宝马和奔驰的车,要求要构建发动机,轮子,车身
车产品类
//车产品类
public class CarProduct
{
//汽车的各个部件,可以是任意类型
public string Engine { get; set; } //发动机
public string Wheel { get; set; } //轮子
public string Body { get; set; } //车身
//启动汽车
public void RunCar()
{
Console.WriteLine("汽车启动,发动机是{0},轮子是{1},车身是{2}", Engine, Wheel, Body);
}
}
车建造者接口和具体车建造者类
//车建造者接口
public interface ICarBuilder
{
//创建发动机的抽象方法
public abstract void BuildEngine();
//创建轮子的抽象方法
public abstract void BuildWheel();
//创建车身的抽象方法
public abstract void BuildBody();
//获取产品的抽象方法
public abstract CarProduct GetCarProduct();
}
//奔驰车建造者类
class BenzCarBuilder : ICarBuilder
{
//创建一个空的汽车对象
private CarProduct carProduct = new CarProduct();
//重写创建发动机的方法,设置汽车对象的发动机属性为奔驰发动机
public void BuildEngine()
{
carProduct.Engine = "奔驰发动机";
}
//重写创建轮子的方法,设置汽车对象的轮子属性为奔驰轮子
public void BuildWheel()
{
carProduct.Wheel = "奔驰轮子";
}
//重写创建车身的方法,设置汽车对象的车身属性为奔驰车身
public void BuildBody()
{
carProduct.Body = "奔驰车身";
}
//重写获取产品的方法,返回构建好的汽车对象
public CarProduct GetCarProduct()
{
return carProduct;
}
}
//宝马车建造者
class BMWCarBuilder : ICarBuilder
{
//创建一个空的汽车对象
private CarProduct carProduct = new CarProduct();
//重写创建发动机的方法,设置汽车对象的发动机属性为宝马发动机
public void BuildEngine()
{
carProduct.Engine = "宝马发动机";
}
//重写创建轮子的方法,设置汽车对象的轮子属性为宝马轮子
public void BuildWheel()
{
carProduct.Wheel = "宝马轮子";
}
//重写创建车身的方法,设置汽车对象的车身属性为宝马车身
public void BuildBody()
{
carProduct.Body = "宝马车身";
}
//重写获取产品的方法,返回构建好的汽车对象
public CarProduct GetCarProduct()
{
return carProduct;
}
}
车指挥官类
//指挥者官,包含一个抽象建造者类型的属性和一个构建产品的方法
class CarDirector
{
//抽象建造者类型的属性,用来接收具体建造者对象
private ICarBuilder builder;
//构造函数,用来初始化抽象建造者属性
public CarDirector(ICarBuilder builder)
{
this.builder = builder;
}
//构建产品的方法,可以指定创建产品的各个部件的顺序和逻辑
public void Construct()
{
//先创建发动机
builder.BuildEngine();
//再创建轮子
builder.BuildWheel();
//最后创建车身
builder.BuildBody();
}
}
客户端
class Program
{
static void Main(string[] args)
{
ICarBuilder benzBuilder = new BenzCarBuilder();
CarDirector director = new CarDirector(benzBuilder);
director.Construct();
CarProduct benzCarProduct = benzBuilder.GetCarProduct();
benzCarProduct.RunCar();//汽车启动,发动机是奔驰发动机,轮子是奔驰轮子,车身是奔驰车身
ICarBuilder bmwBuilder = new BMWCarBuilder();
CarDirector bmwDirector = new CarDirector(bmwBuilder);
bmwDirector.Construct();
CarProduct bmwCarProduct = bmwBuilder.GetCarProduct();
bmwCarProduct.RunCar();//汽车启动,发动机是宝马发动机,轮子是宝马轮子,车身是宝马车身
}
}
7.4 Unity实践
实践需求
使用建造者模式,建造暗夜猎手薇恩和无极剑圣易,建造时要传入名字和英雄位置分类
英雄产品类
public class HeroProduct
{
public string name;
public string roleLane;
public const string PrefabConstPath = "Lesson08_创建型模式_建造者模式";
public void CreateHeroPrefab()
{
Debug.Log($"创建英雄,英雄名字是{name},位置是{roleLane}");
GameObject prefab = Resources.Load<GameObject>(PrefabConstPath +"/" +name);
GameObject.Instantiate(prefab, Vector3.zero, Quaternion.identity);
}
}
英雄建造者接口和具体英雄建造者类
public interface IHeroBuilder
{
void SetName();
void SetRoleLane();
HeroProduct ReturnHeroProduct();
}
public class VayneBuilder:IHeroBuilder
{
private readonly HeroProduct heroProduct = new HeroProduct();
public void SetName()
{
heroProduct.name = "Vayne";
}
public void SetRoleLane()
{
heroProduct.roleLane = "ADC";
}
public HeroProduct ReturnHeroProduct()
{
return heroProduct;
}
}
public class YiBuilder:IHeroBuilder
{
private readonly HeroProduct heroProduct = new HeroProduct();
public void SetName()
{
heroProduct.name = "Yi";
}
public void SetRoleLane()
{
heroProduct.roleLane = "Jungle";
}
public HeroProduct ReturnHeroProduct()
{
return heroProduct;
}
}
英雄指挥官
public class HeroDirector
{
private IHeroBuilder heroBuilder;
public HeroDirector(IHeroBuilder heroBuilder)
{
this.heroBuilder = heroBuilder;
}
public void Construct()
{
heroBuilder.SetName();
heroBuilder.SetRoleLane();
}
}
客户端
public class TestBuilderPattern : MonoBehaviour
{
void Start()
{
IHeroBuilder vayneBuilder = new VayneBuilder();
IHeroBuilder yiBuilder = new YiBuilder();
ShowHero(vayneBuilder);
ShowHero(yiBuilder);
}
public void ShowHero(IHeroBuilder heroBuilder)
{
HeroDirector heroDirector = new HeroDirector(heroBuilder);
heroDirector.Construct();
HeroProduct heroProduct = heroBuilder.ReturnHeroProduct();
heroProduct.CreateHeroPrefab();
}
}
运行结果
转载请注明来源,欢迎对文章中的引用来源进行考证,欢迎指出任何有错误或不够清晰的表达。可以在下面评论区评论,也可以邮件至 785293209@qq.com