当前位置: 首页 > news >正文

C# 设计模式--建造者模式 (Builder Pattern)

定义

建造者模式是一种创建型设计模式,它允许你逐步构建复杂对象,而无需使用多个构造函数或重载。建造者模式将对象的构建过程与表示分离,使得相同的构建过程可以创建不同的表示。

正确写法

假设我们有一个复杂的 Car 对象,需要逐步构建其各个部分(如引擎、轮胎、颜色等)。

// 产品类
public class Car
{public string Engine { get; set; }public string Tires { get; set; }public string Color { get; set; }public override string ToString(){return $"Car: Engine={Engine}, Tires={Tires}, Color={Color}";}
}// 抽象建造者
public abstract class CarBuilder
{protected Car car;public Car GetCar() => car;public abstract void BuildEngine();public abstract void BuildTires();public abstract void BuildColor();
}// 具体建造者
public class SportsCarBuilder : CarBuilder
{public SportsCarBuilder(){car = new Car();}public override void BuildEngine() => car.Engine = "V8";public override void BuildTires() => car.Tires = "High-performance tires";public override void BuildColor() => car.Color = "Red";
}public class LuxuryCarBuilder : CarBuilder
{public LuxuryCarBuilder(){car = new Car();}public override void BuildEngine() => car.Engine = "V6";public override void BuildTires() => car.Tires = "All-season tires";public override void BuildColor() => car.Color = "Black";
}// 导演类
public class Director
{public void Construct(CarBuilder builder){builder.BuildEngine();builder.BuildTires();builder.BuildColor();}
}// 客户端代码
class Program
{static void Main(string[] args){Director director = new Director();CarBuilder sportsCarBuilder = new SportsCarBuilder();director.Construct(sportsCarBuilder);Car sportsCar = sportsCarBuilder.GetCar();Console.WriteLine(sportsCar);CarBuilder luxuryCarBuilder = new LuxuryCarBuilder();director.Construct(luxuryCarBuilder);Car luxuryCar = luxuryCarBuilder.GetCar();Console.WriteLine(luxuryCar);}
}

类图:

Car
-string Engine
-string Tires
-string Color
+override string ToString()
CarBuilder
-Car car
+Car GetCar()
+abstract void BuildEngine()
+abstract void BuildTires()
+abstract void BuildColor()
SportsCarBuilder
+SportsCarBuilder()
+override void BuildEngine()
+override void BuildTires()
+override void BuildColor()
LuxuryCarBuilder
+LuxuryCarBuilder()
+override void BuildEngine()
+override void BuildTires()
+override void BuildColor()
Director
+void Construct(CarBuilder builder)
Program
+static void Main(string[] args)

解释

  1. 产品类 (Car):定义了汽车的属性(引擎、轮胎、颜色)和一个重写的 ToString 方法,用于显示汽车的详细信息。
  2. 抽象建造者 (CarBuilder):定义了一个受保护的 Car 对象,并提供了获取汽车的方法 GetCar 以及三个抽象方法 BuildEngineBuildTiresBuildColor
  3. 具体建造者 (SportsCarBuilderLuxuryCarBuilder):继承自 CarBuilder,具体实现了构建汽车各个部分的方法。
  4. 导演类 (Director):负责调用具体建造者的构建方法,按照一定的顺序构建汽车。
  5. 客户端代码 (Program):创建了 Director 对象和具体的建造者对象,通过导演类的 Construct 方法构建汽车,并最终获取和显示汽车的信息。

用途

  1. 逐步构建复杂对象:当对象的构建过程复杂且需要多个步骤时,使用建造者模式可以将构建过程分解为多个方法调用。
  2. 分离构建过程和表示:建造者模式将对象的构建过程与表示分离,使得相同的构建过程可以创建不同的表示。
  3. 避免大量的构造函数:避免使用多个构造函数或重载,使代码更加清晰和易于维护。

优点

  1. 封装性好:将对象的构建过程封装在建造者类中,客户端代码不需要关心具体的构建细节。
  2. 代码复用性高:相同的构建过程可以创建不同的表示,提高了代码的复用性。
  3. 易于扩展:增加新的建造者类时,不需要修改现有的代码,符合开闭原则。

缺点

  1. 代码复杂度增加:引入了多个类(抽象建造者、具体建造者、导演类等),系统结构变得更复杂。
  2. 增加类的数量:每增加一个新的产品类型,就需要增加相应的建造者类,类的数量会增加。
  3. 灵活性受限:如果产品的内部表示发生变化,可能需要修改多个建造者类。
    适用场景
  4. 对象构建过程复杂:当对象的构建过程复杂且需要多个步骤时。
  5. 对象的表示多种多样:当需要创建多种不同表示的对象时。
  6. 避免大量的构造函数:当对象的构造函数参数较多且复杂时。

实际开发中的应用

1. 配置文件解析

假设我们需要解析一个复杂的配置文件,并根据配置文件的内容创建相应的对象。
代码如下:

