设计模式-第10章(建造者模式)

news2024/11/25 10:14:32

建造者模式

  • 建造者模式
  • 建造者模式解析
  • 建造者模式的基本代码结构

建造者模式

建造者模式(Builder),将一个复杂对象的构建和表示分离,使得同样的构建过程可以创建不同的表示。
如果我们用了建造者模式,那么用户就只需指定需要建造的类型就可以得到它们,而具体建造的过程和细节就不需要知道了。

示例:使用建造者模式画小人
小人有高矮胖瘦,但是每一个小人都有一个头,两个手,两个腿,可以把这些必须要建造的过程和细节定义一个建造者类,规定必须要有的建造过程。

抽象的建造者类

abstract class PersonBuilder {
    protected Graphics g;
    public PersonBuilder(Graphics g){
        this.g = g;
    }
    public abstract void buildHead();       //头
    public abstract void buildBody();       //身体
    public abstract void buildArmLeft();    //左手
    public abstract void buildArmRight();   //右手
    public abstract void buildLegLeft();    //左脚
    public abstract void buildLegRight();   //右脚
}

具体建造者— 瘦小人

class PersonThinBuilder extends PersonBuilder {
    
    public PersonThinBuilder(Graphics g){
        super(g);
    }
    // 实现具体的建造方法,自定义建造细节
    public void buildHead(){
        g.drawOval(150, 120, 30, 30);   //头
    }
    public void buildBody(){
        g.drawRect(160, 150, 10, 50);   //身体
    }
    public void buildArmLeft(){
        g.drawLine(160, 150, 140, 200); //左手
    }
    public void buildArmRight(){
        g.drawLine(170, 150, 190, 200); //右手
    }
    public void buildLegLeft(){
        g.drawLine(160, 200, 145, 250); //左脚
    }
    public void buildLegRight(){
        g.drawLine(170, 200, 185, 250); //右脚 
    }
}

具体的建造者—胖小人

class PersonFatBuilder extends PersonBuilder {
    public PersonFatBuilder(Graphics g){
        super(g);
    }
	// 实现具体的建造方法,自定义建造细节
    public void buildHead(){
        g.drawOval(250, 120, 30, 30);   //头
    }
    public void buildBody(){
        g.drawOval(245, 150, 40, 50);   //身体
    }
    public void buildArmLeft(){
        g.drawLine(250, 150, 230, 200); //左手
    }
    public void buildArmRight(){
        g.drawLine(280, 150, 300, 200); //右手
    }
    public void buildLegLeft(){
        g.drawLine(260, 200, 245, 250); //左脚
    }
    public void buildLegRight(){
        g.drawLine(270, 200, 285, 250); //右脚
    }
}

抽象的建造者规定了必须要有的建造过程,具体的建造者,实现必须的建造过程,根据需求自定义建造细节。
在建造者和使用者之间还需要一个指挥者,来控制具体建造过程,同时隔离用户与建造过程的关联。

指挥者

class PersonDirector {
    private PersonBuilder pb;
    // 初始化时指定需要建造什么样的小人
    public PersonDirector(PersonBuilder pb){
        this.pb = pb;
    }               
    // 根据用户的需要建造小人
    public void CreatePerson(){
        pb.buildHead();     // 头
        pb.buildBody();     // 身体
        pb.buildArmLeft();  // 左手
        pb.buildArmRight(); // 右手
        pb.buildLegLeft();  // 左脚
        pb.buildLegRight(); // 右脚
    }
}

客户端

class Test extends JFrame {
    public Test() {
        setSize(400, 400);
        setDefaultCloseOperation(EXIT_ON_CLOSE);
        setLocationRelativeTo(null);
    }
    public void paint(Graphics g) {
        PersonBuilder gThin = new PersonThinBuilder(g);
        // 使用指挥者,控制建造过程
        PersonDirector pdThin = new PersonDirector(gThin);
        pdThin.CreatePerson();
        PersonBuilder gFat = new PersonFatBuilder(g);
        PersonDirector pdFat = new PersonDirector(gFat);
        pdFat.CreatePerson();
    }
    public static void main(String[] args) {
        new Test().setVisible(true);
    }
}

建造者模式解析

在这里插入图片描述
Builder类,是为创建Product对象的各个部分指定的抽象接口(抽象的小人)。
ConcreteBuilder类,具体的建造者,实现 Builder接口,构造和装配各个部件(具体的小人)。
Product,建造出来的具体对象(小人对象)。
Director ,指挥者,使用 Builder接口的对象,

何时需要使用建造者模式?
建造者模式主要用于创建一些复杂的对象,这些对象内部子对象的建造顺序通常是稳定的,但每个子对象本身的构建通常面临复杂的变化。

建造者模式的好处就是使得建造代码与表示代码分离,由于建造者隐藏了该产品是如何组装的,所以若需要改变一个产品的内部表示,只需要再定义一个具体的建造者就可以了。

建造者模式的基本代码结构

产品类

class Product{
    ArrayList<String> parts = new ArrayList<String>();
    //添加新的产品部件
    public void add(String part){
        parts.add(part);
    }
    //列举所有产品部件
    public void show(){
        for(String part : parts){
            System.out.println(part);
        }
    }
}

