前往小程序,Get更优阅读体验!
立即前往
首页
学习
活动
专区
工具
TVP
发布
社区首页 >专栏 >建造者模式和设计者模式应该怎么使用

建造者模式和设计者模式应该怎么使用

作者头像
燃192
发布2023-02-28 13:52:56
4830
发布2023-02-28 13:52:56
举报
文章被收录于专栏:Java技术圈子

建造者模式

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

一个 Builder 类会一步一步构造最终的对象。该 Builder 类是独立于其他对象的。

说人话:

Bean的建造者对象BeanBuilder是可以写成两个类的

BeanBuilder.xxa().xxb().xxc().build();就会返回一个Bean对象

使用场景1

假设build一个人

代码语言:javascript
复制
PersonBuilder.head(head)
  .arm(arm).arm(arm)
  .leg(leg).leg(leg)
  .body(body).build();

发现什么问题没

如果我这样写呢

代码语言:javascript
复制
PersonBuilder.head(head).head(head).head(head)
  .arm(arm).arm(arm).arm(arm).arm(arm).arm(arm).arm(arm)
  .leg(leg).leg(leg)
  .body(body).build();

这人不就三头六臂了吗,显然不是每一个人都是哪吒,建造者模式适合做整体和局部都可以单独存在组合。

专业术语叫做聚合

聚合 aggregation

UML类图中用 空心菱形箭头 标识

整体和部分可以脱离各自而存在

比如大雁和雁群,比如早餐自选餐。我可以选择豆浆、油条、煎包,也可以选择拌面、胡辣汤 这些聚合起来叫早餐

模板设计模式

那么我真的要new一个人应该怎么做呢

其实这里应该用模板设计模式更合适

在模板模式(Template Pattern)中,一个抽象类公开定义了执行它的方法的方式/模板。它的子类可以按需要重写方法实现,但调用将以抽象类中定义的方式进行。这种类型的设计模式属于行为型模式。

说人话

我设计好一套方法,子类继承以后直接填就行

代码语言:javascript
复制
public abstract class Person {
   abstract void setHead();
   abstract void setLeftArm();
   abstract void setRightArm();
   abstract void setLeftLeg();
   abstract void setRightLeg();
   abstract void setBody();
 
   //模板
   public final void create(){
    abstract void setHead();
   abstract void setLeftArm();
      abstract void setRightArm();
     abstract void setLeftLeg();
      abstract void setRightLeg();
      abstract void setBody();
   }
}

想new一个人,只要继承这个类,然后挨个填就行,还兼容杨过,子类只要setLeftArm(null)就可以了

专业术语叫组合 composition

UML类图中用实心菱形箭头标识

实战

实际使用中,这两者往往没有很明确的界限,要根据实际场景自己选用和适配修改。

比如洗澡

建造者模式就是我可以 桑拿 洗澡 泡温泉 搓澡 随意选几样体验结束就可以。

模板模式就要 先淋浴 泡澡 搓澡 按顺序一条龙

当然也可以混合使用,设计对象的行为,抽象成我们日常的操作方式,会设计的更优雅和更好理解

talk is cheap show me the code

比如我上篇需要构建一个表格对象

建造者模式 我需要set表头,一行内容或者多行内容,可以选择其中几样,表头也可以不传,约束较低使用灵活但是别人用起来会有理解成本。

代码语言:javascript
复制
     // 对象列表,支持泛型,单个对象和list都可以传
    List<OrderDTO> list = Lists.newArrayList();
    list.add(new OrderDTO("12345","创建中"));
    OrderDTO orderDTO = new OrderDTO("12346", "销毁");
    // 不传表格表头名为字段名,字段别名map可以将字段名替换成自定义的名称
    HashMap<String,String> tableHeadDisplayMap = new HashMap();
    tableHeadDisplayMap.put("orderCode","单号");

    // 建造json对象
    TableResultUtil<OrderDTO> tableResultUtil = new TableResultUtil<OrderDTO>();
    TableResult<OrderDTO> tableResult=TableResult.builder().tableHead(tableHeadDisplayMap)
            .item(orderDTO)
            .items(list).build();
    String jsonData = tableResultUtil.createTableResult(tableResult);

模板模式

模板模式 我必须set表头,然后一项一项set数据进去,这样有约束,但是代码即文档。

代码语言:javascript
复制
// 使用
TableResultTemplateExampleImpl<OrderDTO> tableTemplate = new TableResultTemplateExampleImpl();
        tableTemplate.buildTableHead("单号", "结果");
        tableTemplate.buildTableBody("xyz123","模板设计模式");
    // 按理说模板这里只放属性,create()这个职责应该给其他类,为了简便就写这里了
        String jsonData = tableTemplate.create();

混用建造者和模板

场景:将对象转为json数据,再根据json生成excel表格和html表格

效果展示

使用

代码语言:javascript
复制
    public static void template() throws IOException {
        // 任意对象
        OrderDTO orderDTO = new OrderDTO("54320001","已过期");
        // 创建模板set表头
        TableTemplateImpl tableTemplate = new TableTemplateImpl();
        tableTemplate.setTableHead("单号","状态");
        TableResult4Template<TableTemplateImpl> tableResult =
                TableResult4Template.builder()
                        .template(tableTemplate)
                        // set对象的属性,对应表格的内容
                        .items(orderDTO.getOrderCode(),orderDTO.getStatus())
                        .build();
        String toolResult = tableResult.toJson();
        // 表格头及数据
        StringBuffer sBuffer = new StringBuffer();
        List<String> tableHead = dealTableHead2(toolResult);
        dealTableData2(toolResult,sBuffer);
        // 导出成excel
        String filePath = "D:\\模板设计模式" + System.currentTimeMillis()+".xls";
        export(tableHead,sBuffer,filePath);

        // 导出成html table
        String htmltable = convertTaskResultToHtmlTable(tableHead,sBuffer);
        System.out.println(htmltable);
    }

结果 控制台

单号

状态

54320001

已过期

代码语言:javascript
复制
<table border='1' cellspacing='0' cellpadding='3'  align='center'><tr><th>单号</th><th>状态</th></tr><tr><td>54320001</td><td>已过期</td></tr></table>

filepath excel表格

模板设计模式1656141582396.xls

image-20220625152224211

具体代码介绍可以看下一篇

本文参与 腾讯云自媒体同步曝光计划,分享自微信公众号。
原始发表:2022-06-25,如有侵权请联系 cloudcommunity@tencent.com 删除

本文分享自 Java技术圈子 微信公众号,前往查看

如有侵权,请联系 cloudcommunity@tencent.com 删除。

本文参与 腾讯云自媒体同步曝光计划  ,欢迎热爱写作的你一起参与!

评论
登录后参与评论
0 条评论
热度
最新
推荐阅读
目录
  • 建造者模式
    • 说人话:
      • 使用场景1
      • 模板设计模式
        • 说人话
          • 实战
          • talk is cheap show me the code
            • 混用建造者和模板
            • 场景:将对象转为json数据,再根据json生成excel表格和html表格
              • 效果展示
                • 具体代码介绍可以看下一篇
                领券
                问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档