java设计模式——建造者模式

1.定义

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

2.介绍

意图:将一个复杂的构建与其表示相分离,使得同样的构建过程创建不同的表示。
主要解决:主要解决在软件系统中,有时面临着“一个复杂对象”的创建工作,其通常由各个部分的子对象用一定的算法构成。
何时使用:一些基本部件不会变,而其组合经常变化的时候。
如何解决:将变与不变分离开。
关键代码:建造者:创建和提供实例,导演:管理建造出来的实例的依赖关系。
注意事项:与工厂模式的区别是:建造者模式更加关注与零件转配的顺序。

3.优缺点

建造者独立,易扩展,便于控制细节风险。
缺点:产品必须有共同点,范围有限制,如内部变化负责,会有很多的建造类。

4.使用场景

1.需要生成的对象具有复杂的内部结构。2.需要生成的对象的内部属性本身相互依赖。

5.建造实现的两种方式

(1)通过Client、Director、Builder和Product形式的建造者模式(比较常见)

抽象建造者(builder):描述具体建造者的公共接口,一般用来定义建造细节的方法,并不涉及具体的对象部件的创建。
具体构建者(ConcreteBuilder):描述具体构建者,并实现抽象建造者公共接口。
指挥者(Director):调用具体建造者来创建复杂对象(产品)的各个部分,并按照一定顺序来建造复杂对象。
产品(Product):描述一个由一系列部件组成较为复杂的对象。

6.方式一的实现例子:

既然是建造者模式,那么我们还是继续造房吧,其实我也想不到更简单的例子。假设造房简化为如下步骤:(1)地基(2)钢筋工程(3)铺电线(4)粉刷
“如果”要盖一座房子,首先要找一个建筑公司或工程承包商(指挥者)。承包商指挥工人(具体建造者)过来造房子(产品),最后验收。
具体步骤:

1.创建抽象建造者定义造房步骤。
2.创建工人具体实现造房步骤。
3.创建承包商指挥工人施工。
4.验收、检查是否建造完成。

代码:

public class BuilderPattern {
    public static void main(String[] args) {
        
        Director dirctor=new Director();
        Product  product=dirctor.creat(new ConcreteBuilder());
        System.out.println(product.toString());
        
    }

}
/**
 * @author xin
 *建造者
 */
abstract class Builder{ 
    //地基
    abstract void buildFoundation();
    //钢筋工程
    abstract void buildSteelBar();
    //电线
    abstract void buildWire();
    //粉刷
    abstract void buildPainting();
    //产品
    abstract Product build();
}

/**
 * @author xin
 *产品
 */
class Product{
    private String buildFoundation;
    private String buildSteelBar;
    private String buildWire;
    private String buildPainting;
    @Override
    public String toString() {
        
        return buildFoundation+","+buildSteelBar+","+buildWire+","+buildPainting+"房子已完成";
    }
    public String getBuildFoundation() {
        return buildFoundation;
    }
    public String getBuildSteelBar() {
        return buildSteelBar;
    }
    public String getBuildWire() {
        return buildWire;
    }
    public String getBuildPainting() {
        return buildPainting;
    }
    public void setBuildFoundation(String buildFoundation) {
        this.buildFoundation = buildFoundation;
    }
    public void setBuildSteelBar(String buildSteelBar) {
        this.buildSteelBar = buildSteelBar;
    }
    public void setBuildWire(String buildWire) {
        this.buildWire = buildWire;
    }
    public void setBuildPainting(String buildPainting) {
        this.buildPainting = buildPainting;
    }
    
}
/**
 * @author xin
 *具体的建造者,实现抽象类
 */
class ConcreteBuilder extends Builder{
    private Product product;
    public ConcreteBuilder(){
        product=new Product();
    }
    @Override
    void buildFoundation() {
        product.setBuildFoundation("地基");
    }

    @Override
    void buildSteelBar() {
        product.setBuildSteelBar("钢筋");
    }

