设计模式--模板方法外观模式

news2024/12/26 23:04:51

模板方法模式

场景:需使用代码方式实现,考完试后,将各个学生的试卷及答案誊抄一份。

假如有两个学生的试卷誊抄完毕.

// 学生A
public class TestPaperA {
    // 试题1
    public void testQuestion1() {
        System.out.println("问题一:XXXXXXXX[] A.xx B.xx C.xx D.xx ");
        System.out.println("答案 A");
    }
    // 试题2
    public void testQuestion2() {
        System.out.println("问题二:XXXXXXXX[] A.xx B.xx C.xx D.xx ");
        System.out.println("答案 A");
    }
    // 试题3
    public void testQuestion3() {
        System.out.println("问题三:XXXXXXXX[] A.xx B.xx C.xx D.xx ");
        System.out.println("答案 A");
    }
}
// 学生B
public class TestPaperB {
    // 试题1
    public void testQuestion1() {
        System.out.println("问题一:XXXXXXXX[] A.xx B.xx C.xx D.xx ");
        System.out.println("答案 B");
    }
    // 试题2
    public void testQuestion2() {
        System.out.println("问题二:XXXXXXXX[] A.xx B.xx C.xx D.xx ");
        System.out.println("答案 B");
    }
    // 试题3
    public void testQuestion3() {
        System.out.println("问题三:XXXXXXXX[] A.xx B.xx C.xx D.xx ");
        System.out.println("答案 B");
    }
}
  • 客户端
System.out.println("学生A的试卷");
TestPaperA a = new TestPaperA();
a.testQuestion1();
a.testQuestion2();
a.testQuestion3();

System.out.println("学生B的试卷");
TestPaperB b = new TestPaperB();
b.testQuestion1();
b.testQuestion2();
b.testQuestion3();

一眼看出,很多重复的代码,直接进行提炼抽离。此例中,试卷都是一样的,而答案是不同的,我们直接将重复的代码提炼,然后学生去继承它即可。

  • 试卷类
// 试卷类
public abstract class TestPaper { 
    // 3道题的答案
    protected abstract String answer1();
    protected abstract String answer2();
    protected abstract String answer3();

    // 试题1
    public void testQuestion1() {
        System.out.println("问题一:XXXXXXXX[] A.xx B.xx C.xx D.xx ");
        System.out.println("答案 " + answer1());
    }
    // 试题2
    public void testQuestion2() {
        System.out.println("问题二:XXXXXXXX[] A.xx B.xx C.xx D.xx ");
        System.out.println("答案 " + answer2());
    }
    // 试题3
    public void testQuestion3() {
        System.out.println("问题三:XXXXXXXX[] A.xx B.xx C.xx D.xx ");
        System.out.println("答案 " + answer3());
    }  
}

学生类只需要继承它,然后填写自己的答案即可。因为父类已经建立好了所有重复的模板

// 学生A
public class TestPaperA extends TestPaper{
    @Override
    protected String answer1() {
        return "A";
    }
    @Override
    protected String answer2() {
        return "A";
    }
    @Override
    protected String answer3() {
        return "A";
    }
}
  • 客户端
System.out.println("学生A的试卷");
TestPaper a = new TestPaperA();
a.testQuestion1();
a.testQuestion2();
a.testQuestion3();

那么上述的例子中,用的一种设计模式就是模板方法模式。定义一个操作中的算法的骨架,而将一些步骤延迟到子类中。模板方法使得子类可以不改变一个算法的结构即可重新定义该算法的某些特定步骤。

结构图及代码示例如下:

在这里插入图片描述

public abstract class AbstractClass {
    
    // 模板方法(所有重复的代码都放入这里)
    public void templateMethod() {
        ...
    }
    
    // 子类的特定实现
    public abstract void primitiveOperation1();
    public abstract void primitiveOperation2();
    
}
  • 子类
public class ConcreteClassA extends AbstractClass {
    @Override
    public void primitiveOperation1() {
        System.out.println("A类具体实现一");
    }

    @Override
    public void primitiveOperation2() {
        System.out.println("A类具体实现二");
    }
}

模板方法是通过把不变行为搬到父类(超类),去除子类中重复代码来体现它的优势。

模板方法是提供了一个代码复用平台。

当不变的和可变行为在方法的实现中混合在一起的时候,不变行为就会在类中重复出现。我们通过模板方法将这些行为搬移到单一的地方,这样帮助子类摆脱重复的不变行为的纠缠。

外观模式

以一个股票买卖的例子来理解一下,现在有股票、国债、房产,买入卖出代码如下:

  • 股票
// 股票1
public class Stock1 {
    public void buy() {
        System.out.println("股票1买入");
    }
    public void sell() {
        System.out.println("股票1卖出");
    }
}
// 股票2
class Stock2 {
    public void buy() {
        System.out.println("股票2买入");
    }
    public void sell() {
        System.out.println("股票2卖出");
    }
}
  • 国债、房产
// 国债1
public class NationalDebt1 {
    public void buy() {
        System.out.println("国债买入");
    }
    public void sell() {
        System.out.println("国债卖出");
    }
}

// 房产
class Realty1 {
    public void buy() {
        System.out.println("房产买入");
    }
    public void sell() {
        System.out.println("房产卖出");
    }
}
  • 客户端
Stock1 stock1 = new Stock1();
Stock2 stock2 = new Stock2();
NationalDebt1 nd1 = new NationalDebt1();
Realty1 rt1 = new Realty1();

// 买入
stock1.buy();
stock2.buy();
nd1.buy();
rt1.buy();

// 卖出
stock1.sell();
stock2.sell();
nd1.sell();
rt1.sell();

外观模式

增加一个基金类,结构图

在这里插入图片描述

  • 基金类代码
public class Fund {
    Stock1 stock1;
    Stock2 stock2;
    NationalDebt1 nd1;
    Realty1 rt1;
    public Fund() {
        stock1 = new Stock1();
        stock2 = new Stock2();
        nd1 = new NationalDebt1();
        rt1 = new Realty1();
    }
    public void buyFund() {
        stock1.buy();
        stock2.buy();
        nd1.buy();
        rt1.buy();
    }
    public void sellFund() {
        stock1.sell();
        stock2.sell();
        nd1.sell();
        rt1.sell();
    }
    
}
  • 客户端
Fund fund = new Fund();
fund.buyFund();

fund.sellFund();

外观模式:为子系统中的一组接口提供一个一致的界面,此模式定义了一个高层接口,这个接口使得这一子系统更加容易使用。

首先在设计阶段,应该有意识将不同的两个层进行分离。其次,在开发阶段,子系统往往因为不断的重构演化而变得越来越复杂,增加外观模式可以提供一个简单的接口减少它们之间的依赖。

还可以在新系统中使用外观模式,创建一个Facade类(外观模式类),来提供设计粗糙或高复杂度的遗留代码的比较清晰简单的接口,让新系统与Facade对象交互,Facade与遗留代码交互完成复杂的工作。

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

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

相关文章

HIS医疗项目

文章目录 医疗项目简介HIS项目介绍HIS架构解析HIS业务流程图HIS项目架构图 HIS组件解析——服务支撑 内存设置为4G或以上部署NGINX服务部署web安装JDK部署Elasticsearch安装ik中文分词器 部署rabbitmq部署MySQL服务安装MySQL服务建库、授权用户导入数据 部署Redis测试Redis 部署…

vue3+vant 实现树状多选组件

vue3vant 实现树状多选组件 需求描述效果图代码父组件引用selectTree组件 tree组件数据格式 需求描述 移动端需要复刻Pc端如上图的功能组件,但vant无组件可用,所以自己封装一个。 效果图 代码 父组件引用 import TreeSelect from "/selectTree.vu…

车间ERP管理系统都有哪些?能带给企业什么好处

不同规模的制造企业有不同的管理模式和经营策略,而生产和销售等业务是这类企业较为核心的部门,其中车间的管理是生产过程管理的重点环节之一。 车间的管理工作涉及物料、班组、设备、工时评估、生产现场数据采集、派工单、退补料等环节,如何…

ARM 版 Kylin V10 部署 KubeSphere 3.4.0 不完全指南

前言 知识点 定级:入门级KubeKey 安装部署 ARM 版 KubeSphere 和 KubernetesARM 版麒麟 V10 安装部署 KubeSphere 和 Kubernetes 常见问题 实战服务器配置 (个人云上测试服务器) 主机名IPCPU内存系统盘数据盘用途ksp-master-1172.16.33.1681650200KubeSphere/k8…

vite vue3 配置pinia

准备 https://blog.csdn.net/qq_36437991/article/details/134474050 安装pinia 官网 yarn add piniasrc下新建store文件夹,该文件夹下新建index.ts import { createPinia } from "pinia"; const store createPinia(); export default store;修改ma…

【C++11】多线程库 {thread线程库,mutex互斥锁库,condition_variable条件变量库,atomic原子操作库}

在C11之前,涉及到多线程问题,都是和平台相关的,比如windows和linux下各有自己的接口,这使得代码的可移植性比较差。 //在C98标准下,实现可移植的多线程程序 —— 条件编译 #ifdef _WIN32CreateThread(); //在windows系…

腾讯云S5服务器4核8G配置价格表S5.LARGE8性能测评

腾讯云服务器4核8G配置优惠价格表,轻量应用服务器和CVM云服务器均有活动,云服务器CVM标准型S5实例4核8G配置价格15个月1437.3元,5年6490.44元,轻量应用服务器4核8G12M带宽一年446元、529元15个月,腾讯云百科txybk.com分…

