Java设计模式百例 - 建造者模式

本文源码见:https://github.com/get-set/get-designpatterns/tree/master/builder

建造者模式(Builder Pattern)使用多个简单的对象一步一步构建成一个复杂的对象,这种类型的设计模式属于创建型模式。建造模式可以将一个复杂对象的内部组成部分,与该对象本身的创建分离开来,从而使得复杂对象的组装更灵活。

文绉绉的话不宜多说,其实这种模式还是挺常见的: 
* 比如我们在订手机套餐的时候,无论是自选还是电信公司配置好的,通常一个套餐包括:多少分钟市话、多少条短信、多少G的省内和省外流量等,这几样通常得有,但是具体选多少可以自由搭配。 
* 比如我们玩网游创建任务的时候,要选择职业、肤色、发型;还有游戏中给自己角色搭配装备的时候,要配置帽子、肩部、披风、上衣、裤子、鞋子等等,还有一系列配饰,十几个框框所有人都是一样的,不同的是放什么样的装备进去。

例子

就以刚才提到的网游人物的配置为例: 
我们在创建游戏任务的时候,必须填写任务名称、选择职业或种族,然后可以自行配置角色的发型、发色、武器、铠甲等等,当然后边这些有可能是根据职业或种族随机分配的。

首先是角色的发型、发色、武器、铠甲,以及职业:

HairType.java

public enum HairType {
    BALD("bald"), SHORT("short"), CURLY("curly"), LONG_STRAIGHT("long straight"), LONG_CURLY("long curly");
    private String title;
    HairType(String title) {
        this.title = title;
    }
    @Override
    public String toString() {
        return title;
    }
}

HairColor.java

public enum HairColor {
    WHITE, BLOND, RED, BROWN, BLACK;
    @Override
    public String toString() {
        return name().toLowerCase();
    }
}

Weapon.java

public enum Weapon {
    DAGGER, SWORD, AXE, WARHAMMER, BOW;
    @Override
    public String toString() {
        return name().toLowerCase();
    }
}

Armor.java

public enum Armor {
    CLOTHES("clothes"), LEATHER("leather"), CHAIN_MAIL("chain mail"), PLATE_MAIL("plate mail");
    private String title;
    Armor(String title) {
        this.title = title;
    }
    @Override
    public String toString() {
        return title;
    }
}

Profession.java

public enum Profession {
    WARRIOR, THIEF, MAGE, PRIEST;
    @Override
    public String toString() {
        return name().toLowerCase();
    }
}

在设计具体实现的时候,我们参考《Effective Java》第二条”遇到多个构造器参数时要考虑用构建器“中的内容组织类之间的关系。将Builder类内置于角色内部。

Hero.java

public final class Hero {

    private final Profession profession;
    private final String name;
    private final HairType hairType;
    private final HairColor hairColor;
    private final Armor armor;
    private final Weapon weapon;

    private Hero(Builder builder) {
        this.profession = builder.profession;
        this.name = builder.name;
        this.hairColor = builder.hairColor;
        this.hairType = builder.hairType;
        this.weapon = builder.weapon;
        this.armor = builder.armor;
    }

    // getters

    @Override
    public String toString() {
        ... ...
    }

    /**
     * The builder class.
     */
    public static class Builder {

        private final Profession profession;
        private final String name;
        private HairType hairType;
        private HairColor hairColor;
        private Armor armor;
        private Weapon weapon;

        /**
         * Constructor
         */
        public Builder(Profession profession, String name) {
            if (profession == null || name == null) {
                throw new IllegalArgumentException("profession and name can not be null");
            }
            this.profession = profession;
            this.name = name;
        }

        public Builder withHairType(HairType hairType) {
            this.hairType = hairType;
            return this;
        }

        public Builder withHairColor(HairColor hairColor) {
            this.hairColor = hairColor;
            return this;
        }

        public Builder withArmor(Armor armor) {
            this.armor = armor;
            return this;
        }

        public Builder withWeapon(Weapon weapon) {
            this.weapon = weapon;
            return this;
        }

        public Hero build() {
            return new Hero(this);
        }
    }
}

建造者模式的主要内容其实就在这个Hero.java类中了。

我们可以看到Hero类中有个子类Hero.Builder,具体Hero的创建由Builder来完成。可以看到Hero只有一个以Build为参数的构造函数,所以将只接受这种形式的创建。

是不是想到了单例模式中的那个使用静态内部类来保管单一实例的例子了呢。其实是有相通之处的,我们说过,静态内部类可以看作恰好定义在另一个类内部的普通类。与单例不同的是,这个静态内部类Builder由于需要在外部使用,是public的。之所以放在内部是因为内部类同外部类之间可以访问所有的成员,更加方便。

那么在使用的使用的时候,就可以通过Builder定义的一系列“组装方法”来创建实例了:

Hero warrior = new Hero.Builder(Profession.WARRIOR, "Amberjill").withHairColor(HairColor.BLOND)
        .withHairType(HairType.LONG_CURLY).withArmor(Armor.CHAIN_MAIL).withWeapon(Weapon.SWORD)
        .build();

这样一个“战士”就诞生了,突然有点想玩网游了呢~

总结

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

最后给一个小作业可以考虑一下用建造者模式实现: 
假设张三要盖房,交钥匙拎包入住那种。他找到服务商,说希望盖五间大瓦房、刮大白简装、配置便宜家居,谈好合同后,服务商找到施工队去盖房、装修和配便宜家具。另外又有个叫李四的人也找到这个服务商,说希望盖一个小洋楼、精装修、配实木家具,服务商又找到另一个擅长小洋楼的施工队去实施。

时间: 2024-11-05 20:29:32

Java设计模式百例 - 建造者模式的相关文章