    @Override
    void buildWire() {
        product.setBuildWire("电线");
    }

    @Override
    void buildPainting() {
        product.setBuildPainting("刷墙");
    }

    @Override
    Product build() {
        //返回产品
        return product;
    }
    
}

/**
 * @author xin
 *指挥者
 */
class Director{
    //按顺序建房
    public Product creat(Builder builder) {
        builder.buildFoundation();
        builder.buildSteelBar();
        builder.buildWire();
        builder.buildPainting();
        return builder.build();
        
    }
    
}
7.方式二实现例子

通过内部类方式实现零件无序装配构造。这种方式使用更加灵活,更符合定义。内部有复杂对象的默认实现,使用时可以根据用户需求自由定义更改内容,并且无需改变具体的构造方式,这样就可以生产出不同复杂产品。
主要有是哪个角色:抽象建造者,具体建造者,产品。

例子:如麦当劳的套餐,服务员(具体建造者)可以随意搭配任意几种产品组成一款套餐产品,然后出售给客户。

步骤:
1.创建建造者定义麦当劳的产品
2.创建服务员实现具体产品
3.服务员随意搭配套餐出售给客户。

代码:

public class BuilderPatternStaticClass {

    public static void main(String[] args) {
        Product product=new ConcreteBuilder().bulidA("汉堡")
                .bulidB("可乐").bulidC("冰淇淋").bulidD("鸡翅").build();
        System.out.println("第一位顾客的套餐"+product.toString());
        Product product1=new ConcreteBuilder().bulidA("米饭")
                .bulidB("雪碧").build();
        System.out.println("第二位顾客的套餐"+product1.toString());
    }

}
/*Builder.java
*建造者
*/
abstract class Builder{
    //主食
    abstract Builder bulidA(String mes);
    //饮料
    abstract Builder bulidB(String mes);
    //甜品
    abstract Builder bulidC(String mes);
    //小吃
    abstract Builder bulidD(String mes);
    //获取套餐
    abstract Product build();
}
class Product{
    private String buildA;
    private String buildB;
    private String buildC;
    private String buildD;
    public String getBuildA() {
        return buildA;
    }
    public String getBuildB() {
        return buildB;
    }
    public String getBuildC() {
        return buildC;
    }
    public String getBuildD() {
        return buildD;
    }
    public void setBuildA(String buildA) {
        this.buildA = buildA;
    }
    public void setBuildB(String buildB) {
        this.buildB = buildB;
    }
    public void setBuildC(String buildC) {
        this.buildC = buildC;
    }
    public void setBuildD(String buildD) {
        this.buildD = buildD;
    }
    @Override
    public String toString() {
        
        return "套餐:"+buildA+","+buildB+","+buildC+","+buildD;
    }
    
}
class ConcreteBuilder extends Builder{
    private Product product;
    
    public ConcreteBuilder() {
        super();
        product =new Product();
        
    }

    @Override
    Builder bulidA(String mes) {
        product.setBuildA(mes);
        return this;
    }

    @Override
    Builder bulidB(String mes) {
        product.setBuildB(mes);
        return this;
    }

    @Override
    Builder bulidC(String mes) {
        product.setBuildC(mes);
        return this;
    }

    @Override
    Builder bulidD(String mes) {
        product.setBuildD(mes);
        return this;
    }

    @Override
    Product build() {
        
        return product;
    }
    
}
image.png

本人的技术比较菜,上面的内容基本上是来源别人的博客,如果有不好的地方请参考下方的链接。


image.png

参考的链接:https://www.jianshu.com/p/47329a94f5dc
https://www.runoob.com/design-pattern/builder-pattern.html

