生成器设计模式是一种创建性设计模式,允许使用 Builder 对象逐步创建复杂对象。客户端代码不是直接创建对象,而是在 Builder 对象上调用一系列方法来创建对象。这允许在创建对象时具有更大的灵活性,因为相同的客户端代码可用于创建具有不同实现的对象。
生成器设计模式的关键元素是生成器界面、混凝土生成器、控制器和产品。
生成器接口定义用于创建对象各部分的方法。这些方法通常由控制器调用。
ConcreteBuilder 是一个实现 Builder 接口并提供用于创建对象各部分的实际实现的类。
控制器负责使用生成器对象来创建对象。它通过在生成器对象上调用适当的方法来执行此操作。
产品是由构建器创建的复杂对象。它由构建器创建的零件组成。
下面是如何使用生成器设计模式的示例:
想象一下,您正在创建一个用于建造房屋的工具。可以建造多种类型的房屋,例如单层房屋,两层房屋和带地下室的房屋。每种类型的房屋都有一组不同的建造步骤。
要使用 Builder 设计模式建造房屋,您需要创建一个 Builder 界面,该界面定义了构建房屋各个部分(例如地基、墙壁、屋顶等)的方法。然后,您将为每种类型的房屋创建 ConcreteBuilder 类,这些类实现 Builder 接口并提供用于构建该类型房屋的特定实现。
然后,客户端代码将创建一个特定的 ConcreteBuilder 对象并将其传递给控制器。然后,控制器将在 Builder 对象上调用适当的方法来构建房屋。这允许使用相同的客户端代码来构建不同类型的房屋,因为具体的实现由 ConcreteBuilder 提供。
对于代码,让我们看看:
using System; namespace BuilderDesignPattern { // Builder interface public interface IHouseBuilder { void BuildFoundation(); void BuildWalls(); void BuildRoof(); House GetHouse(); } // Concrete Builder public class SingleStoryHouseBuilder : IHouseBuilder { private House _house = new House(); public void BuildFoundation() { Console.WriteLine("Building foundation for single-story house"); _house.Add("Foundation"); } public void BuildWalls() { Console.WriteLine("Building walls for single-story house"); _house.Add("Walls"); } public void BuildRoof() { Console.WriteLine("Building roof for single-story house"); _house.Add("Roof"); } public House GetHouse() { return _house; } } // Concrete Builder public class TwoStoryHouseBuilder : IHouseBuilder { private House _house = new House(); public void BuildFoundation() { Console.WriteLine("Building foundation for two-story house"); _house.Add("Foundation"); } public void BuildWalls() { Console.WriteLine("Building walls for two-story house"); _house.Add("Walls"); } public void BuildRoof() { Console.WriteLine("Building roof for two-story house"); _house.Add("Roof"); } public House GetHouse() { return _house; } } // Product public class House { private string[] _parts; public House() { _parts = new string[3]; } public void Add(string part) { for (int i = 0; i < _parts.Length; i++) { if (_parts[i] == null) { _parts[i] = part; break; } } } public void Show() { Console.WriteLine("/nHouse is complete. It includes the following parts:"); foreach (string part in _parts) { Console.WriteLine(part); } } } // Director public class HouseBuilder { public void Construct(IHouseBuilder houseBuilder) { houseBuilder.BuildFoundation(); houseBuilder.BuildWalls(); houseBuilder.BuildRoof(); } } }
您可以使用客户大小的构建器来创建这样的房屋:
class Program { static void Main(string[] args) { HouseBuilder builder = new HouseBuilder(); IHouseBuilder singleStoryHouseBuilder = new SingleStoryHouseBuilder(); IHouseBuilder twoStoryHouseBuilder = new TwoStoryHouseBuilder(); // Build single-story house builder.Construct(singleStoryHouseBuilder); House singleStoryHouse = singleStoryHouseBuilder.GetHouse(); singleStoryHouse.Show(); // Build two-story house builder.Construct(twoStoryHouseBuilder); House twoStoryHouse = twoStoryHouseBuilder.GetHouse(); twoStoryHouse.Show(); } }
假设您正在开发一个用于创建网页的软件应用程序。网页可以具有不同的布局,例如单列布局、两列布局和三列布局。每个网页还具有一组可以包含的元素,例如页眉、导航菜单和页脚。
要使用 Builder 设计模式创建网页,您可以创建一个界面来定义构建网页各种元素的方法(例如 setHeader()、setNavigationMenu()、setFooter() 等)。然后,您可以为每种类型的布局创建具体的类,例如 、 和 ,这些类实现接口并提供用于创建该类型布局的特定实现。WebPageBuilder
OneColumnLayoutBuilder
TwoColumnLayoutBuilder
ThreeColumnLayoutBuilder
WebPageBuilder
然后,客户端代码将创建一个特定对象并将其传递给 ,然后 将在对象上调用适当的方法来创建网页。这允许使用相同的客户端代码来创建不同类型的网页,因为具体的实现由具体类提供。WebPageBuilder
WebPageDirector
WebPageBuilder
WebPageBuilder
要创建它,您必须按照以下步骤操作:
首先,你确实需要一个产品。这是表示正在构建的产品的类。它具有用于存储产品不同部分的各种字段。这是其中之一:
// Product public class WebPage { public string Header { get; set; } public string Menu { get; set; } public string Footer { get; set; } public void Show() { Console.WriteLine("/nWeb page is complete. It includes the following elements:"); Console.WriteLine("Header: " + Header); Console.WriteLine("Menu: " + Menu); Console.WriteLine("Footer: " + Footer); } }
其次,您必须创建 Builder 接口,该接口是定义构建产品各个部分的方法的接口。它由混凝土生成器类实现。
// Builder interface public interface IWebPageBuilder { void SetHeader(string header); void SetNavigationMenu(string menu); void SetFooter(string footer); WebPage GetWebPage(); }
第三部分是混凝土建造者。这些类实现生成器接口并提供用于生成产品的特定实现。可以有多个混凝土生成器类,每个类创建产品的不同版本。
// Concrete Builder public class OneColumnLayoutBuilder : IWebPageBuilder { private WebPage _webPage = new WebPage(); public void SetHeader(string header) { _webPage.Header = header; } public void SetNavigationMenu(string menu) { _webPage.Menu = menu; } public void SetFooter(string footer) { _webPage.Footer = footer; } public WebPage GetWebPage() { return _webPage; } } // Concrete Builder public class TwoColumnLayoutBuilder : IWebPageBuilder { private WebPage _webPage = new WebPage(); public void SetHeader(string header) { _webPage.Header = header; } public void SetNavigationMenu(string menu) { _webPage.Menu = menu; } public void SetFooter(string footer) { _webPage.Footer = footer; } public WebPage GetWebPage() { return _webPage; } } // Concrete Builder public class ThreeColumnLayoutBuilder : IWebPageBuilder { private WebPage _webPage = new WebPage(); public void SetHeader(string header) { _webPage.Header = header; } public void SetNavigationMenu(string menu) { _webPage.Menu = menu; } public void SetFooter(string footer) { _webPage.Footer = footer; } public WebPage GetWebPage() { return _webPage; } }
最后,您需要一个控制器来定义构建步骤。Director 是一个使用生成器接口构造产品的类。它负责创建构建产品的正确步骤序列。
// Director public class WebPageDirector { public void Construct(IWebPageBuilder builder) { builder.SetHeader("Header"); builder.SetNavigationMenu("Menu"); builder.SetFooter("Footer"); } }
好的,就是这样。它已准备好在客户端上使用或您想要使用的位置使用。让我们创建一个网页,嗯?
class Program { static void Main(string[] args) { // Create director and builders WebPageDirector director = new WebPageDirector(); IWebPageBuilder oneColumnBuilder = new OneColumnLayoutBuilder(); IWebPageBuilder twoColumnBuilder = new TwoColumnLayoutBuilder(); IWebPageBuilder threeColumnBuilder = new ThreeColumnLayoutBuilder(); // Construct one-column web page Console.WriteLine("Building one-column web page"); director.Construct(oneColumnBuilder); WebPage oneColumnWebPage = oneColumnBuilder.GetWebPage(); oneColumnWebPage.Show(); // Construct two-column web page Console.WriteLine("/nBuilding two-column web page"); director.Construct(twoColumnBuilder); WebPage twoColumnWebPage = twoColumnBuilder.GetWebPage(); twoColumnWebPage.Show(); // Construct three-column web page Console.WriteLine("/nBuilding three-column web page"); director.Construct(threeColumnBuilder); WebPage threeColumnWebPage = threeColumnBuilder.GetWebPage(); threeColumnWebPage.Show(); } }
弊
使用 Builder 设计模式的一个潜在缺点是,它可能导致生成大量代码,因为每个产品变型通常都有一个单独的 Concrete Builder 类。这会使代码更难维护和理解。
另一个缺点是,对于简单产品来说,Builder 模式可能有点过分,因为它增加了额外的抽象级别,并使代码更加复杂。在这种情况下,直接创建对象可能比使用生成器更简单。
值得注意的是,与任何设计模式一样,Builder 模式不是一个放之四海而皆准的解决方案,应根据正在开发的软件的特定需求适当使用。
结论
总之,Builder 设计模式是一种创建性设计模式,允许逐步构建复杂对象。它将构造过程与对象的表示分开,允许相同的构造过程创建不同的表示。当构造过程复杂且要构造的对象由多个部分组成时,生成器模式非常有用。它还可用于构造不可变的对象,并提供对构造过程的更高级别的控制。但是,它可能会导致生成大量代码,并且对于简单产品来说可能是矫枉过正的。与任何设计模式一样,根据正在开发的软件的特定需求适当地使用 Builder 模式非常重要。
下面是生成器模式可能有用的一些特定需求:
- 当构造过程复杂且要构造的对象由多个部分组成时,可以使用 Builder 模式来简化构造过程并使其更易于理解。
- 当构造过程需要高度灵活并能够生成对象的不同表示时,可以使用 Builder 模式将构造过程与对象的表示分开。
- 当要构造的对象是不可变的并且需要线程安全时,可以使用 Builder 模式逐步构造对象,确保在创建对象后不会对其进行修改。
- 当需要对构造过程进行高级别控制时,可以使用 Builder 模式来指定构造对象所需的确切步骤顺序。
- 当需要能够轻松地将新类型的产品添加到软件中时,Builder 模式可用于创建实现 Builder 接口的新混凝土生成器,并且可以以与现有混凝土生成器相同的方式使用。
本站声明:
1. iCode9 技术分享网(下文简称本站)提供的所有内容,仅供技术学习、探讨和分享;
2. 关于本站的所有留言、评论、转载及引用,纯属内容发起人的个人观点,与本站观点和立场无关;
3. 关于本站的所有言论和文字,纯属内容发起人的个人观点,与本站观点和立场无关;
4. 本站文章均是网友提供,不完全保证技术分享内容的完整性、准确性、时效性、风险性和版权归属;如您发现该文章侵犯了您的权益,可联系我们第一时间进行删除;
5. 本站为非盈利性的个人网站,所有内容不会用来进行牟利,也不会利用任何形式的广告来间接获益,纯粹是为了广大技术爱好者提供技术内容和技术思想的分享性交流网站。
原创文章,作者:ItWorker,如若转载,请注明出处:https://blog.ytso.com/295246.html