学习设计模式之建造者模式,但是宝可梦

这篇具有很好参考价值的文章主要介绍了学习设计模式之建造者模式,但是宝可梦。希望对大家有所帮助。如果存在错误或未考虑完全的地方,请大家不吝赐教,您也可以点击"举报违法"按钮提交疑问。

前言

作者在准备秋招中,学习设计模式,做点小笔记,用宝可梦为场景举例,有错误欢迎指出。

代码同步更新到 github ,要是点个Star您就是我的神

建造者模式

建造者模式是一种创建型模式,主要针对于某一个类有特别繁杂的属性,并且这些属性中有部分不是必须的。
避免在创建对象时,需要众多的构造函数,就有了建造者模式。

比如说,我现在有一个果篮,我可以放苹果、香蕉、梨等各种水果进去构造一个果篮,但是会出现什么状况呢?
我可能今天只有苹果,或者只有香蕉,也有可能我今天只有其中的两种。那么,有3个属性的情况下,会出现共6种情况。
这时候有2种解决办法:1.针对所有情况,写6个不同参数的构造函数;2.写一个全参构造方法,在没有某种水果时传入0或者null。

第一种方法,在属性变多的时候,构造函数直接变成海量;第二种方法,需要记住参数的顺序,容易出错。

(吐槽:要是可以像python一样,把参数名指定一下就好了:比如
plt.plot(data_x, data_y1, label="IUG-CF", marker='*')

那么针对这种“对象的属性过多,又有些属性不必须”的时候,建造者模式是一个好的选择。(就像最近投简历,简历由众多模块组成,可能就没有实习经历,或者项目经历)

1.情景模拟

小智和小霞在旅行,路过西柚市,这里在举办一个多属性大师的比赛,规则是每种属性的宝可梦只能带一只,组成一个队伍参加比赛。
我们把宝可梦组成的队伍抽象成一个类,每种属性的宝可梦作为类的属性。
于是有了Product

/**
 * Product
 * 一个多属性队伍由多个属性的宝可梦组成
 * 省略了Pokemon接口,直接用String
 */
public class MultiTypeTeam {
    private String fireType; // 火属性
    private String waterType; // 水属性
    private String flyingType; // 飞行系
    private String grassType; // 草属性
    private String electricType; // 电属性
    // ...
    // setter + toString 省略
}

小智和小霞找到了比赛的报名入口,这里是一个建造者的抽象建造类:

/**
 * 抽象建造者Builder
 * 为每个属性的构建提供方法
 */
public interface TeamBuilder {
    void chooseFireType();
    void chooseWaterType();
    void chooseFlyingType();
    void chooseGrassType();
    void chooseElectricType();
}

小智的队伍很快构建出来了:

public class SatoshiTeamBuilder implements TeamBuilder{
    private MultiTypeTeam multiTypeTeam;
    public SatoshiTeamBuilder() {
        this.multiTypeTeam = new MultiTypeTeam();
    }
    @Override
    public void chooseFireType() {
        multiTypeTeam.setFireType("喷火龙");
    }

    @Override
    public void chooseWaterType() {
        multiTypeTeam.setWaterType("杰尼龟");
    }

    @Override
    public void chooseFlyingType() {
        multiTypeTeam.setFlyingType("巴大蝴");
    }

    @Override
    public void chooseGrassType() {
        multiTypeTeam.setGrassType("妙蛙种子");
    }

    @Override
    public void chooseElectricType() {
        multiTypeTeam.setElectricType("皮卡丘");
    }

    @Override
    public MultiTypeTeam createTeam() {
        return this.multiTypeTeam;
    }
}

小霞直接无语了,谁懂啊家人们,我一个水属性大师,当然只有水属性

public class MistyTeamBuilder implements TeamBuilder{
    private MultiTypeTeam multiTypeTeam;
    public MistyTeamBuilder() {
        this.multiTypeTeam = new MultiTypeTeam();
    }
    @Override
    public void chooseFireType() {
        
    }

    @Override
    public void chooseWaterType() {
        multiTypeTeam.setWaterType("宝石海星");
    }
    // ......

    @Override
    public MultiTypeTeam createTeam() {
        return this.multiTypeTeam;
    }
}

再定义一个指挥者,实现使用者和对象创建过程的解耦:

/**
 * 指挥者
 * 指挥构造,实现解耦,让获取者无需关心对象怎么构建的
 */
public class Director {
    public MultiTypeTeam buildTeam(TeamBuilder teamBuilder){
        teamBuilder.chooseElectricType();
        teamBuilder.chooseFireType();
        teamBuilder.chooseFlyingType();
        teamBuilder.chooseWaterType();
        teamBuilder.chooseGrassType();
        return teamBuilder.createTeam();
    }
}

测试类:

public class BuilderDemo {
    public static void main(String[] args) {
        Director director = new Director();
        MultiTypeTeam satoshiTeam = director.buildTeam(new SatoshiTeamBuilder());
        MultiTypeTeam mistyTeam = director.buildTeam(new MistyTeamBuilder());

        System.out.println(satoshiTeam.toString());
        System.out.println(mistyTeam.toString());
    }
}
MultiTypeTeam{fireType='喷火龙', waterType='杰尼龟', flyingType='巴大蝴', grassType='妙蛙种子', electricType='皮卡丘'}
MultiTypeTeam{fireType='null', waterType='宝石海星', flyingType='null', grassType='null', electricType='null'}

稍微总结一下,建造者模式的四个角色:

  • 产品 (Product): 要建造的类
  • 抽象建造者 (Builder): 提供建造需要的方法
  • 具体建造者 (Concrete Builder): 实现建造
  • 指挥者 (Director): 调度建造方法,实现解耦,每次使用对象时只需通过Director,不需要知道怎么构建的

上面的实现方法,其实可以让使用者自己来进行按需构建,从而省略指挥者的角色。
并且,修改其中某个参数的时候,需要写一个全新的实现类,这很麻烦。
于是,通过查阅资料,有一种对传统建造者方法的改进,也称为简化版。

2. 改进实现

顺便在这里做一个改进,我们将水属性宝可梦设置为必须的,以区分必须的属性和非必须的属性,然后将建造的方法的返回类型改为建造者

/**
 * 返回一个产品对象
 */
public interface TeamBuilderSimple {
    TeamBuilderSimple chooseFireType(String pokemon);
    TeamBuilderSimple chooseGrassType(String pokemon);
    TeamBuilderSimple chooseFlyingType(String pokemon);
    TeamBuilderSimple chooseElectricType(String pokemon);
    MultiTypeTeam getTeam();
}

那么具体的构造类只需要实现方法:

/**
 * 自行传入
 */
public class ConcreteTeamBuilderSimple implements TeamBuilderSimple{
    MultiTypeTeam multiTypeTeam;

    ConcreteTeamBuilderSimple(String waterPokemon){
        multiTypeTeam = new MultiTypeTeam();
        multiTypeTeam.setWaterType(waterPokemon);
    }

    @Override
    public TeamBuilderSimple chooseFireType(String pokemon) {
        multiTypeTeam.setFireType(pokemon);
        return this;
    }

    @Override
    public TeamBuilderSimple chooseGrassType(String pokemon) {
        multiTypeTeam.setGrassType(pokemon);
        return this;
    }

    @Override
    public TeamBuilderSimple chooseFlyingType(String pokemon) {
        multiTypeTeam.setFlyingType(pokemon);
        return this;
    }

    @Override
    public TeamBuilderSimple chooseElectricType(String pokemon) {
        multiTypeTeam.setElectricType(pokemon);
        return this;
    }

    @Override
    public MultiTypeTeam getTeam() {
        return multiTypeTeam;
    }
}

于是要使用的时候,就更加方便,通过一种链式调用自行构建对象,且不需要写繁杂的构造函数

public class BuilderDemo02 {
    public static void main(String[] args) {
        MultiTypeTeam satoshiTeam = new ConcreteTeamBuilderSimple("小锯鳄")
                .chooseElectricType("皮卡丘")
                .chooseFireType("暖暖猪")
                .chooseFlyingType("急冻鸟")
                .chooseGrassType("菊草叶")
                .getTeam();

        MultiTypeTeam mistyTeam = new ConcreteTeamBuilderSimple("暴鲤龙")
                .getTeam();

        System.out.println(satoshiTeam.toString());
        System.out.println(mistyTeam.toString());
    }
}
MultiTypeTeam{fireType='暖暖猪', waterType='小锯鳄', flyingType='急冻鸟', grassType='菊草叶', electricType='皮卡丘'}
MultiTypeTeam{fireType='null', waterType='暴鲤龙', flyingType='null', grassType='null', electricType='null'}

3.应用

3.1 Swagger

写过web应用的读者们应该接触过Swagger, 通过SpringBoot整合Swagger的时候,会编写一个配置类,我们来看看他的代码:

@Configuration
public class SwaggerConfig {
    @Bean
    public OpenAPI springShopOpenAPI() {
        return new OpenAPI()
                .info(new Info().title("GoCooking")
                        .description("GoCooking API文档")
                        .version("v1")
                        .license(new License().name("Apache 2.0").url("http://springdoc.org")))
                        .externalDocs(new ExternalDocumentation()
                        .description("外部文档")
                        .url("https://springshop.wiki.github.org/docs"));
    }
}

OpenAPI类中有个info属性, 通过info()方法来设置info

public OpenAPI info(Info info) {
        this.info = info;
        return this;
    }

Info类的构建过程,就是本文改进版的写法,比如下面两个方法

    public Info description(String description) {
        this.description = description;
        return this;
    }

    public Info title(String title) {
        this.title = title;
        return this;
        }

3.2 StringBuilder

StringBuilder使用append()方法后,返回的还是同一个对象,这也是建造者模式的应用文章来源地址https://www.toymoban.com/news/detail-680955.html

public StringBuilder append(String str) {
        super.append(str);
        return this;
    }

到了这里,关于学习设计模式之建造者模式,但是宝可梦的文章就介绍完了。如果您还想了解更多内容,请在右上角搜索TOY模板网以前的文章或继续浏览下面的相关文章,希望大家以后多多支持TOY模板网!

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处: 如若内容造成侵权/违法违规/事实不符,请点击违法举报进行投诉反馈,一经查实,立即删除!

领支付宝红包 赞助服务器费用

相关文章

  • 学习设计模式之享元模式,但是宝可梦

    作者在准备秋招中,学习设计模式,做点小笔记,用宝可梦为场景举例,有错误欢迎指出。 代码同步更新到 github ,要是点个Star您就是我的神 享元模式很好理解,它主要是为了减少创建对象的数量,属于结构型设计模式 目的:减少创建对象的次数 方法:复用对象 何时使用:

    2024年02月11日
    浏览(36)
  • 【设计模式——学习笔记】23种设计模式——建造者模式Builder(原理讲解+应用场景介绍+案例介绍+Java代码实现)

    建造者模式又叫生成器模式,是一种对象构建模式。它可以将复杂对象的建造过程抽象出来(抽象类别),使这个抽象过程的不同实现方法可以构造出不同属性的对象 建造者模式是一步一步创建一个复杂的对象,它允许用户只通过指定复杂对象的类型和内容就可以构建它们,不

    2024年02月15日
    浏览(41)
  • 设计模式-建造者模式

    在前面几篇文章中,已经讲解了单例模式、工厂方法模式、抽象工厂模式,创建型还剩下一个比较重要的模式-建造者模式。在理解该模式之前,我还是希望重申设计模式的初衷,即 为解决一些问题而提供的优良方案 。学习设计模式遗忘其初衷,注定无法理解其真正的深刻内

    2024年02月15日
    浏览(44)
  • 设计模式——建造者模式

    建造者模式(Builder Pattern)是一种创建型设计模式,它允许通过分步骤来构建复杂对象。该模式的核心原理是将一个复杂对象的构建与它的表示分离,使得同样的构建过程可以创建不同的表现形式。 在建造者模式中,通常有以下角色: 抽象建造者(Builder): 定义了创建产品

    2024年01月16日
    浏览(46)
  • 【设计模式】建造者模式

    建造者模式(Builder Pattern)使用多个简单的对象一步一步构建成一个复杂的对象。这种类型的设计模式属于创建型模式,它提供了一种创建对象的最佳方式。 一个 Builder 类会一步一步构造最终的对象。该 Builder 类是独立于其他对象的。 意图: 将一个复杂的构建与其表示相分

    2024年02月13日
    浏览(45)
  • 设计模式: 建造者模式

    建造模式通过一步一步的去构建一个复杂的对象。该模式将对象的构建细节封装在一个独立的建造者类中,使得客户端代码可以根据需要定制对象的构建过程,而不必知道具体的构建细节。 建造者模式通常包括以下几个角色: 产品类(Product):需要对象,通常是包含多个属

    2024年02月21日
    浏览(39)
  • 设计模式(三)建造者模式

    相关文章 设计模式系列 1.建造者模式简介 定义 建造者模式(builder),将一个复杂对象的构建与它的表示分离,使得同样的构建过程可以创建不同的表示。 简介 建造者模式(builder)是创建一个复杂对象的创建型模式,将构建复杂对象的过程和它的部件解耦,使得构建过程和

    2024年03月17日
    浏览(50)
  • 设计模式之建造者模式

    建造者模式(Builder Pattern) 是一种创建型设计模式,它将一个复杂对象的构建与它的表示分离,使得同样的构建过程可以创建不同的表示。这种模式适用于需要分步骤创建复杂对象、构造过程可能需要改变、或者需要隐藏复杂对象的具体构建过程的场景。 Product(产品) :表

    2024年04月24日
    浏览(32)
  • 设计模式(9)建造者模式

    一、介绍 1、概念:将一个复杂对象的构造与它的表示分离,使得同样的构造过程可以创建不同的表示。建造者模式主要用于创建一些复杂的对象,这些对象内部构建间的顺序通常是稳定的,但对象内部的构建通常面临着复杂的变化;建造者模式的好处就是使得建造代码与表

    2024年02月11日
    浏览(38)
  • Java设计模式-建造者模式

    建造者模式是一种创建型设计模式,用于将复杂对象的构建过程与其表示分离,使得同样的构建过程可以创建不同的表示。建造者模式通过将复杂对象的构建过程分解为多个简单的步骤来实现。 与其他创建型模式不同,建造者模式强调的是将构建过程与表示分离,而不是将对

    2024年02月02日
    浏览(40)

觉得文章有用就打赏一下文章作者

支付宝扫一扫打赏

博客赞助

微信扫一扫打赏

请作者喝杯咖啡吧~博客赞助

支付宝扫一扫领取红包,优惠每天领

二维码1

领取红包

二维码2

领红包