(2)创建型模式——生成器

创建型模式——生成器(Builder)

问题背景

当创建一个可以明显划分为多个可配置部件的复杂对象时,可以考虑使用生成器。比如我们现在要创建一台电脑,电脑有处理器、显卡和硬盘三个可配置部件。创建一台高配电脑和一台低配电脑,如果不使用生成器,代码是这样的:

var high = new Computer();
high.Cpu = new CoreI9();
high.Gpu = new TitanRTX();
high.Drive = new SSD();
var low = new Computer();
low.Cpu = new CoreI3();
low.Gpu = new GTX960();
low.Drive = new HHD();

这样做的弊端很明显:

  1. 用户必须清楚电脑创建过程中的每个细节,不利于程序的模块化。
  2. 用户必须手写大量创建代码,增加了出错率。
  3. 创建逻辑散落在程序的各个角落,会导致牵一发而动全身,不利于后期维护。

解决方案

为了隐藏复杂的创建逻辑,我们将电脑的创建封装到一个专门负责创建对象的类中,只暴露获取复杂对象的接口,改进后的程序结构是这样的:
程序结构
使用生成器后,用户创建电脑时只需要创建对应的生成器实现,不再需要知道任何创建电脑的细节。同时,使用了稳定性较强的接口后也不容易出现牵一发而动全身的情况。

效果

  1. 将对象的创建和表示分离,降低了模块间的耦合度。
  2. 利用多态实现不同部件的组装,可扩展性强。
  3. 将创建逻辑提取到一处,防止逻辑分散。

缺陷

生成器的实现虽然可以通过多态进行扩展,但每多一种配置,哪怕只变了一个配置项,就需要一个新的生成器类,这在大型系统中会造成类爆炸。

相关模式

  1. 抽象工厂:生成器和抽象工厂都用来创建复杂对象,但关注点不同:生成器的关注点是整体,抽象工厂的关注点是部件。
  2. 复合:复合结构通常用生成器创建。
  3. 单例:生成器常被设计成单例类。

实现

using System;

namespace Builder
{
    class Client
    {
        public interface ICPU { }
        public interface IGPU { }
        public interface IDrive { }

        public class CoreI9 : ICPU
        {
            public override string ToString()
            {
                return "酷睿I9处理器";
            }
        }

        public class CoreI3 : ICPU
        {
            public override string ToString()
            {
                return "酷睿I3处理器";
            }
        }

        public class TitanRTX : IGPU
        {
            public override string ToString()
            {
                return "TitanRTX显卡";
            }
        }

        public class GTX960 : IGPU
        {
            public override string ToString()
            {
                return "GTX960显卡";
            }
        }

        public class SSD : IDrive
        {
            public override string ToString()
            {
                return "固态硬盘";
            }
        }

        public class HHD : IDrive
        {
            public override string ToString()
            {
                return "机械硬盘";
            }
        }

        public class Computer
        {
            public ICPU Cpu { get; set; }
            public IGPU Gpu { get; set; }
            public IDrive Drive { get; set; }
            public override string ToString()
            {
                return $"一台{Cpu.ToString()},{Gpu.ToString()},{Drive.ToString()}的电脑";
            }
        }

        public interface IComputerBuilder
        {
            Computer CreateComputer();
        }

        public class HighBuilder : IComputerBuilder
        {
            public Computer CreateComputer()
            {
                var computer = new Computer();
                computer.Cpu = BuildCPU();
                computer.Gpu = BuildGPU();
                computer.Drive = BuildDrive();
                return computer;
            }
            private ICPU BuildCPU()
            {
                return new CoreI9();
            }
            private IGPU BuildGPU()
            {
                return new TitanRTX();
            }
            private IDrive BuildDrive()
            {
                return new SSD();
            }
        }

        public class LowBuilder : IComputerBuilder
        {
            public Computer CreateComputer()
            {
                var computer = new Computer();
                computer.Cpu = BuildCPU();
                computer.Gpu = BuildGPU();
                computer.Drive = BuildDrive();
                return computer;
            }
            private ICPU BuildCPU()
            {
                return new CoreI3();
            }
            private IGPU BuildGPU()
            {
                return new GTX960();
            }
            private IDrive BuildDrive()
            {
                return new HHD();
            }
        }

        static void Main(string[] args)
        {
            Console.WriteLine("创建高配电脑...");
            IComputerBuilder builder = new HighBuilder();
            var high = builder.CreateComputer();
            Console.WriteLine(high);

            Console.WriteLine("创建低配电脑...");
            builder = new LowBuilder();
            var low = builder.CreateComputer();
            Console.WriteLine(low);
        }
    }
}

运行结果

发布了10 篇原创文章 · 获赞 10 · 访问量 485

猜你喜欢

转载自blog.csdn.net/DIAX_/article/details/104131361
今日推荐