详解Java实践之建造者模式

目录
  • 一、前言
  • 二、开发环境
  • 三、建造者模式介绍
  • 四、案例场景模拟
    • 4.1、场景模拟工程
    • 4.2、场景简述
      • 4.2.1、物料接口
      • 4.2.2、吊顶(ceiling)
      • 4.2.3、涂料(coat)
      • 4.2.4、地板(floor)
      • 4.2.5、地砖(tile)
  • 五、代码实现
    • 5.1、工程结构
    • 5.2、ifelse实现需求
    • 5.3、 测试验证
  • 六、建造者模式重构代码
    • 6.1、工程结构
    • 6.2、代码实现
      • 6.2.1、定义装修包接口
      • 6.2.2、装修包实现
      • 6.2.3、建造者方法
    • 6.3、测试验证
  • 七、总结

一、前言

无论承接什么样的需求,是不是身边总有那么几个人代码写的烂,但是却时常有测试小姐姐过来聊天(求改bug)、有产品小伙伴送吃的(求写需求)、有业务小妹妹陪着改代码(求上线),直至领导都认为他的工作很重要,而在旁边的你只能蹭点吃的。

这样的小伙伴,可能把代码写的很直接,ifelse多用一点,满足于先临时支持一下,想着这也没什么的。而且这样的业务需求要的急又都是增删改查的内容,实在不想做设计。而如果有人提到说好好设计下,可能也会被反对不要过渡设计。

第一次完成产品需求实在是很快,但互联网的代码不比传统企业。在传统行业可能一套代码能用十年,但在互联网高速的迭代下你的工程,一年就要变动几十次。如果从一开始就想着只要完成功能就可以,那么随之而来的是后续的需求难以承接,每次看着成片成片的代码,实在不知如何下手。

在研发流程规范下执行,才能写出好程序!

一个项目的上线往往要经历业务需求产品设计研发实现测试验证上线部署正式开量,而这其中对研发非常重要的一换就是研发实现的过程,又可以包括为;架构选型功能设计设计评审代码实现代码评审单测覆盖率检查编写文档提交测试。所以在一些流程规范下,其实很难让你随意开发代码。

开发代码的过程不是炫技,就像盖房子如果不按照图纸来修建,回首就在山墙上搭一个厨房卫浴!可能在现实场景中这很荒唐,但在功能开发中却总有这样的代码。

所以我们也需要一些设计模式的标准思想,去建设代码结构,提升全局把控能力。

二、开发环境

1.JDK 1.8

2.Idea + Maven

工程 描述
itstack-demo-design-3-00 场景模拟工程,模拟装修过程中的套餐选择(豪华、田园、简约)
itstack-demo-design-3-01 使用一坨代码实现业务需求,也是对ifelse的使用
itstack-demo-design-3-02 通过设计模式优化改造代码,产生对比性从而学习

三、建造者模式介绍

建造者模式所完成的内容就是通过将多个简单对象通过一步步的组装构建出一个复杂对象的过程。

那么,哪里有这样的场景呢?

例如你玩王者荣耀的时的初始化界面;有三条路、有树木、有野怪、有守卫塔等等,甚至依赖于你的网络情况会控制清晰度。而当你换一个场景进行其他不同模式的选择时,同样会建设道路、树木、野怪等等,但是他们的摆放和大小都有不同。这里就可以用到建造者模式来初始化游戏元素。

而这样的根据相同的物料,不同的组装所产生出的具体的内容,就是建造者模式的最终意图,也就是;将一个复杂的构建与其表示相分离,使得同样的构建过程可以创建不同的表示。

四、案例场景模拟

这里我们模拟装修公司对于设计出一些套餐装修服务的场景。

很多装修公司都会给出自家的套餐服务,一般有;欧式豪华、轻奢田园、现代简约等等,而这些套餐的后面是不同的商品的组合。例如;一级&二级吊顶、多乐士涂料、圣象地板、马可波罗地砖等等,按照不同的套餐的价格选取不同的品牌组合,最终再按照装修面积给出一个整体的报价。

这里我们就模拟装修公司想推出一些套餐装修服务,按照不同的价格设定品牌选择组合,以达到使用建造者模式的过程。

4.1、场景模拟工程

itstack-demo-design-3-00

