23设计模式之 --------- 建造者模式

1.建造者模式简介

1.1定义:

建造者模式:将一个复杂的对象的构建与它的表示分离,使得同样的构建过程可以创建不同的表示。

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

一个 Builder 类会一步一步构造最终的对象。该 Builder 类是独立于其他对象的

1.2实用范围

1、当创建复杂对象的算法应该独立于该对象的组成部分以及它们的装配方式时。
2、当构造过程必须允许被构造的对象有不同表示时。

1.3介绍

意图:将一个复杂的构建与其表示相分离,使得同样的构建过程可以创建不同的表示。

主要解决:主要解决在软件系统中,有时候面临着"一个复杂对象"的创建工作,其通常由各个部分的子对象用一定的算法构成;由于需求的变化,这个复杂对象的各个部分经常面临着剧烈的变化,但是将它们组合在一起的算法却相对稳定。

何时使用:一些基本部件不会变,而其组合经常变化的时候。

如何解决:将变与不变分离开。

关键代码:建造者:创建和提供实例,导演:管理建造出来的实例的依赖关系。

应用实例: 1、去肯德基,汉堡、可乐、薯条、炸鸡翅等是不变的,而其组合是经常变化的,生成出所谓的"套餐"。 2、JAVA 中的 StringBuilder。

优点: 1、建造者独立,易扩展。 2、便于控制细节风险。

缺点: 1、产品必须有共同点,范围有限制。 2、如内部变化复杂,会有很多的建造类。

使用场景: 1、需要生成的对象具有复杂的内部结构。 2、需要生成的对象内部属性本身相互依赖。

注意事项:与工厂模式的区别是:建造者模式更加关注与零件装配的顺序。

2.0 建造者模式

在这里插入图片描述
主要使用:于复杂的对象场景;

在这里插入图片描述
看完结构我们来用代码更好的理解下把(我自己看ppt也无法深刻得到理解)
在这里插入图片描述
抽象的建造者方法 Builder

//抽象的建造者方法
public abstract class Builder {

    abstract  void buildA();//地基
    abstract  void buildB();//钢筋工程
    abstract  void buildC();//铺电线
    abstract  void buildD();//粉刷

    //得到产品
    abstract Product getProduct();

}

产品 Product

//产品(房子)
@Data
@AllArgsConstructor
@NoArgsConstructor
public class Product {

    private  String buildA;
    private  String buildB;
    private  String buildC;
    private  String buildD;


    @Override
    public String toString() {
        return "Product{" +
                "buildA='" + buildA + '\'' +
                ", buildB='" + buildB + '\'' +
                ", buildC='" + buildC + '\'' +
                ", buildD='" + buildD + '\'' +
                '}';
    }
}

Worker

public class Worker extends Builder{
    private Product product;

    //由工人进行创建产品 此处构造需注意
    public Worker() {
        product = new Product();
    }

    @Override
    void buildA() {
     product.setBuildA("地基");
     System.out.println(product.getBuildA());
    }

    @Override
    void buildB() {
        product.setBuildB("钢筋工程");
        System.out.println(product.getBuildB());
    }

    @Override
    void buildC() {
        product.setBuildC("铺电线");
        System.out.println(product.getBuildC());
    }

    @Override
    void buildD() {
        product.setBuildC("粉刷");
        System.out.println(product.getBuildC());
    }

    @Override
    Product getProduct() {
        return product;
    }
}

Director 他来指挥先执行那个就先执行那个进行顺序排序

//指挥:核心 负责指挥一个工程 工程如何创建 由他决定
public class Director {

    //指挥工人按照顺序建筑房子 他会指定执行的顺序
    public Product build(Builder builder){
        builder.buildA();

        builder.buildC();
        builder.buildD();
        builder.buildB();
        return builder.getProduct();
    }


}

测试 Test
指定new Worker() 为不同方法就执行不同的程序代码;

//测试
public class Test {

    public static void main(String[] args) {
        Director director = new Director();
        //指挥 指挥具体的工人
        Product build = director.build(new Worker());
        System.out.println(build.toString());
    }
}

执行结果如下:
在这里插入图片描述

2.1 抽象类简单理解

解释:抽象,抽取事物的共性

特点

  1. 方法只有声明没有实现时,该方法是抽象方法,要被abstract修饰,抽象方法必须定义在抽象类中,该类也被abstract修饰。

  2. 抽象类不可以被实例化,为什么?
    解答:调用抽象方法没有意义。

  3. 抽象类必须有其子类覆盖了所有的抽象方法后,该子类才可以实例化,否则,这个子类还是抽象类。

问题:

  1. 抽象类中有构造函数吗?
    解答:有,用于给子类对象初始化。
  2. 抽象类可以不定义抽象方法吗?
    解答:可以,但是十分少见,目的就是让该类创建对象。AWT的适配器对象就是这种类,通常这种类的方法有方法体,但是没有内容。
    例如
