65.9K
CodeProject 正在变化。 阅读更多。
Home

构建器设计模式

starIconstarIconstarIconstarIcon
emptyStarIcon
starIcon

4.66/5 (25投票s)

2016 年 11 月 18 日

CPOL

5分钟阅读

viewsIcon

25018

downloadIcon

83

在本文中,我们将了解构建器设计模式,并创建一个演示应用程序来实践理解它。我们将探讨构建器模式如何帮助我们创建复杂的对象。

引言

在本文中,我们将了解构建器设计模式,并创建一个演示应用程序来实践理解它。我们将探讨构建器模式如何帮助我们创建复杂的对象。

目录

  • 什么是构建器模式
  • 何时使用构建器模式
  • 通过示例理解定义
  • 构建器模式的问题

什么是构建器模式

构建器设计模式在《设计模式》(GoF)一书中有所描述,属于创建型模式。以下是摘自《设计模式》(GoF)一书的构建器模式的定义:

“将一个复杂对象的构建与它的表示分离,使得相同的构建过程可以创建不同的表示。”

我们将在本文的“通过示例理解定义”部分详细了解这个定义。

何时使用构建器模式

该模式可用于需要分步完成大量工作来构建相似的复杂对象的情况。换句话说,该模式在需要通过特定过程或算法组装小对象(复杂对象的组成部分)来创建复杂对象时很有用。

在许多场景中,我们需要创建几种复杂的对象,但这些对象都遵循相似的构建过程。例如,构建不同类型的自行车(儿童自行车、标准自行车、女士自行车和山地自行车等)的基本步骤是相同的。我们在这里得到了两点:

  1. 构建复杂对象的通用步骤(将了解它如何与 Director 协同工作)
  2. 该复杂对象的不同表示及其相应部件的创建(将了解它如何与 Concrete Builders 协同工作)

通过示例理解定义

因此,让我们以这个场景为例来详细了解构建器模式。假设我们要制造几辆自行车,它们是相当复杂的对象。要制造自行车,我们需要其他小对象,它们将是自行车的一部分,如车架、车轮、把手、齿轮、链条等。为了构造自行车,我们现在需要分步组装所有部件,只有这样才能制造出自行车。在本节中,我们将实现构建器模式,通过组装适合这些自行车的必需部件来创建不同类型的自行车。

让我们通过上述场景来理解构建器模式的定义。首先创建一个上述场景的设计图,并尝试将定义与场景关联起来。

下图显示了使用构建器模式实现上述场景所需的实体或类。

Builder Classes

因此,我们将遵循上述设计并解释构建器模式的标准定义。

根据定义“将一个复杂对象的构建与它的表示分离…”,在上面的图表中,BicycleBuildDirector 类将拥有创建复杂对象的所有构建逻辑,该对象将是实际的构建器类 Bicycle 的表示。“…使得相同的构建过程可以创建不同的表示。” 这里,同一个 BicycleBuildDirector 可以用来创建 Bicycle 的不同表示,即 KidsBicycleBuilder 和 RoadBicycleBuilder。

构建器模式的主要组件/参与者

  • Director (BicycleBuildDirector)
  • 抽象构建器 (IBicycleBuilder)
  • 具体构建器 (KidsBicycleBuilder, RoadBicycleBuilder 等)
  • 产品 (Bicycle)

以下是上述场景的实现。

创建一个表示产品对象的类。

    public class Bicycle
    {
        public string BicycleType { get; set; }
        public int BicycleHeight { get; set; }
        public string BicycleColour { get; set; }
    }

现在创建一个名为 IBicycleBuilder 的接口,该接口将包含创建自行车所需的所有方法定义。

    // IBicycleBuilder provides an interface for different Builders of Bicycle
    // ConcreteBuilder are like KidsBicycleBuilder, RoadBicycleBuilder, LadiesBicycleBuilder, MountainBicycleBuilder
    // A Concrete Builder have creation logic of parts which are assembled 
    // to create a particular type (of different Representations) of bicycle.
    public interface IBicycleBuilder
    {
        void SetHeight(int height);
        void SetFrame();
        void SetGears();
        void PutTires();
        void SetColour(string colour);
        void PutAccessaries();
        Bicycle GetBicycle();
    }