最后编辑于
©著作权归作者所有,转载或内容合作请联系作者
  • 序言:七十年代末,一起剥皮案震惊了整个滨河市,随后出现的几起案子,更是在滨河造成了极大的恐慌,老刑警刘岩,带你破解...
    沈念sama阅读 216,496评论 6 501
  • 序言:滨河连续发生了三起死亡事件,死亡现场离奇诡异,居然都是意外死亡,警方通过查阅死者的电脑和手机,发现死者居然都...
    沈念sama阅读 92,407评论 3 392
  • 文/潘晓璐 我一进店门,熙熙楼的掌柜王于贵愁眉苦脸地迎上来,“玉大人,你说我怎么就摊上这事。” “怎么了?”我有些...
    开封第一讲书人阅读 162,632评论 0 353
  • 文/不坏的土叔 我叫张陵,是天一观的道长。 经常有香客问我,道长,这世上最难降的妖魔是什么? 我笑而不...
    开封第一讲书人阅读 58,180评论 1 292
  • 正文 为了忘掉前任,我火速办了婚礼,结果婚礼上,老公的妹妹穿的比我还像新娘。我一直安慰自己,他们只是感情好,可当我...
    茶点故事阅读 67,198评论 6 388
  • 文/花漫 我一把揭开白布。 她就那样静静地躺着,像睡着了一般。 火红的嫁衣衬着肌肤如雪。 梳的纹丝不乱的头发上,一...
    开封第一讲书人阅读 51,165评论 1 299
  • 那天,我揣着相机与录音,去河边找鬼。 笑死,一个胖子当着我的面吹牛,可吹牛的内容都是我干的。 我是一名探鬼主播,决...
    沈念sama阅读 40,052评论 3 418
  • 文/苍兰香墨 我猛地睁开眼,长吁一口气:“原来是场噩梦啊……” “哼!你这毒妇竟也来了?” 一声冷哼从身侧响起,我...
    开封第一讲书人阅读 38,910评论 0 274
  • 序言:老挝万荣一对情侣失踪,失踪者是张志新(化名)和其女友刘颖,没想到半个月后,有当地人在树林里发现了一具尸体,经...
    沈念sama阅读 45,324评论 1 310
  • 正文 独居荒郊野岭守林人离奇死亡,尸身上长有42处带血的脓包…… 初始之章·张勋 以下内容为张勋视角 年9月15日...
    茶点故事阅读 37,542评论 2 332
  • 正文 我和宋清朗相恋三年,在试婚纱的时候发现自己被绿了。 大学时的朋友给我发了我未婚夫和他白月光在一起吃饭的照片。...
    茶点故事阅读 39,711评论 1 348
  • 序言:一个原本活蹦乱跳的男人离奇死亡,死状恐怖,灵堂内的尸体忽然破棺而出,到底是诈尸还是另有隐情,我是刑警宁泽,带...
    沈念sama阅读 35,424评论 5 343
  • 正文 年R本政府宣布,位于F岛的核电站,受9级特大地震影响,放射性物质发生泄漏。R本人自食恶果不足惜,却给世界环境...
    茶点故事阅读 41,017评论 3 326
  • 文/蒙蒙 一、第九天 我趴在偏房一处隐蔽的房顶上张望。 院中可真热闹,春花似锦、人声如沸。这庄子的主人今日做“春日...
    开封第一讲书人阅读 31,668评论 0 22
  • 文/苍兰香墨 我抬头看了看天上的太阳。三九已至,却和暖如春,着一层夹袄步出监牢的瞬间,已是汗流浃背。 一阵脚步声响...
    开封第一讲书人阅读 32,823评论 1 269
  • 我被黑心中介骗来泰国打工, 没想到刚下飞机就差点儿被人妖公主榨干…… 1. 我叫王不留,地道东北人。 一个月前我还...
    沈念sama阅读 47,722评论 2 368
  • 正文 我出身青楼,却偏偏与公主长得像,于是被迫代替她去往敌国和亲。 传闻我的和亲对象是个残疾皇子,可洞房花烛夜当晚...
    茶点故事阅读 44,611评论 2 353

推荐阅读更多精彩内容