一看就懂的设计模式——建造者模式(06)

定义

建造者模式(Builder Design Pattern)属于创建型设计模式,将一个复杂对象的构建与它的表示分离,使得同样的构建过程可以创建不同的表示。

意义

在这里插入图片描述

建造者模式可以将一个产品的内部表象与产品的生成过程分割开来,从而可以使一个建造过程生成具有不同的内部表象的产品对象。如果我们用建造者模式,那么用户就只需要指定需要建造的类型就可以得到它们,而具体建造的过程和细节就不需要知道了。

真实世界类比

在这里插入图片描述

5料现调咖啡机是个不错的类比,用户只需要提供想要3种饮料中的哪一种,由工作人员通过点击对应按钮向咖啡机发出指令(机器提前设定好了各种饮料的冲调步骤),机器在内部会自动完成所有的冲调过程,而对于用户来说,是不知道内部的冲调过程。

结构

在这里插入图片描述

C#代码

using System;

namespace Builder
{
    public interface ICarBuilder
    {
        void BuildSeats();        
        void BuildEngine();        
        void BuildWheel();     
        void BuildBody();
    }
    
    public class SUVBuilder : ICarBuilder
    {
        private SUV _suv = new SUV();
        
        public void BuildSeats()
        {
            this._suv.Add("拥有7个座位");
        }
        
        public void BuildEngine()
        {
            this._suv.Add("拥有4驱引擎");
        }
        
        public void BuildWheel()
        {
            this._suv.Add("拥有加宽车轮");
        }
        
        public void BuildBody()
        {
            this._suv.Add("拥有超大车身");
        }
        
        public string GetCar()
        {
            return this._suv.GetCar();
        }
    }
    
    public class SUV
    {
        private string _parts = "";
        
        public void Add(string part)
        {
            this._parts += part + "\n";
        }
        
        public string GetCar()
        {
            return "你需要的SUV: \n" + str + "\n";
        }
    }
    
    public class SportCarBuilder : ICarBuilder
    {
        private SportCar _car = new SportCar();
        
        public void BuildSeats()
        {
            this._car.Set("拥有5个运动座椅");
        }
        
        public void BuildEngine()
        {
            this._car.Set("拥有4缸涡轮增压发动机");
        }
        
        public void BuildWheel()
        {
            this._car.Set("拥有防滑车轮");
        }
        
        public void BuildBody()
        {
            this._car.Set("拥有流线型车身");
        }
        
        public string GetCar()
        {
            return this._car.GetCar();
        }
    }
    
    public class SportCar 
    {
        private string _parts = "";
        
        public void Set(string part)
        {
            this._parts += part + "\n";
        }
        
        public string GetCar()
        {
            return "你需要的SportCar: \n" + _parts + "\n";
        }
    }
    
    public class CarDirector
    {
        private IBuilder _builder;
        
        public IBuilder Builder
        {
            set { _builder = value; } 
        }
        
        public void MakeCar()
        {
            this._builder.BuildSeats();
            this._builder.BuildEngine();
            this._builder.BuildWheel();
            this._builder.BuildBody();
        }        
    }

    class Program
    {
        static void Main(string[] args)
        {
            var director = new CarDirector();
            var suvbuilder = new SUVBuilder ();
            director.Builder = suvbuilder;            
            director.MakeCar();
            Console.WriteLine(builder.GetCar());

            Console.WriteLine("= = = = = = = = = = = = = = =");
            var sportcarbuilder = new SportCarBuilder();
            director.Builder = sportcarbuilder;
            director.MakeCar();
            Console.WriteLine(builder.GetCar());
        }
    }
}

运行结果如下:

你需要的SUV:
拥有7个座位
拥有4驱引擎
拥有加宽车轮
拥有超大车身

= = = = = = = = = = = = = = =
你需要的SportCar:
拥有5个运动座椅
拥有4缸涡轮增压发动机
拥有防滑车轮
拥有流线型车身

应用场景

  • 需要生成的产品对象有复杂的内部结构,这些产品对象通常包含多个成员变量
  • 需要生成的产品对象的属性相互依赖,需要指定其生成顺序
  • 对象的创建过程独立于创建该对象的类。在建造者模式中通过引入了指挥者类,将创建过程封装在指挥者类中,而不在建造者类和客户类中
  • 隔离复杂对象的创建和使用,并使得相同的创建过程可以创建不同的产品

模式优点

  • 客户端不必知道产品内部组成的细节,将产品本身与产品的创建过程解耦,使得相同的创建过程可以创建不同的产品对象
  • 每一个具体建造者都相对独立,与其他的具体建造者无关,因此可以很方便地替换具体建造者或增加新的具体建造者,扩展方便,符合开闭原则
  • 可以更加精细地控制产品的创建过程

模式缺点

  • 建造者模式所创建的产品一般具有较多的共同点,其组成部分相似,如果产品之间的差异性很大,不适合使用建造者模式,因此其使用范围受到一定的限制
  • 如果产品的内部变化复杂,可能会需要定义很多具体建造者类来实现这种变化,导致系统变得很庞大,增加了系统的理解难度和运行成本
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值