// 配置对象
public class Configuration
{public string Host { get; set; }public int Port { get; set; }public string Username { get; set; }public string Password { get; set; }public override string ToString(){return $"Configuration: Host={Host}, Port={Port}, Username={Username}, Password={Password}";}
}// 抽象建造者
public abstract class ConfigurationBuilder
{protected Configuration configuration;public Configuration GetConfiguration() => configuration;public abstract void BuildHost();public abstract void BuildPort();public abstract void BuildUsername();public abstract void BuildPassword();
}// 具体建造者
public class ProductionConfigBuilder : ConfigurationBuilder
{public ProductionConfigBuilder(){configuration = new Configuration();}public override void BuildHost() => configuration.Host = "prod.example.com";public override void BuildPort() => configuration.Port = 8080;public override void BuildUsername() => configuration.Username = "admin";public override void BuildPassword() => configuration.Password = "securepassword";
}public class DevelopmentConfigBuilder : ConfigurationBuilder
{public DevelopmentConfigBuilder(){configuration = new Configuration();}public override void BuildHost() => configuration.Host = "dev.example.com";public override void BuildPort() => configuration.Port = 8081;public override void BuildUsername() => configuration.Username = "devuser";public override void BuildPassword() => configuration.Password = "devpassword";
}// 导演类
public class ConfigDirector
{public void Construct(ConfigurationBuilder builder){builder.BuildHost();builder.BuildPort();builder.BuildUsername();builder.BuildPassword();}
}// 客户端代码
class Program
{static void Main(string[] args){ConfigDirector director = new ConfigDirector();ConfigurationBuilder productionBuilder = new ProductionConfigBuilder();director.Construct(productionBuilder);Configuration productionConfig = productionBuilder.GetConfiguration();Console.WriteLine(productionConfig);ConfigurationBuilder developmentBuilder = new DevelopmentConfigBuilder();director.Construct(developmentBuilder);Configuration developmentConfig = developmentBuilder.GetConfiguration();Console.WriteLine(developmentConfig);}
}

2. 报告生成

假设我们需要生成不同类型的报告(如 PDF 报告和 HTML 报告),并逐步构建报告的内容。

// 报告对象
public class Report
{public string Title { get; set; }public string Content { get; set; }public string Footer { get; set; }public override string ToString(){return $"Report: Title={Title}, Content={Content}, Footer={Footer}";}
}// 抽象建造者
public abstract class ReportBuilder
{protected Report report;public Report GetReport() => report;public abstract void BuildTitle();public abstract void BuildContent();public abstract void BuildFooter();
}// 具体建造者
public class PdfReportBuilder : ReportBuilder
{public PdfReportBuilder(){report = new Report();}public override void BuildTitle() => report.Title = "PDF Report Title";public override void BuildContent() => report.Content = "This is the content of the PDF report.";public override void BuildFooter() => report.Footer = "Generated by PDF Report Builder";
}public class HtmlReportBuilder : ReportBuilder
{public HtmlReportBuilder(){report = new Report();}public override void BuildTitle() => report.Title = "HTML Report Title";public override void BuildContent() => report.Content = "This is the content of the HTML report.";public override void BuildFooter() => report.Footer = "Generated by HTML Report Builder";
}// 导演类
public class ReportDirector
{public void Construct(ReportBuilder builder){builder.BuildTitle();builder.BuildContent();builder.BuildFooter();}
}// 客户端代码
class Program
{static void Main(string[] args){ReportDirector director = new ReportDirector();ReportBuilder pdfBuilder = new PdfReportBuilder();director.Construct(pdfBuilder);Report pdfReport = pdfBuilder.GetReport();Console.WriteLine(pdfReport);ReportBuilder htmlBuilder = new HtmlReportBuilder();director.Construct(htmlBuilder);Report htmlReport = htmlBuilder.GetReport();Console.WriteLine(htmlReport);}
}

总结

建造者模式 通过将对象的构建过程分解为多个方法调用,使得对象的创建更加灵活和可控。虽然它增加了系统的复杂度,但在需要逐步构建复杂对象的场景中,建造者模式能够显著提高代码的可维护性和扩展性。

在我看来,切碎一点,繁琐一点,微操大神,优势在我

http://www.lryc.cn/news/499137.html

相关文章:

  • leetcode 23. 合并 K 个升序链表
  • 【Redis】深入解析Redis缓存机制:全面掌握缓存更新、穿透、雪崩与击穿的终极指南
  • SQL语法——DQL查询
  • 云计算.运维.面试题
  • 基于vue和vite的计算器
  • 《OpenCV:视觉世界的魔法钥匙》
  • 部署kafka并通过python操作
  • 【JAVA】Java高级:数据库监控与调优:SQL调优与执行计划的分析
  • 【单片机开发】MCU三种启动方式(Boot选择)[主Flash/系统存储器(BootLoader)/嵌入式SRAM]
  • 跨库移植 SQL
  • (软件测试文档大全)测试计划,测试报告,测试方案,压力测试报告,性能测试,等保测评,安全扫描测试,日常运维检查测试,功能测试等全下载
  • Vue前端开发-路由跳转及带参数跳转
  • 服务器上安装 Node.js
  • 在阿里云/Linux环境搭建Gitblit服务
  • MicroBlaze软核开发(二):GPIO
  • threejs相机辅助对象cameraHelper
  • Luma 视频生成 API 对接说明
  • 服务器数据恢复—EVA存储硬盘磁头和盘片损坏离线的数据恢复案例
  • 【Python】深入探索Python类型检查:掌握 `typing` 模块的高级用法
  • Android学习15--charger
  • 顶会新宠!KAN-LSTM完美融合新方案
  • JS中对象的浅拷贝,深拷贝和引用
  • 思普企业运营平台 idsCheck Sql注入漏洞复现
  • FSWIND脉动风-风载时程生成器软件下载、安装及注册
  • spring通过RequestContextHolder获取HttpServletRequest对象
  • STM32编码器接口及编码器测速模板代码
  • qt QNetworkAccessManager详解
  • 部署 Vue 前端项目到 Linux
  • 数据分析:探索数据背后的秘密与挑战
  • 文本域设置高度 加上文字限制并show出来: