当前位置: 首页 > article >正文

设计模式-建造者模式Builder

建造者模式

  • 建造者模式 (Builder)
    • 1) 原理
    • 2) 为什么需要建造者模式
    • 3) 源码应用

建造者模式 (Builder)

1) 原理

Builder 模式,中文翻译为建造者模式或者构建者模式,也有人叫它生成器模式

创建者模式主要包含以下四个角色:

  • 1.产品(Product):表示将要被构建的复杂对象
  • 2.抽象创建者(Abstract Builder):定义构建产品的接口,通常包含创建和获取产品的方法。
  • 3.具体创建者(Concrete Builder):实现抽象创建者定义的接口,为产品的各个部分提供具体实现。
  • 4.指挥者(Director):负责调用具体创建者来构建产品的各个部分,控制构建过程。

我们考虑一个文档编辑器的例子。假设我们需要创建一个复杂的HTML文档,它包含了标题、段落和图像等元素。我们可以使用创建者设计模式来构建HTML文档。

1.产品(Product)类 - HTML文档(HtmlDocument):

public class HtmlDocument {
    private String header = "";
    private String body = "";
    private String footer = "";
    
    public void addHeader(String header) {
    	this.header = header;
    }
    public void addBody(String body) {
    	this.body = body;
    }
    public void addFooter(String footer) {
    	this.footer = footer;
    }
    
    @Override
    public String toString() {
        return "<html><head>" + header + "</head><body>" + body + "</body>
        	<footer>" + footer + "</footer></html>";
    }
}

2.抽象创建者(Abstract Builder)类 - HtmlDocumentBuilder:

public abstract class HtmlDocumentBuilder {
    protected HtmlDocument document;
    public HtmlDocument getDocument() {
    	return document;
    }
    public void createNewHtmlDocument() {
    	document = new HtmlDocument();
    }
    public abstract void buildHeader();
    public abstract void buildBody();
    public abstract void buildFooter();
}

3.具体创建者(Concrete Builder)类 - ArticleHtmlDocumentBuilder:

public class ArticleHtmlDocumentBuilder extends HtmlDocumentBuilder {
    @Override
    public void buildHeader() {
    	document.addHeader("Article Header");
    }
    @Override
    public void buildBody() {
    	document.addBody("Article Body");
    }
    @Override
    public void buildFooter() {
    	document.addFooter("Article Footer");
    }
}

4.指挥者(Director)类 - HtmlDirector:

public class HtmlDirector {
    private HtmlDocumentBuilder builder;
    public HtmlDirector(HtmlDocumentBuilder builder) {
    	this.builder = builder;
    }
    public void constructDocument() {
        builder.createNewHtmlDocument();
        builder.buildHeader();
        builder.buildBody();
        builder.buildFooter();
    }
    public HtmlDocument getDocument() {
    	return builder.getDocument();
    }
}

现在我们可以使用创建者设计模式来构建一个HTML文档对象:

public class Main {
    public static void main(String[] args) {
        HtmlDocumentBuilder articleBuilder = new ArticleHtmlDocumentBuilder();
        HtmlDirector director = new HtmlDirector(articleBuilder);
        director.constructDocument();
        HtmlDocument document = director.getDocument();
        System.out.println("Constructed HTML Document: \n" + document);
    }
}

以上是一个创建者设计模式的标准写法,事实,我们在工作中往往不会写的这么复杂,为了创建一个对象,我们创建了很多辅助的类,总觉得不太合适,在这个案例中,我们可以使用内部类来简化代码,以下是修改后的代码:

public class HtmlDocument {
    private String header = "";
    private String body = "";
    private String footer = "";
    public void addHeader(String header) {
    	this.header = header;
    }
    public void addBody(String body) {
    	this.body = body;
    }
    public void addFooter(String footer) {
    	this.footer = footer;
    }
    @Override
    public String toString() {
        return "<html><head>" + header + "</head><body>" + body + "</body>
        	<footer>" + footer + "</footer></html>";
    }
    
    public static class Builder {
        protected HtmlDocument document;
        public Builder() {
        	document = new HtmlDocument();
        }
        public Builder addHeader(String header) {
        	document.addHeader(header);
        	return this;
        }
        public Builder addBody(String body) {
        	document.addBody(body);
        	return this;
        }
        public Builder addFooter(String footer) {
        	document.addFooter(footer);
        	return this;
        }
        public HtmlDocument build() {
        	return document;
        }
    }
}

2) 为什么需要建造者模式

1.根据复杂的配置项进行定制化构建

2.实现不可变对象。即一旦创建完成,对象的状态就不能改变。这有助于保证对象的线程安全和数据完整性

3) 源码应用

1.jdk中,如StringBuilder和StringBuffer,他们的实现不是完全按照标准的创建者设计模式设计,但也是一样的思想:

2.在ssm源码中很多类都使用创建者设计模式,如Spring中的BeanDefinitionBuilder 类,mybatis中的 SqlSessionFactoryBuilderXMLConfigBuilderXMLMapperBuilderXMLStatementBuilderCacheBuilder


http://www.kler.cn/news/233401.html

相关文章:

  • uniapp的配置和使用
  • 【C语言】变量与常量
  • 【Qt】常见问题
  • 2.7日学习打卡----初学RabbitMQ(二)
  • springboot173疫苗发布和接种预约系统
  • 3 scala集合-Set
  • 面试经典150题 -- 栈(总结)
  • vue3+vite+ts 配置commit强制码提交规范配置 commitlint
  • 力扣刷题之旅:进阶篇(三)
  • Java异常的处理 try-catch-finally
  • Python 字符串模块
  • “OLED屏幕,色彩绚丽,画面清晰,让每一帧都生动无比。“#IIC协议【下】
  • JavaWeb02-MyBatis
  • QCoro: Qt C++ 20 协程库介绍
  • 基于图像掩膜和深度学习的花生豆分拣(附源码)
  • 【OpenVINO™】在 MacOS 上使用 OpenVINO™ C# API 部署 Yolov5 (上篇)
  • uni-app x,一个纯原生的Android App开发工具
  • 【力扣】复写零,栈 + 双指针法
  • 张楠辞任抖音集团CEO;东方甄选将开服饰号;小红书新增“附近”一级入口;华为分红770亿元
  • Vue3中路由配置Catch all routes (“*“) must .....问题
  • 通过Harbor构建docker私服仓库
  • 前端使用pdf.js进行pdf文件预览的第二种方式:Viewer.html
  • Quartus工程的qsf配置约束文件介绍
  • 【C语言】一道相当有难度的指针某大厂笔试真题(超详解)
  • 106. 从中序与后序遍历序列构造二叉树 - 力扣(LeetCode)
  • RTE2023第九届实时互联网大会:揭秘未来互联网趋势,PPT分享引领行业新思考
  • Python基础篇_修饰符(Decorators)【下】
  • 常用的正则表达式
  • 一条 SQL 查询语句是如何执行的
  • 探索Spring Validation:优雅实现后端数据验证的艺术