抽象的建造者类

abstract class Builder {
    public abstract void buildPartA();      //建造部件A
    public abstract void buildPartB();      //建造部件B
    public abstract Product getResult();    //得到产品
}

具体的建造者类

// 具体建造者1
class ConcreteBuilder1 extends Builder {
    private Product product = new Product();
    public void buildPartA(){
        product.add("部件A");
    }
    public void buildPartB(){
        product.add("部件B");
    }
    public Product getResult(){
        return product;
    }
}
// 具体建造者2
class ConcreteBuilder2 extends Builder {
    private Product product = new Product();
    public void buildPartA(){
        product.add("部件X");
    }
    public void buildPartB(){
        product.add("部件Y");
    }
    public Product getResult(){
        return product;
    }
}

指挥者

class Director{
    public void construct(Builder builder){
        builder.buildPartA();
        builder.buildPartB();
    }
}

客户端
客户端不需要知道具体的建造过程

public class Test {
    public static void main(String[] args){
        System.out.println("**********************************************");       
        System.out.println("《大话设计模式》代码样例");
        System.out.println();  
        Director director = new Director();
        Builder b1 = new ConcreteBuilder1();
        Builder b2 = new ConcreteBuilder2();
        //指挥者用ConcreteBuilder1的方法来建造产品
        director.construct(b1); //创建的是产品A和产品B
        Product p1 = b1.getResult();
        p1.show();
        //指挥者用ConcreteBuilder2的方法来建造产品
        director.construct(b2); //创建的是产品X和产品Y
        Product p2 = b2.getResult();
        p2.show();
        System.out.println();
        System.out.println("**********************************************");
    }
}

建造者模式是在当创建复杂对象的算法应该独立于该对象的组成部分以及它们的装配方式时适用的模式。

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.coloradmin.cn/o/392329.html

如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈,一经查实,立即删除!

相关文章

欢乐消除开心假日协议解密

欢乐消除开心假日协议解密协/议/流/量/解/密分析欢乐消除开心假日这款游戏流量的协议加密方式。序欢乐消除开心假日是一款合成模拟家装的游戏&#xff0c;在这个游戏中&#xff0c;你将成为一位充满热情的设计师&#xff0c;与好友一起经营工作室。你需要根据客户的需求重新设计…

详解PyTorch Tensor 数据类型——张量

目录 张量 张量的结构 张量的创建 张量的操作 数学运算 逻辑运算 形状操作 索引和切片 张量的维度变换 常见的数据类型存储 附录PyTorch官方API中文文档 张量 在PyTorch中&#xff0c;张量&#xff08;Tensor&#xff09;是一种常见的数据类型&#xff0c;它是一个…

如何快速将多图片合并拼接成一张大图并保留原图质量 - 极速图片合成拼接器软件简介

在工作中我们有时需要把多张图片打印在一张纸上&#xff0c;那就必须手动排列和调整每张图片的大小&#xff0c;这可是一项费时费力的任务。 借助极速图片合成拼接器这款软件&#xff0c;终于可以快速自动解决这种任务啦&#xff01; 它是一款可以自动一次性将多个图像文件合并…

Jenkins部署angular11自动打包

可能年纪大了&#xff0c;对于新东西的学习和接收有点慢&#xff0c;花了差不多一周的时间&#xff0c;终于把jenkins配置好了&#xff0c;可以自动打包&#xff0c;与手动打出来的一样&#xff0c;以后就解放双手了。#!/bin/bashnpm cache clean -fnpm -vnode -vnpm install n…

ubuntu 18.04.06LST安装R4.0+版本报错及解决过程

1. sudo apt-get update无法正常使用 错误:13 http://ppa.launchpad.net/webupd8team/sublime-text-3/ubuntu bionic Release 404 Not Found [IP: 2620:2d:4000:1::3e 80] 解决措施&#xff1a;删除 webupd8team/sublime-text-3这个ppa文件。 sudo add-apt-repository --…

MySQL调优 - SQL查询深度分页问题

一、问题引入 例如当前存在一张表test_user&#xff0c;然后往这个表里面插入3百万的数据&#xff1a; CREATE TABLE test_user (id int(11) NOT NULL AUTO_INCREMENT COMMENT 主键id,user_id varchar(36) NOT NULL COMMENT 用户id,user_name varchar(30) NOT NULL COMMENT 用…

嵌入式学习笔记——寄存器开发STM32 GPIO口

寄存器开发STM32GPIO口前言认识GPIOGPIO是什么GPIO有什么用GPIO怎么用STM32上GPIO的命名以及数量GPIO口的框图&#xff08;重点&#xff09;输入框图解析三种输入模式GPIO输入时内部器件及其作用1.保护二极管2.上下拉电阻&#xff08;可配置&#xff09;3.施密特触发器4.输入数…

什么是CatGPT-使用效果如何-

个人使用效果&#xff0c;评分优&#xff0c;足以满足教学和填表。程序媛借助CatGPT&#xff08;ChatGPT更佳&#xff09;&#xff0c;基本上可以秒杀不用此类工具的程序猿&#xff08;男&#xff09;&#xff01;&#xff01;&#xff01;问&#xff1a;为什么使用AIGC能大幅度…

