设计模式---创建型模式---建造者模式

1. 建造者模式

1.1 定义

建造者模式(Builder Pattern)使用多个简单的对象一步一步构建成一个复杂的对象。这种类型的设计模式属于创建型模式,它提供了一种创建对象的最佳方式。

它与工厂模式一样,也是一种创建型设计模式。不同点在于:它创建的是一种产品,一个复杂的对象。而工厂模式它创建的是一系列产品。它将一个对象的构建与表示分离。建造者模式更加关注与零件装配的顺序。

1.2 介绍

建造者模式是将一个复杂的构建与其表示分离,使得同样的构建过程可以创建不同的表示。也就是实现局部与整体的解耦。主要解决在面临“一个复杂对象”的创建的工作的时候,通常由各个部分的子对象用一定的算法构成。由于需求的变化,这个复杂对象的各个部分经常面临着剧烈的变化,但是将它们组合在一起的算法却相对稳定。

一般建造者都有以下几种角色:

  • 产品(Product)角色:具体的产品对象。
  • 抽象建造者(Builder)角色:定义一个抽象/接口类,用来规范产品对象的各个组成成分的建造。
  • 具体建造者(ConcreteBuilder)角色:用来直接创建产品的实例,即实现抽象接口类。实现接口所要求的两种方法:1.建造方法。2.返还结构方法。一般有多少实例就有多少相应的建造方法。
  • 导演者(Director)角色:用来调用这个角色的类的具体建造者角色已创建产品对象。其没有产品类的具体知识。

建造者模式主要用于一些基本组件不变,而其组合经常变化的时候。

2. 代码实现

2.1. 普通实例

小例子:去肯德基,汉堡、可乐、薯条、炸鸡翅等是不变的,而其组合是经常变化的,生成出所谓的"套餐"。

1.产品类

@Data
@AllArgsConstructor
@NoArgsConstructor
public class SetFoods {

    private String hamburg;

    private String drink;

    private String friedFood;

}

2.抽象建造者,即定义事物的接口或者抽象类

public interface AbstractFabricationFoods {

    void fabricationHamburg();
    void fabricationDrink();
    void fabricationFriedFoods();

    SetFoods fabricationPackage();

}

3.具体建造者,即具体的实现类

//套餐一
public class FabricationPackage1 implements AbstractFabricationFoods {

    @Override
    public void fabricationHamburg() {
        System.out.println("制作爆浆芝士汉堡");
    }

    @Override
    public void fabricationDrink() {
        System.out.println("制作可乐");
    }

    @Override
    public void fabricationFriedFoods() {
        System.out.println("制作炸鸡");
    }

    @Override
    public SetFoods fabricationPackage() {
        return new SetFoods();
    }
}
//套餐二
public class FabricationPackage2 implements AbstractFabricationFoods {

    @Override
    public void fabricationHamburg() {
        System.out.println("制作芝士汉堡");
    }

    @Override
    public void fabricationDrink() {
        System.out.println("制作雪碧");
    }

    @Override
    public void fabricationFriedFoods() {
        System.out.println("制作炸鸡翅");
    }

    @Override
    public SetFoods fabricationPackage() {
        return new SetFoods();
    }
}

4.导演,即制作事物的决定者

public class FoodsDirector {

    public SetFoods fabricationFoods(AbstractFabricationFoods aff) {
        aff.fabricationHamburg();
        aff.fabricationDrink();
        aff.fabricationFriedFoods();
        return aff.fabricationPackage();
    }
}

5.测试类

public class Test {
    public static void main(String[] args) {
        FoodsDirector fd=new FoodsDirector();
        fd.fabricationFoods(new FabricationPackage1());
        fd.fabricationFoods(new FabricationPackage2());
    }
}

/**
 *制作爆浆芝士汉堡
 * 制作可乐
 * 制作炸鸡
 * 制作芝士汉堡
 * 制作雪碧
 * 制作炸鸡翅
 */

2.2 StringBuilder的源码分析

具体来说,StirngBuilder就是一个典型的建造者模式的实现,JDK中的StirngBuilder提供了append()追加方法,这是一种链式调用,最后通过toString()返回该对象的字符串类型。

1.抽象类

public abstract class MyAbstractStringBuilder {

    char[] value;

    int count;

    //创造一个大小为capacity的空间
    public MyAbstractStringBuilder(int capacity) {
        count = 0;
        value = new char[capacity];
    }