现在我们要为孩子制造自行车。所以让我们创建一个名为 KidsBicycleBuilder 的类。这个类将实现 IBicycleBuilder 接口,其实现将根据 Kids 自行车的需求。

    // Builds components and set them as per need of a Kids Bicycle
    class KidsBicycleBuilder : IBicycleBuilder
    {
        private Bicycle bicycle;
        public KidsBicycleBuilder()
        {
            bicycle = new Bicycle();
            bicycle.BicycleType = "Kids Bicycle";
        }
        public void SetHeight(int height)
        {
            Console.WriteLine("Bicycle is set with given height: {0}", height);
            bicycle.BicycleHeight = height;
        }
        public void SetFrame()
        {
            Console.WriteLine("Frame has been set.");
        }
        public void SetGears()
        {
            Console.WriteLine("Gears have been set.");
        }
        public void PutTires()
        {
            Console.WriteLine("Tires have been set.");
        }
        public void SetColour(string colour)
        {
            Console.WriteLine("Bicycle is set with given colour: {0}", colour);
            bicycle.BicycleColour = colour;
        }
        public void PutAccessaries()
        {
            Console.WriteLine("Accessaries have been set.");
        }
        public Bicycle GetBicycle()
        {
            return this.bicycle;
        }
    }

同样,创建一个名为 RoadBicycleBuilder 的更多类,并实现 IBicycleBuilder 接口。这个类将构建一辆公路自行车(完整代码请下载本文附带的源代码)。

    class RoadBicycleBuilder : IBicycleBuilder {...}

让我们创建一个名为 BicycleBuildDirector 的 Director,它包含使用自行车构建器构建自行车的流程或算法。Director 按创建自行车过程中所需的顺序调用构建器类的方。

    // Director encapsulate the process to construct a bicycle
    // It sets required attribute and start building process using a concrete builder.
    // It contains the flow or algorithm to be followed to create a bicycle
    // i.e. assembling bicycle by getting parts from a builder
    // and coordinating with inventory/departments and notifying stockholders
    public class BicycleBuildDirector
    {
        SellDepartment sellDepartment = new SellDepartment();
        public Bicycle Construct(IBicycleBuilder builder, string colour, int height)
        {
            // Start Process and Notify user
            Console.WriteLine("We have sarted process for Bicycle manufacturing");
            // Follow the process and set attributes given
            builder.SetFrame();
            builder.SetGears();
            builder.SetColour(colour);
            builder.SetHeight(height);
            builder.PutTires();
            builder.PutAccessaries();
            Bicycle bicycle = builder.GetBicycle();
            // Coordinate with other departments/inventories     
            sellDepartment.GenerateInvoice(bicycle.BicycleType, colour, height);
            // End Process and Notify user
            Console.WriteLine("{0} is ready for your disposal.\n ** Happy Riding ! **", bicycle.GetType());
            return bicycle;
        }
    }

以下代码显示了客户端如何创建 BicycleBuildDirector 类的实例,并通过传递所需参数来调用 Construct 方法以获得所需的自行车。

     static void Main(string[] args)
        {
            BicycleBuildDirector buildDirector = new BicycleBuildDirector();
            Bicycle bicycle = buildDirector.Construct(new KidsBicycleBuilder(), "Red", 16);            
        }

如果客户端想要获得一辆公路自行车,他只需要修改 BicycleBuildDirector 的 Construct 方法的参数,如下所示。

    Bicycle bicycle = buildDirector.Construct(new RoadBicycleBuilder(), "Blue", 24);  

通过这种方式,通过将不同的构建器与相同的 Director 一起使用,客户端能够创建不同类型的自行车。

构建器模式的问题

每种设计模式都属于特定的问题领域。我们已经知道,当我们需要创建遵循分步创建过程的相似对象时,应该使用构建器模式。因此,除非出现这种情况,否则使用构建器模式将是一种负担。

此外,还有一些关于构建器模式缺点的讨论,例如在这个 Stack Overflow 页面。据说,使用构建器模式,我们需要创建更多的类(这会引入更多的复杂性)。这些都是因为尝试在相对简单的场景或不需要它的地方使用构建器模式。

但是,当我们在足够复杂的情况下使用它时,它有助于我们更好地组织整体创建过程,提高可读性和可维护性,从而帮助我们轻松应对复杂性。

结论

在本文中,我们通过一个示例学习了构建器模式及其用法。我们理解了构建器模式的上下文以及如何使用它来提高应用程序的可维护性。感谢您的阅读。非常欢迎您提出改进意见和建议。

参考文献

© . All rights reserved.