设计模式之分步构建模式

本文介绍了分步构建模式,一种为解决创建复杂对象时的困难而设计的模式。它通过分解对象构建过程,提供更简洁、灵活和可扩展的方法,通过一步步引导用户创建对象,降低错误风险。
摘要由CSDN通过智能技术生成

分步构建模式

动机

(分步构建模式)的动机主要是解决在创建复杂对象时面临的问题。在传统的构建方式中,可能需要一次性传递大量的参数给构造函数,或者设置大量的属性来构建一个对象。这种方式不仅代码冗长,而且容易出错,因为需要确保传递的参数或设置的属性都是正确的。
(分步构建模式)通过将对象的构建过程分解为一系列的步骤,每个步骤只关注对象的一部分属性或行为,从而简化了对象的创建过程。这种模式允许用户按照特定的顺序逐步构建对象,每个步骤都返回一个构建器对象,用户可以在这个对象上继续调用其他方法来设置更多的属性或行为。最后,当用户完成对象的构建后,可以调用构建器的build()方法来生成最终的对象。
(分步构建模式)的动机还包括提供一种更加灵活和可扩展的对象创建方式。通过定义一系列的构建步骤,可以根据不同的需求选择不同的步骤来构建对象,从而满足不同的业务需求。此外,由于每个步骤都是独立的,因此可以很容易地对某个步骤进行修改或扩展,而不会影响其他步骤的实现。

总之,(分步构建模式)的动机是为了解决在创建复杂对象时面临的问题,提供一种更加简洁、灵活和可扩展的对象创建方式

目的

这是构建者模式的一个扩展,完全指导用户创建对象,没有混淆的机会。
用户体验会大大提升,因为他只能看到下一个步骤的方法,直到适当的时机才会出现构建对象的“build”方法。

该模式的主要优势在于它为客户提供了一个关于如何使用API的指南,通过对象创建过程的逐步引导,使得API用户能够更加方便地创建对象,
并减少了创建不一致对象实例的机会。

定义

(分步构建模式)是一种创建型设计模式,它是链式建造者模式的进一步扩展,能够按步骤实例化对象

应用

使用分布构建模式当创建复杂对象的算法需要独立于组成对象的部分以及它们的组装方式,
且构造过程必须允许对象有不同的表示形式,并且在此过程中顺序很重要时。

本质

分步构建模式本质是提供一种更加灵活和可扩展的逐步(按照一定的字段的初始化顺序)对象创建方式

逐步构建的方式可以更加清晰地表达构建过程,减少错误和遗漏的可能性

代码示例

模拟创建人物角色信息
步骤1. 创建Character类

public class Character {

    private String name;
    private String fighterClass;
    private String wizardClass;
    private String weapon;
    private String spell;
    private List<String> abilities;

    public Character(String name) {
        this.name = name;
    }

    public String getName() {
        return name;
    }

    public void setName(String name) {
        this.name = name;
    }

    public String getFighterClass() {
        return fighterClass;
    }

    public void setFighterClass(String fighterClass) {
        this.fighterClass = fighterClass;
    }

    public String getWizardClass() {
        return wizardClass;
    }

    public void setWizardClass(String wizardClass) {
        this.wizardClass = wizardClass;
    }

    public String getWeapon() {
        return weapon;
    }

    public void setWeapon(String weapon) {
        this.weapon = weapon;
    }

    public String getSpell() {
        return spell;
    }

    public void setSpell(String spell) {
        this.spell = spell;
    }

    public List<String> getAbilities() {
        return abilities;
    }

    public void setAbilities(List<String> abilities) {
        this.abilities = abilities;
    }

    @Override
    public String toString() {
        return new StringBuilder()
                .append("This is a ")
                .append(fighterClass != null ? fighterClass : wizardClass)
                .append(" named ")
                .append(name)
                .append(" armed with a ")
                .append(weapon != null ? weapon : spell != null ? spell : "with nothing")
                .append(abilities != null ? " and wielding " + abilities + " abilities" : "")
                .append('.')
                .toString();
    }

}

步骤2.创建角色分步构建器CharacterStepBuilder类


public class CharacterStepBuilder {

    private CharacterStepBuilder() {
    }

    public static NameStep newBuilder() {
        return new CharacterSteps();
    }

    /**
     * 第一步NameStep. 下一步: ClassStep
     */
    public interface NameStep {
        ClassStep name(String name);
    }

    /***
       这一步负责设置角色类(战士或向导)。战斗机选择:
       下一步可用:武器步骤向导选择:下一步可用:SpellStep
    */
    public interface ClassStep {
        WeaponStep fighterClass(String fighterClass);

        SpellStep wizardClass(String wizardClass);
    }

    /**
      *这一步是负责武器的。武器选择:下一步可用:能力步骤编号
      *武器选择:下一步可用:BuildStep
     */
    public interface WeaponStep {
        AbilityStep withWeapon(String weapon);

        BuildStep noWeapon();
    }

    /**
     * 这个步骤负责咒语。法术选择:下一步可用:能力步骤无法术
       选项:Next Step可用:BuildStep
     */
    public interface SpellStep {
        AbilityStep withSpell(String spell);

        BuildStep noSpell();
    }

    /**
     * 这一步就是掌管能力。下一步可用:BuildStep
     */
    public interface AbilityStep {
        AbilityStep withAbility(String ability);

        BuildStep noMoreAbilities();

        BuildStep noAbilities();
    }