79、ClimateNeRF: Physically-based Neural Rendering for Extreme Climate Synthesis

简介主页物理模拟可以很好地预测天气影响。神经辐射场产生SOTA场景模型。ClimateNeRF 允许我们渲染真实的天气效果&#xff0c;包括雾霾、雪和洪水 &#xff0c;结果可以通过有物理意义的变量来控制&#xff0c;比如水位 &#xff0c;这允许人们可视化气候变化的结果将对他们产…

2022年MathorCup数学建模B题无人仓的搬运机器人调度问题解题全过程文档加程序

2022年第十二届MathorCup高校数学建模 B题 无人仓的搬运机器人调度问题 原题再现 本题考虑在无人仓内的仓库管理问题之一&#xff0c;搬运机器人 AGV 的调度问题。更多的背景介绍请参看附件-背景介绍。对于无人仓来说&#xff0c;仓库的地图模型可以简化为图的数据结构。 仓库…

面试常问【进程间通信】最详细解说

文章目录 目录 文章目录 一、进程间有哪几种的通信方式 1.为什么需要进程间通信? 2.进程通信的几种方式 3.进程间通信的目的 二、管道 1.匿名管道 2.命名管道 3.管道总结 三、消息队列 四、共享内存 1.共享内存的原理 2.共享内存的接口 1.创建共享内存 2.将共享内存附加到进程…

HBase---Hbase安装(单机版)

Hbase安装单机版 文章目录Hbase安装单机版Master/Slave架构安装步骤配置Hbase1.上传压缩包解压更名修改hbase-env.sh修改hbase-site.xml配置HBase环境变量配置Zookeeper复制配置文件修改zoo.cfg配置文件修改myid配置Zookeeper环境变量刷信息配置文件启动hbase步骤hbase shellMa…

BS系统中的安全方案(SSO和Oauth2认证,数据加密)

摘要用户用浏览器打开网站&#xff0c;DNS会根据域名找到相应的服务器IP给到浏览器&#xff0c;仅接着用户的浏览器会与服务器建立连接&#xff0c;通过网路上的各个设备(交换机、路由器、基站、光纤等)&#xff0c;将服务器上的数据发送到用户的电脑上&#xff0c;在浏览器里呈…

运输层概述及web请求

运输层 运输层概述 运输层向高层用户屏蔽了下面网络核心的细节&#xff08;如网络拓扑、所采用的路由选择协议等&#xff09;它使应用进程看见的就好像是在两个运输层实体之间有一条端到端的逻辑通信信道&#xff1b; 根据需求不同&#xff0c;运输层提供两种运输协议 面向连…

buffer它到底做了个啥,源码级分析linux内核的文件系统的缓冲区

最近一直在学习linux内核源码&#xff0c;总结一下 https://github.com/xiaozhang8tuo/linux-kernel-0.11 自己整理过的带注释的源码。 为什么要有buffer ​ 高速缓冲区是文件系统访问块设备中数据的必经要道(PS:如果所有程序结果都不落盘&#xff0c;只是int a, a直接在主存…

TryHackMe-Debug(ez php反序列化)

Debug Linux机器CTF&#xff01;您将了解枚举&#xff0c;查找隐藏的密码文件以及如何利用php反序列化&#xff01; 端口扫描 循例&#xff0c;nmap Web枚举 进到web是apache默认页面&#xff0c;直接开扫 由于题目告诉我们涉及php反序列化&#xff0c;那直接找php文件来看&…

Linux学习第十四节-shell脚本

1.Shell概述 Shell连接了用户和Linux内核&#xff0c;他可以解释用户输入的命令传输给内核&#xff0c;让用户可以更加方便的使用Linux系统&#xff1b; Shell本身并不是内核的一部分&#xff0c;他只是站在内核的基础上编写一个应用程序&#xff1b; Shell具备编程的能力&a…

C++回顾(八)—— 继承

8.1 继承的概念 继承是类与类之间的关系&#xff0c;是一个很简单很直观的概念&#xff0c;与现实世界中的继承类似&#xff0c;例如儿子继承父亲的财产。 继承&#xff08;Inheritance&#xff09;可以理解为一个类从另一个类获取成员变量和成员函数的过程。例如类 B 继承于类…

jconsole远程linux下的tomcat

修改Tomcat的配置 进去 Tomcat 安装目录下的 bin 目录&#xff0c;编辑 catalina.sh vi catalina.sh定位到 ----- Execute The Requested Command ----------------------------------------- vi 编辑模式下&#xff0c;点击 Esc&#xff0c;输入 / &#xff0c;然后粘贴 -…

什么是Netty

一&#xff0e;Netty介绍 1.什么是netty Netty 是由 JBOSS 提供的一个 Java 开源框架。Netty 提供异步的、基于事件驱动的网络应用程序框架&#xff0c;用以快速开发高性能、高可靠性的网络 IO 程序,是目前最流行的 NIO 框架&#xff0c;Netty 在互联网领域、大数据分布式计算…