└── src

    └── main

        └── java

            └── org.itstack.demo.design

                ├── ceilling

                │   ├── LevelOneCeiling.java

                │   └── LevelTwoCeiling.java

                ├── coat

                │   ├── DuluxCoat.java

                │   └── LiBangCoat.java

                │   └── LevelTwoCeiling.java

                ├── floor

                │   ├── DerFloor.java

                │   └── ShengXiangFloor.java

                ├── tile

                │   ├── DongPengTile.java

                │   └── MarcoPoloTile.java

                └── Matter.java

在模拟工程中提供了装修中所需要的物料;ceilling(吊顶)coat(涂料)floor(地板)tile(地砖),这么四项内容。(实际的装修物料要比这个多的多

4.2、场景简述

4.2.1、物料接口

public interface Matter {

    String scene();      // 场景;地板、地砖、涂料、吊顶

    String brand();      // 品牌

    String model();      // 型号

    BigDecimal price();  // 价格

    String desc();       // 描述

}

物料接口提供了基本的信息,以保证所有的装修材料都可以按照统一标准进行获取。

4.2.2、吊顶(ceiling)

一级顶

public class LevelOneCeiling implements Matter {

    public String scene() {
        return "吊顶";
    }

    public String brand() {
        return "装修公司自带";
    }

    public String model() {
        return "一级顶";
    }

    public BigDecimal price() {
        return new BigDecimal(260);
    }

    public String desc() {
        return "造型只做低一级,只有一个层次的吊顶,一般离顶120-150mm";
    }

}

二级顶

public class LevelTwoCeiling  implements Matter {

    public String scene() {
        return "吊顶";
    }

    public String brand() {
        return "装修公司自带";
    }

    public String model() {
        return "二级顶";
    }

    public BigDecimal price() {
        return new BigDecimal(850);
    }

    public String desc() {
        return "两个层次的吊顶,二级吊顶高度一般就往下吊20cm,要是层高很高,也可增加每级的厚度";
    }

}

4.2.3、涂料(coat)

多乐士

public class DuluxCoat  implements Matter {

    public String scene() {
        return "涂料";
    }

    public String brand() {
        return "多乐士(Dulux)";
    }

    public String model() {
        return "第二代";
    }

    public BigDecimal price() {
        return new BigDecimal(719);
    }

    public String desc() {
        return "多乐士是阿克苏诺贝尔旗下的著名建筑装饰油漆品牌,产品畅销于全球100个国家,每年全球有5000万户家庭使用多乐士油漆。";
    }

}

立邦

public class LiBangCoat implements Matter {

    public String scene() {
        return "涂料";
    }

    public String brand() {
        return "立邦";
    }

    public String model() {
        return "默认级别";
    }

    public BigDecimal price() {
        return new BigDecimal(650);
    }

    public String desc() {
        return "立邦始终以开发绿色产品、注重高科技、高品质为目标,以技术力量不断推进科研和开发,满足消费者需求。";
    }

}

4.2.4、地板(floor)

德尔

public class DerFloor implements Matter {

    public String scene() {
        return "地板";
    }

    public String brand() {
        return "德尔(Der)";
    }

    public String model() {
        return "A+";
    }

    public BigDecimal price() {
        return new BigDecimal(119);
    }

    public String desc() {
        return "DER德尔集团是全球领先的专业木地板制造商,北京2008年奥运会家装和公装地板供应商";
    }

}

圣象

public class ShengXiangFloor implements Matter {

    public String scene() {
        return "地板";
    }

    public String brand() {
        return "圣象";
    }

    public String model() {
        return "一级";
    }

    public BigDecimal price() {
        return new BigDecimal(318);
    }

    public String desc() {
        return "圣象地板是中国地板行业著名品牌。圣象地板拥有中国驰名商标、中国名牌、国家免检、中国环境标志认证等多项荣誉。";
    }

}

4.2.5、地砖(tile)

东鹏

public class DongPengTile implements Matter {

    public String scene() {
        return "地砖";
    }

    public String brand() {
        return "东鹏瓷砖";
    }

    public String model() {
        return "10001";
    }

    public BigDecimal price() {
        return new BigDecimal(102);
    }

    public String desc() {
        return "东鹏瓷砖以品质铸就品牌,科技推动品牌,口碑传播品牌为宗旨,2014年品牌价值132.35亿元,位列建陶行业榜首。";
    }

}

马可波罗

public class MarcoPoloTile implements Matter {

    public String scene() {
        return "地砖";
    }

    public String brand() {
        return "马可波罗(MARCO POLO)";
    }

    public String model() {
        return "缺省";
    }

    public BigDecimal price() {
        return new BigDecimal(140);
    }

    public String desc() {
        return "“马可波罗”品牌诞生于1996年,作为国内最早品牌化的建陶品牌,以“文化陶瓷”占领市场,享有“仿古砖至尊”的美誉。";
    }

}

以上就是本次装修公司所提供的装修配置单,接下我们会通过案例去使用不同的物料组合出不同的套餐服务。

五、代码实现

讲道理没有ifelse解决不了的逻辑,不行就在加一行!

每一个章节中我们都会使用这样很直白的方式去把功能实现出来,在通过设计模式去优化完善。这样的代码结构也都是非常简单的,没有复杂的类关系结构,都是直来直去的代码。除了我们经常强调的这样的代码不能很好的扩展外,做一些例子demo工程还是可以的。

5.1、工程结构

itstack-demo-design-3-01

└── src

    └── main

        └── java

            └── org.itstack.demo.design

                └── DecorationPackageController.java

一个类几千行的代码你是否见过,嚯?那今天就让你见识一下有这样潜质的类!

5.2、ifelse实现需求

public class DecorationPackageController {

    public String getMatterList(BigDecimal area, Integer level) {

        List<Matter> list = new ArrayList<Matter>(); // 装修清单
        BigDecimal price = BigDecimal.ZERO;          // 装修价格

        // 豪华欧式
        if (1 == level) {

            LevelTwoCeiling levelTwoCeiling = new LevelTwoCeiling(); // 吊顶,二级顶
            DuluxCoat duluxCoat = new DuluxCoat();                   // 涂料,多乐士
            ShengXiangFloor shengXiangFloor = new ShengXiangFloor(); // 地板,圣象

            list.add(levelTwoCeiling);
            list.add(duluxCoat);
            list.add(shengXiangFloor);

            price = price.add(area.multiply(new BigDecimal("0.2")).multiply(levelTwoCeiling.price()));
            price = price.add(area.multiply(new BigDecimal("1.4")).multiply(duluxCoat.price()));
            price = price.add(area.multiply(shengXiangFloor.price()));

        }

        // 轻奢田园
        if (2 == level) {

            LevelTwoCeiling levelTwoCeiling = new LevelTwoCeiling(); // 吊顶,二级顶
            LiBangCoat liBangCoat = new LiBangCoat();                // 涂料,立邦
            MarcoPoloTile marcoPoloTile = new MarcoPoloTile();       // 地砖,马可波罗

            list.add(levelTwoCeiling);
            list.add(liBangCoat);
            list.add(marcoPoloTile);

            price = price.add(area.multiply(new BigDecimal("0.2")).multiply(levelTwoCeiling.price()));
            price = price.add(area.multiply(new BigDecimal("1.4")).multiply(liBangCoat.price()));
            price = price.add(area.multiply(marcoPoloTile.price()));

        }

        // 现代简约
        if (3 == level) {

            LevelOneCeiling levelOneCeiling = new LevelOneCeiling();  // 吊顶,二级顶
            LiBangCoat liBangCoat = new LiBangCoat();                 // 涂料,立邦
            DongPengTile dongPengTile = new DongPengTile();           // 地砖,东鹏

            list.add(levelOneCeiling);
            list.add(liBangCoat);
            list.add(dongPengTile);

            price = price.add(area.multiply(new BigDecimal("0.2")).multiply(levelOneCeiling.price()));
            price = price.add(area.multiply(new BigDecimal("1.4")).multiply(liBangCoat.price()));
            price = price.add(area.multiply(dongPengTile.price()));
        }

        StringBuilder detail = new StringBuilder("\r\n-------------------------------------------------------\r\n" +
                "装修清单" + "\r\n" +
                "套餐等级:" + level + "\r\n" +
                "套餐价格:" + price.setScale(2, BigDecimal.ROUND_HALF_UP) + " 元\r\n" +
                "房屋面积:" + area.doubleValue() + " 平米\r\n" +
                "材料清单:\r\n");

        for (Matter matter: list) {
            detail.append(matter.scene()).append(":").append(matter.brand()).append("、").append(matter.model()).append("、平米价格:").append(matter.price()).append(" 元。\n");
        }

        return detail.toString();

    }

}
  • 首先这段代码所要解决的问题就是接收入参;装修面积(area)、装修等级(level),根据不同类型的装修等级选择不同的材料。
  • 其次在实现过程中可以看到每一段if块里,都包含着不通的材料(吊顶,二级顶、涂料,立邦、地砖,马可波罗),最终生成装修清单和装修成本。
  • 最后提供获取装修详细信息的方法,返回给调用方,用于知道装修清单。

5.3、 测试验证

接下来我们通过junit单元测试的方式验证接口服务,强调日常编写好单测可以更好的提高系统的健壮度。

编写测试类:

@Test
public void test_DecorationPackageController(){
    DecorationPackageController decoration = new DecorationPackageController();
    // 豪华欧式
    System.out.println(decoration.getMatterList(new BigDecimal("132.52"),1));
    // 轻奢田园
    System.out.println(decoration.getMatterList(new BigDecimal("98.25"),2));
    // 现代简约
    System.out.println(decoration.getMatterList(new BigDecimal("85.43"),3));
}

结果:

-------------------------------------------------------

装修清单

套餐等级:1

套餐价格:198064.39 元

房屋面积:132.52 平米

材料清单:

吊顶:装修公司自带、二级顶、平米价格:850 元。

涂料:多乐士(Dulux)、第二代、平米价格:719 元。

地板:圣象、一级、平米价格:318 元。

-------------------------------------------------------

装修清单

套餐等级:2

套餐价格:119865.00 元

房屋面积:98.25 平米

材料清单:

吊顶:装修公司自带、二级顶、平米价格:850 元。

涂料:立邦、默认级别、平米价格:650 元。

地砖:马可波罗(MARCO POLO)、缺省、平米价格:140 元。

-------------------------------------------------------

装修清单

套餐等级:3

套餐价格:90897.52 元

房屋面积:85.43 平米

材料清单:

吊顶:装修公司自带、一级顶、平米价格:260 元。

涂料:立邦、默认级别、平米价格:650 元。

地砖:东鹏瓷砖、10001、平米价格:102 元。

Process finished with exit code 0

看到输出的这个结果,已经很有装修公司提供报价单的感觉了。以上这段使用ifelse方式实现的代码,目前已经满足的我们的也许功能。但随着老板对业务的快速发展要求,会提供很多的套餐针对不同的户型。那么这段实现代码将迅速扩增到几千行,甚至在修修改改中,已经像膏药一样难以维护。

六、建造者模式重构代码

接下来使用建造者模式来进行代码优化,也算是一次很小的重构。

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

这里我们会把构建的过程交给创建者类,而创建者通过使用我们的构建工具包,去构建出不同的装修套餐

6.1、工程结构

itstack-demo-design-3-02

└── src

    ├── main

    │   └── java

    │       └── org.itstack.demo.design

    │           ├── Builder.java    

    │           ├── DecorationPackageMenu.java

    │           └── IMenu.java 

    └── test

         └── java

             └── org.itstack.demo.design.test

                 └── ApiTest.java

建造者模型结构

工程中有三个核心类和一个测试类,核心类是建造者模式的具体实现。与ifelse实现方式相比,多出来了两个二外的类。具体功能如下;

Builder,建造者类具体的各种组装由此类实现。DecorationPackageMenu,是IMenu接口的实现类,主要是承载建造过程中的填充器。相当于这是一套承载物料和创建者中间衔接的内容。

好,那么接下来会分别讲解几个类的具体实现。

6.2、代码实现

6.2.1、定义装修包接口

public interface IMenu {

    IMenu appendCeiling(Matter matter); // 吊顶

    IMenu appendCoat(Matter matter);    // 涂料

    IMenu appendFloor(Matter matter);   // 地板

    IMenu appendTile(Matter matter);    // 地砖

    String getDetail();                 // 明细 

}

接口类中定义了填充各项物料的方法;吊顶涂料地板地砖,以及最终提供获取全部明细的方法。

6.2.2、装修包实现

public class DecorationPackageMenu implements IMenu {

    private List<Matter> list = new ArrayList<Matter>();  // 装修清单
    private BigDecimal price = BigDecimal.ZERO;      // 装修价格

    private BigDecimal area;  // 面积
    private String grade;     // 装修等级;豪华欧式、轻奢田园、现代简约

    private DecorationPackageMenu() {
    }

    public DecorationPackageMenu(Double area, String grade) {
        this.area = new BigDecimal(area);
        this.grade = grade;
    }

    public IMenu appendCeiling(Matter matter) {
        list.add(matter);
        price = price.add(area.multiply(new BigDecimal("0.2")).multiply(matter.price()));
        return this;
    }

    public IMenu appendCoat(Matter matter) {
        list.add(matter);
        price = price.add(area.multiply(new BigDecimal("1.4")).multiply(matter.price()));
        return this;
    }

    public IMenu appendFloor(Matter matter) {
        list.add(matter);
        price = price.add(area.multiply(matter.price()));
        return this;
    }

    public IMenu appendTile(Matter matter) {
        list.add(matter);
        price = price.add(area.multiply(matter.price()));
        return this;
    }

    public String getDetail() {

        StringBuilder detail = new StringBuilder("\r\n-------------------------------------------------------\r\n" +
                "装修清单" + "\r\n" +
                "套餐等级:" + grade + "\r\n" +
                "套餐价格:" + price.setScale(2, BigDecimal.ROUND_HALF_UP) + " 元\r\n" +
                "房屋面积:" + area.doubleValue() + " 平米\r\n" +
                "材料清单:\r\n");

        for (Matter matter: list) {
            detail.append(matter.scene()).append(":").append(matter.brand()).append("、").append(matter.model()).append("、平米价格:").append(matter.price()).append(" 元。\n");
        }

        return detail.toString();
    }

}
  • 装修包的实现中每一个方法都会了 this,也就可以非常方便的用于连续填充各项物料。
  • 同时在填充时也会根据物料计算平米数下的报价,吊顶和涂料按照平米数适量乘以常熟计算。
  • 最后同样提供了统一的获取装修清单的明细方法。

6.2.3、建造者方法

public class Builder {

    public IMenu levelOne(Double area) {
        return new DecorationPackageMenu(area, "豪华欧式")
                .appendCeiling(new LevelTwoCeiling())    // 吊顶,二级顶
                .appendCoat(new DuluxCoat())             // 涂料,多乐士
                .appendFloor(new ShengXiangFloor());     // 地板,圣象
    }

    public IMenu levelTwo(Double area){
        return new DecorationPackageMenu(area, "轻奢田园")
                .appendCeiling(new LevelTwoCeiling())   // 吊顶,二级顶
                .appendCoat(new LiBangCoat())           // 涂料,立邦
                .appendTile(new MarcoPoloTile());       // 地砖,马可波罗
    }

    public IMenu levelThree(Double area){
        return new DecorationPackageMenu(area, "现代简约")
                .appendCeiling(new LevelOneCeiling())   // 吊顶,二级顶
                .appendCoat(new LiBangCoat())           // 涂料,立邦
                .appendTile(new DongPengTile());        // 地砖,东鹏
    }

}

建造者的使用中就已经非常容易了,统一的建造方式,通过不同物料填充出不同的装修风格;豪华欧式轻奢田园现代简约,如果将来业务扩展也可以将这部分内容配置到数据库自动生成。但整体的思想还可以使用创建者模式进行搭建。

6.3、测试验证

编写测试类:

@Test
public void test_Builder(){
    Builder builder = new Builder();
    // 豪华欧式
    System.out.println(builder.levelOne(132.52D).getDetail());
    // 轻奢田园
    System.out.println(builder.levelTwo(98.25D).getDetail());
    // 现代简约
    System.out.println(builder.levelThree(85.43D).getDetail());
}

结果:

-------------------------------------------------------

装修清单

套餐等级:豪华欧式

套餐价格:198064.39 元

房屋面积:132.52 平米

材料清单:

吊顶:装修公司自带、二级顶、平米价格:850 元。

涂料:多乐士(Dulux)、第二代、平米价格:719 元。

地板:圣象、一级、平米价格:318 元。

-------------------------------------------------------

装修清单

套餐等级:轻奢田园

套餐价格:119865.00 元

房屋面积:98.25 平米

材料清单:

吊顶:装修公司自带、二级顶、平米价格:850 元。

涂料:立邦、默认级别、平米价格:650 元。

地砖:马可波罗(MARCO POLO)、缺省、平米价格:140 元。

-------------------------------------------------------

装修清单

套餐等级:现代简约

套餐价格:90897.52 元

房屋面积:85.43 平米

材料清单:

吊顶:装修公司自带、一级顶、平米价格:260 元。

涂料:立邦、默认级别、平米价格:650 元。

地砖:东鹏瓷砖、10001、平米价格:102 元。

Process finished with exit code 0

测试结果是一样的,调用方式也基本类似。但是目前的代码结构却可以让你很方便的很有调理的进行扩展业务开发。而不是以往一样把所有代码都写到ifelse里面。

七、总结

通过上面对建造者模式的使用,已经可以摸索出一点心得。那就是什么时候会选择这样的设计模式,当:一些基本物料不会变,而其组合经常变化的时候,就可以选择这样的设计模式来构建代码。

此设计模式满足了单一职责原则以及可复用的技术、建造者独立、易扩展、便于控制细节风险。但同时当出现特别多的物料以及很多的组合后,类的不断扩展也会造成难以维护的问题。但这种设计结构模型可以把重复的内容抽象到数据库中,按照需要配置。这样就可以减少代码中大量的重复。

设计模式能带给你的是一些思想,但在平时的开发中怎么样清晰的提炼出符合此思路的建造模块,是比较难的。需要经过一些锻炼和不断承接更多的项目,从而获得这部分经验。有的时候你的代码写的好,往往是倒逼的,复杂的业务频繁的变化,不断的挑战!

以上就是详解Java实践之建造者模式的详细内容,更多关于Java 建造者模式的资料请关注我们其它相关文章!

(0)

相关推荐

  • 深入解析Java的设计模式编程中建造者模式的运用

    定义:将一个复杂对象的构建与它的表示分离,使得同样的构建过程可以创建不同的表示. 类型:创建类模式 类图: 四个要素 产品类:一般是一个较为复杂的对象,也就是说创建对象的过程比较复杂,一般会有比较多的代码量.在本类图中,产品类是一个具体的类,而非抽象类.实际编程中,产品类可以是由一个抽象类与它的不同实现组成,也可以是由多个抽象类与他们的实现组成. 抽象建造者:引入抽象建造者的目的,是为了将建造的具体过程交与它的子类来实现.这样更容易扩展.一般至少会有两个抽象方法,一个用来建造产品,一个是用来返回

  • Java运用设计模式中的建造者模式构建项目的实例解析

    1.建造者模式概念 定义: 将一个复杂的对象构建与其表示相分离,使得同样的构建过程可以创建不同的表示: 核心 : 构建与表示分离,同构建不同表示 区别于 抽象工厂模式 : (1)与抽象工厂模式 相似,因为它也可以创建复杂对象.主要的区别是建造者模式着重于 一步步构造一个复杂对象,关注的是零件类型和装配工艺的顺序 .而抽象工厂模式着重于多个系列的产品对象(简单的或是复杂的).建造者模式在最后的一步返回产品,而对于抽象工厂来说,产品是立即返回的. (2)在建造者模式里,有个指导者,由指导者来管理建造

  • 讲解Java设计模式编程中的建造者模式与原型模式

    建造者模式 定义 又叫生成器模式,它可以将复杂对象的建造过程抽象出来(抽象类别),使这个抽象过程的不同实现方法可以构造出不同表现(属性)的对象. 当创建复杂对象的算法应该独立于该对象的组成部分时,而且构造过程必须允许被构造的对象有不同的表示时.我们可以考虑使用建造者模式. 实现 1. Builder为创建一个Product对象的各个部件指定抽象接口.通常包含创建产品和返回产品的抽象方法,也可以是具体方法,把创建过程放到ConcreteBuilder类中. 2. ConcreteBuilder 实

  • Java设计模式之建造者模式(Builder模式)介绍

    Builder模式定义:将一个复杂对象的构建与它的表示分离,使得同样的构建过程可以创建不同的表示. Builder模式是一步一步创建一个复杂的对象,它允许用户可以只通过指定复杂对象的类型和内容就可以构建它们.用户不知道内部的具体构建细节.Builder模式是非常类似抽象工厂模式,细微的区别大概只有在反复使用中才能体会到. 为何使用建造者模式 是为了将构建复杂对象的过程和它的部件解耦.注意:是解耦过程和部件. 因为一个复杂的对象,不但有很多大量组成部分,如汽车,有很多部件:车轮.方向盘.发动机,还

  • JAVA设计模式之建造者模式原理与用法详解

    本文实例讲述了JAVA设计模式之建造者模式定义与用法.分享给大家供大家参考,具体如下: 建造者模式:将复杂对象的构造与它的实现相分离,让相同的构建过程可以创建不同的对象. 适用场合: 复杂对象的算法应该独立于该对象的组成部分或当构造过程允许被构造不同的对象时. 组成角色: 1 创建者(Builder)接口:为创建一个对象的对应部件所指定抽象接口. 2 具体创建者(ConcreteBuilder):实现Builder的接口以构造对象的各个部件. 3 具体创建者管理对象(Director):使用Bu

  • Java设计模式之建造者模式实例详解

    本文实例讲述了Java设计模式之建造者模式.分享给大家供大家参考,具体如下: 建造者模式(builder)可以将部件和其组装过程分开.一步一步创建一个复杂的对象. 用户只需要指定复杂对象的类型就可以得到该对象,而无须知道其内部的具体构造细节. 什么情况下会用到建造者模式? 个人理解,当我们创建的对象在创建时需要逻辑的时候. 比如,一个简单的pojo对象,我们想要创建,直接就可以new出来,没有什么逻辑. 当有一个复杂的对象,你想要创建它时,它的各个属性之间是有逻辑关系的. 一个属性赋值取值依赖于

  • java设计模式之建造者模式学习

    1 概述建造者模式(Builder Pattern)主要用于"分步骤构建一个复杂的对象",在这其中"分步骤"是一个稳定的算法,而复杂对象的各个部分则经常变化.因此, 建造者模式主要用来解决"对象部分"的需求变化. 这样可以对对象构造的过程进行更加精细的控制. 2 示例以生产手机为例,每个手机分为屏幕Screen.CPU.Battery.现在要生产两种手机,苹果机和三星. 苹果: 复制代码 代码如下: package org.scott.build

  • Java设计模式之Builder建造者模式

    一.场景描述 建造者模式同工厂模式.抽象工厂模式一样,用于创建继承类对象. 工厂模式:Java设计模式之工厂模式 抽象工厂模式:Java设计模式之抽象工厂模式 所不同的是,工厂模式下,各子类实现接口,通过工厂类创建子类对象:而建造者模式下,各子类拥有其建造者类,通过它创建不同的父类对象,最终实现多态,实际上子类.父类在代码中是不存在的. 以仪器数据采集工具为例,工厂模式下,定义接口"仪器数据采集工具",定义子类"PDF文件数据采集工具"和"Excel文件数

  • 理解java设计模式之建造者模式

    建造者模式(Builder Pattern)主要用于"分步骤构建一个复杂的对象",在这其中"分步骤"是一个稳定的算法,而复杂对象的各个部分则经常变化.因此, 建造者模式主要用来解决"对象部分"的需求变化. 这样可以对对象构造的过程进行更加精细的控制. package com.shejimoshi.create.Builder; /** * 功能:意图是将一个复杂对象的构建与它的表示分离,使得同样的构建过程可以创建不同的表示 * 适用性: * 当创

  • 详解Java实践之建造者模式

    目录 一.前言 二.开发环境 三.建造者模式介绍 四.案例场景模拟 4.1.场景模拟工程 4.2.场景简述 4.2.1.物料接口 4.2.2.吊顶(ceiling) 4.2.3.涂料(coat) 4.2.4.地板(floor) 4.2.5.地砖(tile) 五.代码实现 5.1.工程结构 5.2.ifelse实现需求 5.3. 测试验证 六.建造者模式重构代码 6.1.工程结构 6.2.代码实现 6.2.1.定义装修包接口 6.2.2.装修包实现 6.2.3.建造者方法 6.3.测试验证 七.总

  • 详解Java实践之抽象工厂模式

    目录 一.前言 二.开发环境 三.抽象工厂模式介绍 四.案例场景模拟 4.1.场景模拟工程 4.2.场景简述 4.2.1.模拟单机服务 RedisUtils 4.2.2.模拟集群 EGM 4.2.3.模拟集群 IIR 4.3.单集群代码使用 4.3.1.定义使用接口 4.3.2.实现调用代码 五.代码实现 5.1.工程结构 5.2.ifelse实现需求 5.3.测试验证 六.抽象工厂模式重构代码 6.1.工程结构 6.2.代码实现 6.2.1.定义适配接口 6.2.2.实现集群使用服务 6.2.

  • 详解java实践SPI机制及浅析源码

    1.概念 正式步入今天的核心内容之前,溪源先给大家介绍一下关于SPI机制的相关概念,最后会提供实践源代码. SPI即Service Provider Interface,属于JDK内置的一种动态的服务提供发现机制,可以理解为运行时动态加载接口的实现类.更甚至,大家可以将SPI机制与设计模式中的策略模式建立联系. SPI机制: 从上图中理解SPI机制:标准化接口+策略模式+配置文件: SPI机制核心思想:系统设计的各个抽象,往往有很多不同的实现方案,在面向的对象的设计里,一般推荐模块之间基于接口编

  • 详解Java实践之适配器模式

    目录 一.前言 二.适配器模式介绍 三.案例场景模拟 3.1.场景模拟工程 3.2.场景简述 3.2.1.注册开户MQ 3.2.2.内部订单MQ 3.2.3.第三方订单MQ 3.2.4.查询用户内部下单数量接口 3.2.5.查询用户第三方下单首单接口 四.代码实现 4.1.工程结构 4.2.Mq接收消息实现 五.适配器模式重构代码 5.1.工程结构 5.2.代码实现(MQ消息适配) 5.2.1.统一的MQ消息体 5.2.2.MQ消息体适配类 5.2.3.测试适配类 5.3.代码实现(接口使用适配

  • 详解JAVA设计模式之代理模式

    什么是设计模式(Design Pattern)? 设计模式是一套被反复使用,多数人知晓的,经过分类编目的,代码设计经验的总结. 代理模式的定义? 代理模式就是为其他对象提供一种代理,以控制对这个对象的访问. 代理对象起到中介作用,可去掉功能服务或增加额外的服务. 代理对象和目标对象的关系? 代理对象:增强后的对象 目标对象:被增强的对象 他们不是绝对的,会根据情况发生变化. 代理模式的两种实现方式? 1.静态代理:代理和被代理对象在代理之前是确定的,它们都实现相同的接口或者继承相同的抽象类. 2

  • 详解JAVA设计模式之模板模式

    在模板模式(Template Pattern)中,一个抽象类公开定义了执行它的方法的方式/模板.它的子类可以按需要重写方法实现,但调用将以抽象类中定义的方式进行.这种类型的设计模式属于行为型模式. 介绍 意图:定义一个操作中的算法的骨架,而将一些步骤延迟到子类中.模板方法使得子类可以不改变一个算法的结构即可重定义该算法的某些特定步骤. 主要解决:一些方法通用,却在每一个子类都重新写了这一方法. 何时使用:有一些通用的方法. 如何解决:将这些通用算法抽象出来. 关键代码:在抽象类实现,其他步骤在子

  • 详解JAVA 设计模式之状态模式

    在状态模式(State Pattern)中,类的行为是基于它的状态改变的.这种类型的设计模式属于行为型模式. 在状态模式中,我们创建表示各种状态的对象和一个行为随着状态对象改变而改变的 context 对象. 介绍 意图: 允许对象在内部状态发生改变时改变它的行为,对象看起来好像修改了它的类. 主要解决: 对象的行为依赖于它的状态(属性),并且可以根据它的状态改变而改变它的相关行为. 何时使用: 代码中包含大量与对象状态有关的条件语句. 如何解决: 将各种具体的状态类抽象出来. 关键代码: 通常

  • 详解Java从工厂方法模式到 IOC/DI思想

    前言 简单工厂的本质是选择实现,说白了是由一个专门的类去负责生产我们所需要的对象,从而将对象的创建从代码中剥离出来,实现松耦合.我们来看一个例子: 我们要创建一个文件导出工具 public interface FileOper{ public Boolean exceptFile(String data); } public class XMLFileOp implment FileOper{ public Boolean exceptFile(String data){ System.out.

  • 详解Java设计模式之桥接模式

    目录 一.什么是桥接模式: 二.UML结构图 三.代码实现 四.JDBC源码解析-桥接模式 1.源码分析 2.源码类 3.对 JDBC 的观点 一.什么是桥接模式: 桥接,顾名思义,就是用来连接两个部分,使得两个部分可以互相通讯,桥接模式的作用就是为被分离的抽象部分和实现部分搭桥.在现实生活中一个物品在搭配不同的配件时会产生不同的动作和结果,例如一辆赛车搭配的是硬胎或者是软胎就能够在干燥的马路上行驶,而如果要在下雨的路面行驶,就需要搭配雨胎了,这种根据行驶的路面不同,需要搭配不同的轮胎的变化的情

  • 详解Java设计模式之备忘录模式的使用

    定义与结构     备忘录(Memento)模式又称标记(Token)模式.GOF给备忘录模式的定义为:在不破坏封装性的前提下,捕获一个对象的内部状态,并在该对象之外保存这个状态.这样以后就可将该对象恢复到原先保存的状态. 在讲命令模式的时候,我们曾经提到利用中间的命令角色可以实现undo.redo的功能.从定义可以看出备忘录模式是专门来存放对象历史状态的,这对于很好的实现undo.redo功能有很大的帮助.所以在命令模式中undo.redo功能可以配合备忘录模式来实现. 其实单就实现保存一个对

随机推荐