    /**
     * 这是负责构建角色对象的最后一步。验证应该在这里。
     */
    public interface BuildStep {
        Character build();
    }


    /**
     * stepbuilder实现。
     */
    private static class CharacterSteps implements NameStep, ClassStep, WeaponStep, SpellStep,
            AbilityStep, BuildStep {

        private String name;
        private String fighterClass;
        private String wizardClass;
        private String weapon;
        private String spell;
        private final List<String> abilities = new ArrayList<>();

        @Override
        public ClassStep name(String name) {
            this.name = name;
            return this;
        }

        @Override
        public WeaponStep fighterClass(String fighterClass) {
            this.fighterClass = fighterClass;
            return this;
        }

        @Override
        public SpellStep wizardClass(String wizardClass) {
            this.wizardClass = wizardClass;
            return this;
        }

        @Override
        public AbilityStep withWeapon(String weapon) {
            this.weapon = weapon;
            return this;
        }

        @Override
        public BuildStep noWeapon() {
            return this;
        }

        @Override
        public AbilityStep withSpell(String spell) {
            this.spell = spell;
            return this;
        }

        @Override
        public BuildStep noSpell() {
            return this;
        }

        @Override
        public AbilityStep withAbility(String ability) {
            this.abilities.add(ability);
            return this;
        }

        @Override
        public BuildStep noMoreAbilities() {
            return this;
        }

        @Override
        public BuildStep noAbilities() {
            return this;
        }

        @Override
        public Character build() {
            Character character = new Character(name);

            if (fighterClass != null) {
                character.setFighterClass(fighterClass);
            } else {
                character.setWizardClass(wizardClass);
            }

            if (weapon != null) {
                character.setWeapon(weapon);
            } else {
                character.setSpell(spell);
            }

            if (!abilities.isEmpty()) {
                character.setAbilities(abilities);
            }

            return character;
        }
    }

}

步骤3. 创建测试类App

public class App {

    public static void main(String[] args) {
        // 创建武士
        Character warrior = CharacterStepBuilder
                .newBuilder()
                .name("Amberjill")
                .fighterClass("Paladin")
                .withWeapon("Sword")
                .noAbilities()
                .build();

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

        // 创建魔术师
        Character mage = CharacterStepBuilder
                .newBuilder()
                .name("Riobard")
                .wizardClass("Sorcerer")
                .withSpell("Fireball")
                .withAbility("Fire Aura")
                .withAbility("Teleport")
                .noMoreAbilities()
                .build();

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

        // 创建小偷
        Character thief = CharacterStepBuilder
                .newBuilder()
                .name("Desmond")
                .fighterClass("Rogue")
                .noWeapon()
                .build();
        System.out.println(thief.toString());
        // 创建boss
        Character boss = CharacterStepBuilder.newBuilder().name("大Boss").fighterClass("abc").withWeapon("bow")
                .withAbility("大招1").withAbility("大招2").noMoreAbilities().build();
        System.out.println(boss.toString());


    }

}

运行记录:

This is a Paladin named Amberjill armed with a Sword.
This is a Sorcerer named Riobard armed with a Fireball and wielding [Fire Aura, Teleport] abilities.
This is a Rogue named Desmond armed with a with nothing.
This is a abc named 大Boss armed with a bow and wielding [大招1, 大招2] abilities.

真谛(找到变化,封装变化)

在分步构建模式中,我们可以将代码分为稳定部分和变化部分。
稳定部分是指那些在整个构建过程中保持不变的部分,
而变化部分则是指那些根据构建步骤的不同而有所变化的部分。

稳定部分

稳定部分通常是构建器(Builder)类中的核心逻辑和不变的方法。这些方法在整个构建过程中都是可用的,并且它们的行为不会因为构建步骤的不同而改变。
在CharacterBuilder类中,稳定部分可能包括:
setName(String name): 设置角色名称的方法,无论在哪个构建步骤中,它都会执行相同的操作。
setFighterClass(String fighterClass): 设置战士职业的方法,它的行为也是稳定的。
setWizardClass(String wizardClass): 设置法师职业的方法,同样保持不变。
setWeapon(String weapon): 设置武器的方法,其逻辑在构建过程中是稳定的。
setSpell(String spell): 设置法术的方法,它的行为不随构建步骤变化。
setAbilities(List abilities): 设置能力列表的方法,虽然这里可能包含一些额外的逻辑(如验证能力列表的有效性),但该方法本身仍然是稳定的。

变化部分

变化部分是指构建器类中的构建步骤和它们的顺序。这些步骤可能会根据具体的需求和上下文而有所不同。在CharacterBuilder类中,变化部分主要体现在构建步骤的调用顺序和传递的参数上。
构建步骤的顺序:不同的构建步骤可能以不同的顺序被调用,这取决于用户想要如何构建Character对象。例如,用户可能首先设置名称,然后设置职业,再设置武器和法术,最后设置能力列表。这个顺序是可以变化的。
传递的参数:每个构建步骤都接受不同的参数,这些参数的值可能会根据具体的需求而有所变化。例如,setName方法接受一个字符串作为参数,这个字符串的值在每次调用时都可能是不同的。

总结

通过分离稳定部分和变化部分,分步构建模式提供了一种灵活的方式来构建复杂对象。稳定部分保证了构建过程的稳定性和一致性,而变化部分则允许用户根据具体需求来定制构建过程。这种分离使得代码更加清晰、可维护和可扩展。

评论 2
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值