Java:设计模式
文章目录
- 参考
- 简介
- 工厂模式
- 简单工厂模式
- 工厂方法模式
- 抽象工厂模式
- 总结
- 单例模式
- 预加载
- 懒加载
- 线程安全问题
- 策略模式
参考
知乎
简介
总体来说设计模式分为三类共23种。
创建型模式,共五种:工厂方法模式、抽象工厂模式、单例模式、建造者模式、原型模式。
结构型模式,共七种:适配器模式、装饰器模式、代理模式、外观模式、桥接模式、组合模式、享元模式。
行为型模式,共十一种:策略模式、模板方法模式、观察者模式、迭代子模式、责任链模式、命令模式、备忘录模式、状态模式、访问者模式、中介者模式、解释器模式。
工厂模式
简单工厂模式
定义了一个创建对象的类,由这个类来封装实例化对象的行为。
如下,Pizza工厂生产chesse pepper greek三种类型的pizza,所有创建pizza对象的行为都要通过SimplePizzaFactory这个类完成。
public class SimplePizzaFactory {public Pizza CreatePizza(String ordertype) {Pizza pizza = null;if (ordertype.equals("cheese")) {pizza = new CheesePizza();} else if (ordertype.equals("greek")) {pizza = new GreekPizza();} else if (ordertype.equals("pepper")) {pizza = new PepperPizza();}return pizza;}
}
工厂方法模式
简单工厂模式有一个问题是对象的创建依赖工厂类本身,如果要拓展程序必须对工厂类进行修改。
可以定义一个创建对象的抽象方法,并创建多个不同的工厂类实现该抽象方法,这样需要增加新功能时直接增加新的工厂类即可,如下。
// OrderPizza中的抽象方法
abstract Pizza createPizza();// 伦敦和纽约两个工厂实现抽象方法
public class LDOrderPizza extends OrderPizza {Pizza createPizza(String ordertype) {Pizza pizza = null;if (ordertype.equals("cheese")) {pizza = new LDCheesePizza();} else if (ordertype.equals("pepper")) {pizza = new LDPepperPizza();}return pizza;}
}
public class NYOrderPizza extends OrderPizza {Pizza createPizza(String ordertype) {Pizza pizza = null;if (ordertype.equals("cheese")) {pizza = new NYCheesePizza();} else if (ordertype.equals("pepper")) {pizza = new NYPepperPizza();}return pizza;}}
这个模式的好处是如果想增加功能,只需新增实现类即可。
抽象工厂模式
上述模式抽象程度仍不足,如客户想吃伦敦工厂的pizza,还需亲自调用伦敦工厂的createPizza方法。可以进一步优化,使用户只需传入自己的需求作为参数即可,不用亲自寻找不同的工厂。
点单方法如下,只需向固定的对象传入不同参数即可。
public class PizzaStroe {public static void main(String[] args) {OrderPizza mOrderPizza;mOrderPizza = new OrderPizza("London");}
}
抽象工厂的接口如下
public interface AbsFactory {Pizza CreatePizza(String ordertype) ;
}
工厂实现如下
public class LDFactory implements AbsFactory {@Overridepublic Pizza CreatePizza(String ordertype) {Pizza pizza = null;if ("cheese".equals(ordertype)) {pizza = new LDCheesePizza();} else if ("pepper".equals(ordertype)) {pizza = new LDPepperPizza();}return pizza;}
}
总结
简单工厂模式就是建立一个实例化对象的类,在该类中对多个对象实例化。工厂方法模式是定义了一个创建对象的抽象方法,由子类决定要实例化的类。这样做的好处是再有新的类型的对象需要实例化只要增加子类即可。抽象工厂模式定义了一个接口用于创建对象族,而无需明确指定具体类。抽象工厂也是把对象的实例化交给了子类,即支持拓展。同时提供给客户端接口,避免了用户直接操作子类工厂。
单例模式
确保一个类最多只有一个实例,并提供一个全局访问点。可以分为预加载和懒加载两种。
预加载
在使用单例对象之前先加载其到内存
public class PreloadSingleton {public static PreloadSingleton instance = new PreloadSingleton();//其他的类无法实例化单例类的对象private PreloadSingleton() {};public static PreloadSingleton getInstance() {return instance;}
}
懒加载
为了避免内存浪费,可以等用到该单例对象的时候再创建。
public class Singleton {private static Singleton instance=null;private Singleton(){};public static Singleton getInstance(){if(instance==null){instance=new Singleton();}return instance;}
}
线程安全问题
预加载可以保证线程安全,懒加载无法保证线程安全,因为if判断后执行代码是非原子性的,而且new操作内部也无法保证顺序性,因为创建一个对象分三步
memory=allocate();//1:初始化内存空间ctorInstance(memory);//2:初始化对象instance=memory();//3:设置instance指向刚分配的内存地址
jvm为了提高程序执行性能,会对没有依赖关系的代码进行重排序,上面2和3行代码可能被重新排序。我们用两个线程来说明线程是不安全的。线程A和线程B都创建对象。其中,A2和A3的重排序,将导致线程B在B1处判断出instance不为空,线程B接下来将访问instance引用的对象。此时,线程B将会访问到一个还未初始化的对象(线程不安全)。