    //添加字符串
    public MyAbstractStringBuilder append(String str) {
        if (str == null)
            return null;
        int len = str.length();
        ensureCapacityInternal(count + len);
        str.getChars(0, len, value, count);
        count += len;
        return this;
    }

    //确保内部容量足够
    private void ensureCapacityInternal(int minimumCapacity) {
        if (minimumCapacity - value.length > 0)
            expandCapacity(minimumCapacity);
    }

    //扩展容量  minimumCapacity代表最小容量
    void expandCapacity(int minimumCapacity) {
        int newCapacity = (value.length << 1) + 2; //相当于value.length * 2 + 2;
        if (newCapacity - minimumCapacity < 0)
            newCapacity = minimumCapacity;
        if (newCapacity < 0) {
            if (minimumCapacity < 0)
                throw new OutOfMemoryError();  //内存不足错误
            //Integer.MAX_VALUE表示int数据类型的最大取值数:2 147 483 647
            //Integer.MIN_VALUE表示int数据类型的最小取值数:-2 147 483 648
            newCapacity = Integer.MAX_VALUE;
        }
        value = Arrays.copyOf(value, newCapacity);
    }
}

2.实现类

public class MyStringBuilder extends MyAbstractStringBuilder {

    public MyStringBuilder() {
        super(16);
    }

    @Override
    public String toString() {
        // Create a copy, don't share the array
        return new String(value, 0, count);
    }

    @Override
    public MyStringBuilder append(String str) {
        super.append(str);
        return this;
    }

}

3.测试类

public class Test2 {
    public static void main(String[]args){
        MyStringBuilder sb = new MyStringBuilder();
        sb.append("(").append("hello").append(",").append("world").append(")").toString();
        System.out.println(sb);
    }
}
/**
 * (hello,world)
 */

此处只实现了具体的添加字符串的方法,我们能看到可以通过append()来添加,进而获得自己想得到的字符串。

3. 优/缺点

建造者模式对产品的创建和产品的实现进行了解耦,使得可以通过相同的方法创建出不同的对象,用户只需要指定对象的类型和内容就可以得到想要的结果。主要在需要生成的对象具有复杂的内部结构或者需要生成的对象内部属性本身相互依赖时使用。

优点:

  • 建造者独立,易扩展。
  • 便于控制细节风险。

缺点:

  • 产品必须有共同点,范围有限制。
  • 如内部变化复杂,会有很多的建造类。
  • 0
    点赞
  • 1
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
1) 优秀的程序应该是这样的:阅读时,感觉很优雅;新增功能时,感觉很轻松;运行时,感觉很快速,这就需要设计模式支撑。2) 设计模式包含了大量的编程思想,讲授和真正掌握并不容易,网上的设计模式课程不少,大多讲解的比较晦涩,没有真实的应用场景和框架源码支撑,学习后,只知其形,不知其神。就会造成这样结果: 知道各种设计模式,但是不知道怎么使用到真实项目。本课程针对上述问题,有针对性的进行了升级 (1) 授课方式采用 图解+框架源码分析的方式,让课程生动有趣好理解 (2) 系统全面的讲解了设计模式,包括 设计模式七大原则、UML图-的六大关系、23种设计模式及其分,比如 单例模式的8种实现方式、工厂模式的3种实现方式、适配器模式的3种实现、代理模式的3种方式、深拷贝等3) 如果你想写出规范、漂亮的程序,就花时间来学习下设计模式吧课程内容和目标本课程是使用Java来讲解设计模式,考虑到设计模式比较抽象,授课采用 图解+框架源码分析的方式1) 内容包括: 设计模式七大原则(单一职责、接口隔离、依赖倒转、里氏替换、开闭原则、迪米特法则、合成复用)、UML图(的依赖、泛化和实现、的关联、聚合和组合) 23种设计模式包括:创建型模式:单例模式(8种实现)、抽象工厂模式、原型模式、建造者模式、工厂模式。结构型模式:适配器模式(3种实现)、桥接模式、装饰模式、组合模式、外观模式、享元模式、代理模式(3种实现)。行为型模式:模版方法模式、命令模式、访问者模式、迭代器模式、观察者模式、中介者模式、备忘录模式、解释器模式(Interpreter模式)、状态模式、策略模式、职责链模式(责任链模式)2) 学习目标:通过学习,学员能掌握主流设计模式,规范编程风格,提高优化程序结构和效率的能力。
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值