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


    建造者模式

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

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

    说人话:

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

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

    使用场景1

    假设build一个人

    PersonBuilder.head(head)
    		.arm(arm).arm(arm)
    		.leg(leg).leg(leg)
    		.body(body).build();
    
    • 1
    • 2
    • 3
    • 4

    发现什么问题没

    如果我这样写呢

    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();
    
    • 1
    • 2
    • 3
    • 4

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

    专业术语叫做聚合

    聚合 aggregation

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

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

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

    模板模式

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

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

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

    说人话

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

    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();
       }
    }
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8
    • 9
    • 10
    • 11
    • 12
    • 13
    • 14
    • 15
    • 16
    • 17
    • 18

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

    专业术语叫组合 composition

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

    实战

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

    比如洗澡

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

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

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

    talk is cheap show me the code

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

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

         // 对象列表,支持泛型,单个对象和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);
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8
    • 9
    • 10
    • 11
    • 12
    • 13
    • 14

    模板模式

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

    // 使用
    TableResultTemplateExampleImpl<OrderDTO> tableTemplate = new TableResultTemplateExampleImpl();
            tableTemplate.buildTableHead("单号", "结果");
            tableTemplate.buildTableBody("xyz123","模板设计模式");
    				// 按理说模板这里只放属性,create()这个职责应该给其他类,为了简便就写这里了
            String jsonData = tableTemplate.create();
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6

    混用建造者和模板

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

    效果展示

    使用

        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);
        }
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8
    • 9
    • 10
    • 11
    • 12
    • 13
    • 14
    • 15
    • 16
    • 17
    • 18
    • 19
    • 20
    • 21
    • 22
    • 23
    • 24
    • 25

    结果
    控制台

    单号状态
    54320001已过期
    <table border='1' cellspacing='0' cellpadding='3'  align='center'><tr><th>单号</th><th>状态</th></tr><tr><td>54320001</td><td>已过期</td></tr></table>
    
    • 1

    filepath excel表格

    ​ 模板设计模式1656141582396.xls

    image-20220625152224211
    具体实现参考上一篇
    POI Excel转换工具

  • 相关阅读:
    抖音矩阵系统。抖音矩阵系统。抖音矩阵系统。here
    【Mybatisplus】初识Mybatisplus+SpringBoot整合
    RuntimeError: “addmm_impl_cpu_“ not implemented for ‘Half‘
    java毕业设计超市商品管理mybatis+源码+调试部署+系统+数据库+lw
    数据库设计的酸(ACID)碱(BASE)原则
    有宝妈在家赚钱的兼职副业吗?
    2022刘润年度演讲:进化的力量
    Android13 wifi adb 串口开启
    顾往前行,我的前端之路系列(一)
    Java8与JDK1.8与JDK8之间的关系是什么?
  • 原文地址:https://blog.csdn.net/wdays83892469/article/details/125460936