abstract class Demo{
    void show() { }
}
  1. 抽象关键字不可以和哪些关键字共存?
    解答:
    1).private :因为一个abstract方法需要被重写,所以不能修饰为private;
    2).final:因为一个abstract方法需要被重写。被final修饰的方法是不能被重写的,所以不能同final共存;
    3).static:因为一个abstract方法没有方法体。静态方法需要对方法体执行内容分配空间,所以不能同static共存;(abstract是没有实现的,不能产生对象,而是static是属于类的,类本身是已经存在的对象);
    4).synchronized: 是同步的,然而同步需要具体的操作才能同步,但, abstract是只有声明没有实现的(即,使用synchronized关键字的是需要有具体的实现同步的操作的,但是使用abstract是只有声明而没有实现的,这样就产生了冲突);
    5).native:他们本身的定义就是冲突的,native声明的方法是移交本地操作系统实现的,而abstract是移交子类对象实现的,同时修饰的话,导致不知道谁实现声明的方法。

  2. 抽象类和一般类的异同点
    相同点:抽象类和一般类都是用来描述事物的,在内部定义了成员。
    不同点:
    1.一般类有足够的信息描述事物,抽象类有可能不足;
    2.一般类不能定义抽象方法,抽象类可以定义抽象方法和非抽象方法。
    3.一般类可以被实例化,抽象类不可以被实例化。

  3. 抽象类一定是父类吗?
    解答:是的,因为需要其子类覆盖其方法后才可以实现对子类实例化。

抽象类的特点

1.由abstract修饰的类叫做抽象类,也可以修饰抽象方法

2.abstract修饰的抽象方法可以不在抽象类当中实现,但一定要在子类当中重写,并实现

3.只有抽象类当中才能有抽象方法,普通类当中不能有抽象方法

4.抽象类当中不一定全是抽象方法,也可以使用普通方法,普通方法可以不用重写

5.抽象类不能被实例化,但是可以使用多态

6.final 不能和abstract同时使用,final修饰的方法禁止重写, abstract修饰的方法要求重写 ,冲突

7.private修饰的方法时子类不可见的, abstract修饰的方法要求重写,冲突

8.抽象方法不能使用static,static是针对类层次,抽象方法是针对对象层次的,所以不能一起使用.

9.抽象类可以有构造方法,目的是子类在初始化之前先初始化父类,既在new子类构造器(),之前先new父类构造器()

10.子类继承抽象类后,如果不想实现抽象类中的抽象方法,那么该此类必须是个抽象类

抽象类一定是个父类吗? 答:是的,因为需要子类覆盖其方法后才可以对子类实例化。


在这里插入图片描述

在没有指挥的前提下:

在这里插入图片描述

Builder

//建造者
public abstract class Builder {

    abstract  Builder buildA(String msg);//汉堡
    abstract  Builder buildB(String msg);//可乐
    abstract  Builder buildC(String msg);//薯条
    abstract  Builder buildD(String msg);//甜点

    //得到产品 Product 指定实体类
    abstract Product getProduct();


}

套餐 Product

//套餐
@Data
@NoArgsConstructor
@AllArgsConstructor
public class Product {


    private String BuildA="汉堡";
    private String BuildB="可乐";
    private String BuildC="薯条";
    private String BuildD="甜点";

    @Override
    public String toString() {
        return "Product{" +
                "BuildA='" + BuildA + '\'' +
                ", BuildB='" + BuildB + '\'' +
                ", BuildC='" + BuildC + '\'' +
                ", BuildD='" + BuildD + '\'' +
                '}';
    }
}

Work

public class Work extends Builder{

    public Product product;

    public Work() {
        product =new Product();
    }


    @Override
    Builder buildA(String msg) {
        product.setBuildA(msg);
        return this;
    }

    @Override
    Builder buildB(String msg) {
        product.setBuildB(msg);
        return this;
    }

    @Override
    Builder buildC(String msg) {
        product.setBuildC(msg);
        return this;
    }

    @Override
    Builder buildD(String msg) {
        product.setBuildD(msg);
        return this;
    }

    @Override
    Product getProduct() {
        return product;
    }
}

Test

public class Test {

    public static void main(String[] args) {
        //服务员
        Work work = new Work();
        //链式 编程 :在原来的基础上面可以自由组合不组合也有默认
        Product product = work.buildA("老严来了")
                .getProduct();

        //Product product = work.getProduct();


        System.out.println(product.toString());


    }
}

在这里插入图片描述

关系图:
在这里插入图片描述
在这里插入图片描述

在这里插入图片描述

在这里插入图片描述
在这里插入图片描述
设计模式总目录:https://blog.csdn.net/qq_42055933/article/details/126613801?spm=1001.2014.3001.5501(查看其他章节请点击)

  • 1
    点赞
  • 1
    收藏
    觉得还不错? 一键收藏
  • 打赏
    打赏
  • 1
    评论
评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

默 语

你的鼓励将是我创作的最大动力!

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

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

余额充值