Java设计模式14:建造者模式

什么是建造者模式 发现很多框架的源码使用了建造者模式,看了一下觉得挺实用的,就写篇文章学习一下,顺便分享给大家. 建造者模式是什么呢?用一句话概括就是建造者模式的目的是为了分离对象的属性与创建过程,是的,只要记住并理解红字的几个部分,建造者模式你就懂了. 为什么需要建造者模式 建造者模式是构造方法的一种替代方案,为什么需要建造者模式,我们可以想,假设有一个对象里面有20个属性: 属性1 属性2 ... 属性20 对开发者来说这不是疯了,也就是说我要去使用这个对象,我得去了解每个属性的含义,然后在

Java设计模式之(建造者模式)

建造者模式:是将一个复杂的对象的构建与它的表示分离,使得同样的构建过程可以创建不同的表示. 建造者模式通常包括下面几个角色: 1. builder:抽象建造者,给出一个抽象接口,以规范产品对象的各个组成成分的建造.这个接口规定要实现复杂对象的哪些部分的创建,并不涉及具体的对象部件的创建.2. ConcreteBuilder:建造者,实现Builder接口,针对不同的商业逻辑,具体化复杂对象的各部分的创建. 在建造过程完成后,提供产品的实例.3. Director:导演类,调用具体建造者来创建复杂

java设计模式4--建造者模式(Builder)

本文地址:http://www.cnblogs.com/archimedes/p/java-builder-pattern.html,转载请注明源地址. 建造者模式 将一个复杂对象的构建与它的表示分离,使得同样的构建过程可以创建不同的表示. 概述 当系统准备为用户提供一个内部结构复杂的对象时,就可以使用生成器模式,使用该模式可以逐步地构造对象,使得对象的创建更具弹性.生成器模式的关键是将一个包含有多个组件对象的创建分成若干个步骤,并将这些步骤封装在一个称作生成器的接口中. 适用性 1.当创建复杂

设计模式学习04—建造者模式

一.动机与定义 创建对象时,我们知道可以使用工厂方式来创建,使调用者和具体实现解耦,但是有一种情况,当要创建的多个对象之间重复性较大,只有创建步骤.组装顺序或者内部构件不同时,工厂模式就需要进一步的演化了,如我们去KFC,有很多种套餐,比如套餐1(薯条+可乐+汉堡),套餐2(鸡肉卷+薯条+可乐),这个套餐就是我们要获取的复杂对象,那么程序如何创建出这种对象呢. 我们看到套餐的内容很多是一样的,那么我们是不是可以考虑将创建单个食品(如鸡肉卷.可乐等)方法提取出来,使用单独一个类协调这些食品的组合比

一起学java设计模式--适配器模式(结构型模式)

适配器模式 现有一个接口DataOperation定义了排序方法sort(int[]) 和查找方法search(int[], int),已知类QuickSort的quickSort(int[])方法实现了快速排序算法,类BinarySearch 的binarySearch(int[], int)方法实现了二分查找算法.现使用适配器模式设计一个系统,在不修改源代码的情况下将类QuickSort和类BinarySearch的方法适配到DataOperation接口中.绘制类图并编程实现. (要求实现

Java设计模式之接口型模式总结

摘要: 原创作品,可以转载,但是请标注出处地址:http://www.cnblogs.com/V1haoge/p/6508967.html 之前认真学习了Java设计模式中的四大接口型模式,分别为:适配器模式(Adapter).外观模式(Facade).合成模式(Composite).桥接模式(Bridge). 1.在此处再温习一下四种设计模式: (1)适配器模式: 我们能够访问的类中不存在我们要访问的内容时,就可以使用这个适配器模式,当然就类而言,其实不存在什么不能被访问,这里的不能访问都是人

Java设计模式之工厂方法模式(转) 实现是抽象工厂?

Java设计模式之工厂方法模式 责任编辑:覃里作者:Java研究组织   2009-02-25   来源:IT168网站 文本Tag: 设计模式 Java [IT168 技术文章]          一 .工厂方法(Factory Method)模式 工厂方法模式的意义是定义一个创建产品对象的工厂接口,将实际创建工作推迟到子类当中.核心工厂类不再负责产品的创建,这样核心类成为一个抽象工厂角色,仅负责具体工厂子类必须实现的接口,这样进一步抽象化的好处是使得工厂方法模式可以使系统在不修改具体工厂角色

Java设计模式之结构型模式

结构型设计模式是从程序的结构上解决模块之间的耦合问题.包括以下七种模式: 适配器模式:可以将类的一个借口匹配另一个接口 组合模式:对象的组合 代理模式:一个简单的对象代替一个复杂的稍后会被调用的复杂对象 外观模式:一个类表示一个子系统 享元模式:用于共享对象,其中每个实例都不保存自己的状态.而是将状态保存在外部 桥接模式:将对象的接口与实现分离 装饰模式:动态给对象添加职责结构型设计模式是从程序的结构上解决模块之间的耦合问题 适配器模式: 原文链接:一个示例让你明白适配器模式 含义:将一个类的接

java设计模式之 装饰器模式

适AT java设计模式之 装饰器模式 装饰器模式 装饰器模式(Decorator Pattern)允许向一个现有的对象添加新的功能,同时又不改变其结构. 这种类型的设计模式属于结构型模式,它是作为现有的类的一个包装. 这种模式创建了一个装饰类,用来包装原有的类,并在保持类方法签名完整性的前提下,动态给一个对象添提供了额外的功能. 我们通过下面的实例来演示装饰器模式的用法.模拟一个人从想吃饭.找饭店.享受美食.结束吃饭的过程 代码展示: 首先创建一个被修饰的接口 Eat package deco