经验首页 前端设计 程序设计 Java相关 移动开发 数据库/运维 软件/图像 大数据/云计算 其他经验
当前位置:技术经验 » Java相关 » 设计模式 » 查看文章
Builder 生成器模式简介与 C# 示例【创建型2】【设计模式来了_2】
来源:cnblogs  作者:橙子家  时间:2023/8/2 9:17:47  对本文有异议

〇、简介

1、什么是生成器模式?

一句话解释:

??在构造一个复杂的对象(参数多且有可空类型)时,通过一个统一的构造链路,可选择的配置所需属性值,灵活实现可复用的构造过程。

生成器模式的重心,在于分离构建算法具体的构造实现,从而使得构建算法可以重用采用不同的构建实现,产生不同的产品。所以生成器模式都会存在两个部分:整体构建算法、部件的构造和产品的装配。

官方意图:将一个复杂对象的构建与它的表示分离,使得同样的构建过程可以创建不同的表示。

一个比喻:(班级与各科课代表)

每个班级都需要各科课代表,选人条件也会有多个,比如单科成绩名列前茅、课堂表现活跃等,还有些非必要的条件,例如是否开朗等,根据这些条件就可以制定一个标准,对应的就是统一的 IBuilder 接口。不同的科目都可以实现这个接口去生成自己的课代表。

2、优缺点和使用场景

优点:

  • 客户端不必知道目标对象内部组成的细节,目标对象本身与目标对象的创建过程解耦,使得相同的创建过程可以创建不同的目标对象;
  • 具体创建者可被扩展;
  • 更加精细化的操控目标对象的生成过程,根据生成器提供的步骤逐步构建,可以精细化的控制到产品的内部。

缺点:

  • 目标对象有很多共同特定,不同的目标对象组成类似,差异不是很多。

适用场景:

  • 当创建复杂对象的算法,应该独立于该对象的组成部分,以及它们的装配方式时。
  • 当构造过程必须允许被构造的对象有不同的表示时。

简言之:当一个类的构造函数参数个数超过4个,而且这些参数有些是可选的参数,考虑使用构造者模式。

一、简单的示例代码

 如下示例,通过生成器创建一个订单:

  1. // 测试一下
  2. public class Program
  3. {
  4. static void Main(string[] args)
  5. {
  6. OrderBuilder builder = new OrderBuilder();
  7. OrderDirector director = new OrderDirector(builder);
  8. Order order = director.Construct("John Doe", "Product ABC", 2, 10.99m);
  9. Console.WriteLine(order.ToString());
  10. Console.ReadLine();
  11. }
  12. }
  13. // 订单类
  14. public class Order
  15. {
  16. public string CustomerName { get; set; }
  17. public string ProductName { get; set; }
  18. public int Quantity { get; set; }
  19. public decimal TotalPrice { get; set; }
  20. public override string ToString() // 重写 ToString() 定义输出格式
  21. {
  22. return $"Customer: {CustomerName}\nProduct: {ProductName}\nQuantity: {Quantity}\nTotal Price: {TotalPrice}";
  23. }
  24. }
  25. // 生成器接口
  26. public interface IBuilder
  27. {
  28. OrderBuilder SetCustomer(string customerName);
  29. OrderBuilder AddProduct(string productName, int quantity, decimal price);
  30. }
  31. // 订单生成器,实现接口 IBuilder
  32. public class OrderBuilder : IBuilder
  33. {
  34. private Order order;
  35. public OrderBuilder()
  36. {
  37. order = new Order();
  38. }
  39. public OrderBuilder SetCustomer(string customerName)
  40. {
  41. order.CustomerName = customerName;
  42. return this;
  43. }
  44. public OrderBuilder AddProduct(string productName, int quantity, decimal price)
  45. {
  46. order.ProductName = productName;
  47. order.Quantity = quantity;
  48. order.TotalPrice = quantity * price;
  49. return this;
  50. }
  51. public Order Build() // 最后返回创建的 Order 对象
  52. {
  53. return order;
  54. }
  55. }
  56. // 订单导向器,完成具体的构建步骤
  57. public class OrderDirector
  58. {
  59. private OrderBuilder builder;
  60. public OrderDirector(OrderBuilder builder)
  61. {
  62. this.builder = builder;
  63. }
  64. public Order Construct(string customerName, string productName, int quantity, decimal price)
  65. {
  66. builder.SetCustomer(customerName)
  67. .AddProduct(productName, quantity, price);
  68. return builder.Build();
  69. }
  70. }