可以使用synchronized关键字保证线程安全,如果在getInstance函数上加此关键字,那么无论有没有初始化实例都会影响其他线程的执行,出于性能考虑,把关键字加到if判空的语句块内,保证instance没有实例化时才加锁。然后还需使用volatile关键字保证对象实例化过程的顺序性。
public class Singleton {private static volatile Singleton instance = null;private Singleton() {};public static synchronized Singleton getInstance() {if (instance == null) {synchronized (instance) {if (instance == null) {instance = new Singleton();}}}return instance;}
}
策略模式
策略模式定义了一系列算法,并将每个算法封装起来,使得他们可以相互替换,且算法的变化不会影响到客户。

例:实现一个加减的功能类图如下

抽象策略角色定义如下
public interface Strategy {public int calc(int num1,int num2);
}
具体策略角色继承于抽象策略角色,分别实现了加减法。
public class AddStrategy implements Strategy {@Overridepublic int calc(int num1, int num2) {// TODO Auto-generated method stubreturn num1 + num2;}}
public class SubstractStrategy implements Strategy {@Overridepublic int calc(int num1, int num2) {// TODO Auto-generated method stubreturn num1 - num2;}
环境角色引用抽象角色给客户端调用
public class Environment {private Strategy strategy;public Environment(Strategy strategy) {this.strategy = strategy;}public int calculate(int a, int b) {return strategy.calc(a, b);}}
客户端调用环境角色完成计算
public class MainTest {public static void main(String[] args) {Environment environment=new Environment(new AddStrategy());int result=environment.calculate(20, 5);System.out.println(result);Environment environment1=new Environment(new SubstractStrategy());int result1=environment1.calculate(20, 5);System.out.println(result1);}}
相关文章:
Java:设计模式
文章目录 参考简介工厂模式简单工厂模式工厂方法模式抽象工厂模式总结 单例模式预加载懒加载线程安全问题 策略模式 参考 知乎 简介 总体来说设计模式分为三类共23种。 创建型模式,共五种:工厂方法模式、抽象工厂模式、单例模式、建造者模式、原型模…...
【链表】Leetcode 19. 删除链表的倒数第 N 个结点【中等】
删除链表的倒数第 N 个结点 给你一个链表,删除链表的倒数第 n 个结点,并且返回链表的头结点。 示例 1: 输入:head [1,2,3,4,5], n 2 输出:[1,2,3,5] 解题思路 1、使用快慢指针找到要删除节点的前一个节点。2、删…...
亚马逊认证考试系列 - 知识点 - 安全组简介
AWS安全组是一种虚拟防火墙,用于控制实例进出网络流量。安全组是一个实例级别的防火墙,可以定义哪些流量可以进入或离开特定的EC2实例。 功能:安全组可以用于限制特定类型的流量,如HTTP或SSH,允许特定IP地址范围的流量…...
同向双指针合集(力扣)
283. 移动零 代码 class Solution { public:void moveZeroes(vector<int>& nums) {int n nums.size();int l 0, r 0;while(r < n){if(nums[r]){swap(nums[l],nums[r]);l;}r;}} };209. 长度最小的子数组 代码 class Solution { public:int minSubArrayLen(i…...
G - Find a way
题目分析 1.双重bfs,遍历两个起点求最短路再计算总和即可 2.唯一的坑点在于对于一个KFC,两人中可能有一个到不了,所以还要对到不了的点距离做处理 #include <bits/stdc.h> using namespace std; using ll long long; const int N 220;struct pos…...
AJAX 02 案例、Bootstrap框架
AJAX 学习 AJAX 2 综合案例黑马 API01 图书管理Bootstrap 官网Bootstrap 弹框图书管理-渲染列表图书管理-添加图书图书管理-删除图书图书管理 - 编辑图书 02 图片上传03 更换图片04 个人信息设置信息渲染头像修改补充知识点:label扩大表单的范围 AJAX 2 综合案例 黑…...
SinoDB客户端工具dbaccess
类似Oracle的客户端工具sqlplus,Mysql的客户端工具mysql,SinoDB数据库也有自带的命令行客户端工具dbaccess。 dbaccess 识别用户输入,将用户输入的 SQL 语句打包发送给 SinoDB 数据库服务器执行,然后接收服务器的执行结果…...
postman学习
一、如何学习postman工具 1、下载和安装 Postman: 首先,从 Postman 官方网站(https://www.postman.com)下载并安装 Postman 应用程序。 2、了解基本概念: 在开始学习之前,了解一些基本概念,…...
【Linux】初识进程
目录 操作系统是什么 设计操作系统的目的 操作系统的定位 如何理解管理 管理的本质 管理的例子 计算机的管理概念图 操作系统管理逻辑的六字真言 系统调用和库函数的概念 进程 进程的概念 什么是PCB? PCB的主要内容 如何查看进程? 通过系统…...
有关Theano和PyTensor库
根据Github里面的介绍,PyTensor是源于Theano, Theano目前应该已经不再开发了,更新都是很多年前。 因此PyTensor在背景介绍中说 PyTensor is a fork of Aesara, which is a fork of Theano. Theano和PyTensor都是计算相关的库,可以…...
用 Open-Sora 高效创作视频,让创意触手可及
近年来,视频内容以爆炸式增长席卷了我们的生活。从短视频平台到直播带货,视频正成为人们获取信息和娱乐的主要方式。然而,传统视频制作流程往往耗时费力,对于普通用户来说门槛较高。 为了降低视频创作门槛,让更多人享…...
Git版本管理工具
前言: 本文记录学习使用 Git 版本管理工具的学习笔记,通过阅读参考链接中的博文和实际操作,快速的上手使用 Git 工具。 本文参考了引用链接博文里的内容。 引用: Git使用教程-配置管理 git reset详解-CSDN博客 3、Git使用不完全指南&am…...
微信小程序选择器picker的使用(省市区)
index.wxml picker中的 moderegion模式,这里同element中的select不同的是,不需要自己在绑定数据原,默认就包含了省市区的整体数据 <view class"section"><view class"section__title">省市区选择器</vie…...
std::shared_ptr与std::make_unique在类函数中的使用
在最近学习cartographer算法的时候,发现源码中大量的使用了std::shared_ptr与std::make_unique,对于这些东西之前不是很了解,为了更好的理解源代码,因此简单学习了一下这块内容的使用,在这里简单记个笔记。 std::shar…...
flutter 局部view更新,dialog更新进度,dialog更新
局部更新有好几种方法,本次使用的是 StatefulBuilder 定义 customState去更新对话框内容 import package:flutter/cupertino.dart; import package:flutter/material.dart;class ProgressDialog {final BuildContext context;BuildContext? dialogContext;double _…...
Lombok:@Delegate优化代码利器
提示:文章写完后,目录可以自动生成,如何生成可参考右边的帮助文档 目录 一、Delegate介绍 二、示例 三、使用场景 四、使用注意事项 总结 提示:以下是本篇文章正文内容,下面案例可供参考 一、Delegate介绍 Dele…...
【C语言】对称密码——栅栏的加密和解密
栅栏密码的原理: 栅栏层数n ①把将要传递的信息中的字母交替排成上下n行。 ②再将下面每一行字母排依次在上面一行的后边,从而形成一段密码。 ③例如:栅栏层数为2 明文:THE LONGEST DAY MUST HAVE AN END 加密: …...
一、rv1126开发之视频输入和视频编码
RV1126 H264/HEVC编码流程 一、RV1126编码的流程图: 二、每个代码模块详细讲解 2.1. VI模块的创建 VI模块的初始化:关键在于VI_CHN_ATTR_S结构体,这个结构体是VI设置的结构体。这个结构体的成员变量包括:pcVideoNode࿰…...
4.1 用源文件写汇编代码
汇编语言 1. 源程序 1.1 伪指令 汇编指令是有对应的机器码的指令,可以被编译为机器指令,最终为CPU所执行伪指令没有对应的机器指令,最终不被CPU所执行伪指令是由编译器来执行的指令,编译器根据伪指令来进行相关的编译工作 1.2…...
Linux TCP参数——tcp_abort_on_overflow
文章目录 tcp_abort_on_overflow全连接队列是什么?如何改变队列大小?内核源码流程命令查看总结 tcp_abort_on_overflow 英文翻译理解:溢出中止 所以,溢出指的是什么溢出? Linux中会维护socket全连接队列,所…...
终极免费QQ音乐QMC解码器:3分钟解锁加密音乐,实现跨平台播放自由
终极免费QQ音乐QMC解码器:3分钟解锁加密音乐,实现跨平台播放自由 【免费下载链接】qmc-decoder Fastest & best convert qmc 2 mp3 | flac tools 项目地址: https://gitcode.com/gh_mirrors/qm/qmc-decoder 还在为QQ音乐下载的加密音乐文件无…...
从零构建数控BUCK电源:基于STC32G的HSPWM与PID双环控制实战
1. 项目背景与核心需求 当你需要一款能够精确控制输出电压和电流的电源时,市面上的成品往往难以满足定制化需求。这就是为什么我们要用STC32G单片机打造一个数控BUCK电源——它不仅能实现0.01V精度的电压调节,还能在恒流模式下稳定输出最高6A电流。我去年…...
通义千问1.5-1.8B-Chat-GPTQ-Int4在运维自动化中的智能监控方案
通义千问1.5-1.8B-Chat-GPTQ-Int4:让服务器监控“开口说话”的智能运维新方案 想象一下这个场景:凌晨三点,你的手机被监控告警的短信轰炸。你睡眼惺忪地爬起来,面对屏幕上瀑布般滚动的日志,试图从成千上万行信息里找出…...
从流量包到Flag:一次CTF Misc挑战中的Python加密流量逆向实战
1. 初识CTF流量分析题 第一次接触CTF Misc类题目时,面对pcap流量包总有种无从下手的感觉。记得那次攻防世界的比赛,题目给了一个名为xxx.pcap的文件,打开Wireshark一看,满屏的TCP和HTTP流量让人眼花缭乱。当时我尝试用http.reques…...
Shadcn-Vue深度解析:为什么这个开源组件库正在改变Vue开发者的工作方式?
Shadcn-Vue深度解析:为什么这个开源组件库正在改变Vue开发者的工作方式? 【免费下载链接】shadcn-vue Vue port of shadcn-ui 项目地址: https://gitcode.com/gh_mirrors/sh/shadcn-vue 在当今快速发展的前端生态中,Vue开发者面临着组…...
软考中项备考干货|学长亲测:零基础也能稳过的高效方法
作为过来人社长,真心跟大家说一句:软考中项真的不是靠死记硬背熬出来的!它在 IT 类资格证里,属于门槛友好、通过率稳、实用性强的考试,不考复杂代码和高深算法,重点考项目管理思维和核心考点记忆。很多同学…...
Kali下BeEF-XSS安装全攻略:从源配置到问题解决
1. 为什么选择BeEF-XSS? 如果你正在学习网络安全或者对渗透测试感兴趣,BeEF-XSS绝对是一个绕不开的神器。简单来说,它就像是一个浏览器漏洞的指挥中心,能够通过XSS漏洞控制受害者的浏览器。想象一下,你可以在对方不知情…...
Windows音频采集进阶:利用WASAPI事件驱动与Loopback模式抓取系统声音
Windows音频采集进阶:WASAPI事件驱动与Loopback模式实战解析 1. 系统音频采集的技术挑战与解决方案 在开发屏幕录制工具、游戏直播系统或会议录音软件时,可靠捕获系统音频流是核心需求。传统麦克风采集无法满足这类场景,而直接访问声卡驱动又…...
iOS客户端应用开发深度解析:基于Flutter和Swift的技术实践
在移动应用开发领域,iOS平台因其高性能、安全性和用户体验而备受青睐。随着跨平台框架的兴起,Flutter和Swift成为开发iOS应用的核心工具。本文基于iOS客户端应用开发的职位描述,深入探讨Flutter和Swift在iOS开发中的应用、iOS核心原理(如消息机制、内存管理、UI渲染、多线程…...
5分钟搞定网盘直链下载:八大平台一键解析全攻略
5分钟搞定网盘直链下载:八大平台一键解析全攻略 【免费下载链接】Online-disk-direct-link-download-assistant 一个基于 JavaScript 的网盘文件下载地址获取工具。基于【网盘直链下载助手】修改 ,支持 百度网盘 / 阿里云盘 / 中国移动云盘 / 天翼云盘 /…...