【cpolar】Ubuntu本地快速搭建web小游戏网站,公网用户远程访问

🎥 个人主页:深鱼~🔥收录专栏:cpolar🌄欢迎 👍点赞✍评论⭐收藏 目录 前言 1. 本地环境服务搭建 2. 局域网测试访问 3. 内网穿透 3.1 ubuntu本地安装cpolar 3.2 创建隧道 3.3 测试公网访问 4. 配置…

二、程序员指南:数据平面开发套件

MEMPOOL库 内存池是固定大小对象的分配器。在DPDK中,它由名称标识,并使用环形结构来存储空闲对象。它提供一些其他可选服务,例如每个核心的对象缓存和一个对齐辅助工具,以确保对象填充以将它们均匀分布在所有DRAM或DDR3通道上。 …

三十分钟学会Hive

Hive的概念与运用 Hive 是一个构建在Hadoop 之上的数据分析工具(Hive 没有存储数据的能力,只有使用数据的能力),底层由 HDFS 来提供数据存储,可以将结构化的数据文件映射为一张数据库表,并且提供类似 SQL …

全球地表水数据集JRC Global Surface Water Mapping Layers v1.4

简介: JRC Global Surface Water Mapping Layers产品,是利用1984至2020年获取的landsat5、landsat7和landsat8的卫星影像,生成分辨率为30米的一套全球地表水覆盖的地图集。用户可以在全球尺度上按地区回溯某个时间上地表水分的变化情况。产品…

VS 将 localhost访问改为ip访问

项目场景: 使用vs进行本地调试时需要多人访问界面,使用ip访问报错 问题描述 vs通过ip访问报错 虚拟机或其它电脑不能正常打开 原因分析: 原因是vs访问规则默认是iis,固定默认启动地址是localhost 解决方案: 1.vs项目启动之后会出现这个 右…

BUUCTF [GXYCTF2019]佛系青年 1

BUUCTF:https://buuoj.cn/challenges 题目描述: 密文: 下载附件,解压得到ZIP压缩包。 解题思路: 1、压缩包内有一张png图片和一个txt文本,解压zip压缩包,解压出图片,但txt文本提示需要输入密…

Wireshark 截取指定端口海量包分析

有个应用要分析一下协议,但是8939,8940传输一下子几个G的数据,但是要分析的端口8939实际上只有几个MB最多,如果用wireshark有界面的程序一截取就会卡死,于是使用命令行方式,截取指定端口的 tshark -i &quo…

CentOS7 安装mysql8(离线安装)postgresql14(在线安装)

注:linux系统为vmware虚拟机,和真实工作环境可能有出入 引言 postgresql与mysql目前都是非常受人欢迎的两大数据库,其各有各的优势,初学者先使用简单一张图来说明两者区别 以上内容引用自https://zhuanlan.zhihu.com/p/64326848…

Java 类之 java.util.Properties

Java 类之 java.util.Properties 文章目录 Java 类之 java.util.Properties一、简介二、主要功能1、存储键值对2、读取文件与属性代码示例运行结果截图 3、设置属性并保存文件代码示例结果截图 4、遍历属性代码示例运行结果 关联博客:《基于 Java 列举和说明常用的外…

程序员如何把【知识体系化】

你好,我是田哥 最近有不少人找我聊如何准备面试,其中有个点是大家都无从下手的问题。 这个问题估计是困扰了很多人,最可怕的是都没有想到什么好点办法。 下面来说说个人的想法(仅供参考)。 我该怎么准备?这…

JDK1.8 新特性(二)【Stream 流】

前言 上节我们学了 lambda 表达式,很快我就在 Flink 的学习中用到了,我学的是 Java 版本的 Flink,一开始会以为代码会很复杂,但事实上 Flink 中很多地方都用到了 函数接口,这也让我们在编写 Flink 程序的时候可以使用 …

upload-labs关卡9(基于win特性data流绕过)通关思路

文章目录 前言一、靶场需要了解的知识1::$data是什么 二、靶场第九关通关思路1、看源码2、bp抓包修改后缀名3、检查是否成功上传 总结 前言 此文章只用于学习和反思巩固文件上传漏洞知识,禁止用于做非法攻击。注意靶场是可以练习的平台,不能随意去尚未授…

大模型之十二十-中英双语开源大语言模型选型

从ChatGPT火爆出圈到现在纷纷开源的大语言模型,众多出入门的学习者以及跃跃欲试的公司不得不面临的是开源大语言模型的选型问题。 基于开源商业许可的开源大语言模型可以极大的节省成本和加速业务迭代。 当前(2023年11月17日)开源的大语言模型如下&#…