结果输出:

二、生成器模式结构

根据上一章节的示例代码,简单画一个 UML 图,如下:

IBuilder:为创建一个 Order 对象的各个信息而指定抽象接口。

OrderBuilder:实现 IBuilder 的接口以构造和装配该订单的各个部件;定义并明确它所创建的表示;提供一个获取订单的接口。

OrderDirector:构造一个使用 IBuilder 接口的对象。

Order:表示被构造的复杂对象。OrderBuilder 创建该订单的内部表示并定义它的装配过程。包含定义组成部件的类,包括将这些部件装配成最终产品的接口。

三、在 .Net 框架中的实际应用

例如在 WebAPI 项目中的 Program.cs 文件中的主方法 Main(),CreateHostBuilder(args).Build().Run()在 WebHost 构建时采用了生成器模式。

  1. public class Program
  2. {
  3. public static void Main(string[] args)
  4. {
  5. CreateHostBuilder(args).Build().Run();
  6. }
  7. public static IHostBuilder CreateHostBuilder(string[] args) =>
  8. Host.CreateDefaultBuilder(args)
  9. .ConfigureWebHostDefaults(webBuilder =>
  10. {
  11. webBuilder.UseStartup<Startup>();
  12. });
  13. }

 其生成器接口定义如下,其中 Configure 系列的配置方法均返回构建器接口类,以便在构建时,可以方便的对配置进行连续配置,这也是链式调用的经典场景之一。例如,构建时可以使用CreateHostBuilder(args).ConfigureAppConfiguration(a=>a.builder()).ConfigureServices((builder,s)=>s.register()).Build();,这样感觉像一个流水线机器一样,逐步构建完毕各个部分,最后生成出预制件。

  1. // Microsoft.Extensions.Hosting.Abstractions, Version=5.0.0.0, Culture=neutral, PublicKeyToken=adb9793829ddae60
  2. // Microsoft.Extensions.Hosting.IHostBuilder
  3. using System;
  4. using System.Collections.Generic;
  5. using Microsoft.Extensions.Configuration;
  6. using Microsoft.Extensions.DependencyInjection;
  7. using Microsoft.Extensions.Hosting;
  8. public interface IHostBuilder
  9. {
  10. IDictionary<object, object> Properties { get; }
  11. IHostBuilder ConfigureHostConfiguration(Action<IConfigurationBuilder> configureDelegate);
  12. IHostBuilder ConfigureAppConfiguration(Action<HostBuilderContext, IConfigurationBuilder> configureDelegate);
  13. IHostBuilder ConfigureServices(Action<HostBuilderContext, IServiceCollection> configureDelegate);
  14. IHostBuilder UseServiceProviderFactory<TContainerBuilder>(IServiceProviderFactory<TContainerBuilder> factory);
  15. IHostBuilder UseServiceProviderFactory<TContainerBuilder>(Func<HostBuilderContext, IServiceProviderFactory<TContainerBuilder>> factory);
  16. IHostBuilder ConfigureContainer<TContainerBuilder>(Action<HostBuilderContext, TContainerBuilder> configureDelegate);
  17. IHost Build();
  18. }

四、相关模式

AbstractFactory 与 Builder 相似,因为它也可以创建复杂对象。主要区别是 Builder 模式侧重于一步步构造一个复杂的对象,而 AbstractFactory 侧重于多个系列的产品对象(简单或复杂的)。Builder 在最后一步返回产品,而 AbstractFactory 产品时立即返回的。

另外,Composite 组合模式是用 Builder 生成的。

参考: https://www.cnblogs.com/zhuYears/archive /2012/05/25/2518008.html  https://www.cnblogs.com/gaochundong/p/design_pattern_builder.html  https://juejin.cn/post/6991323757335805960             

原文链接:https://www.cnblogs.com/hnzhengfy/p/SJMSLL_Builder.html

 友情链接:直通硅谷  点职佳  北美留学生论坛

本站QQ群:前端 618073944 | Java 606181507 | Python 626812652 | C/C++ 612253063 | 微信 634508462 | 苹果 692586424 | C#/.net 182808419 | PHP 305140648 | 运维 608723728

W3xue 的所有内容仅供测试,对任何法律问题及风险不承担任何责任。通过使用本站内容随之而来的风险与本站无关。
关于我们  |  意见建议  |  捐助我们  |  报错有奖  |  广告合作、友情链接(目前9元/月)请联系QQ:27243702 沸活量
皖ICP备17017327号-2 皖公网安备34020702000426号