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全连接队列,所…...

JavaSec-RCE
简介 RCE(Remote Code Execution),可以分为:命令注入(Command Injection)、代码注入(Code Injection) 代码注入 1.漏洞场景:Groovy代码注入 Groovy是一种基于JVM的动态语言,语法简洁,支持闭包、动态类型和Java互操作性,…...

调用支付宝接口响应40004 SYSTEM_ERROR问题排查
在对接支付宝API的时候,遇到了一些问题,记录一下排查过程。 Body:{"datadigital_fincloud_generalsaas_face_certify_initialize_response":{"msg":"Business Failed","code":"40004","sub_msg…...

微软PowerBI考试 PL300-选择 Power BI 模型框架【附练习数据】
微软PowerBI考试 PL300-选择 Power BI 模型框架 20 多年来,Microsoft 持续对企业商业智能 (BI) 进行大量投资。 Azure Analysis Services (AAS) 和 SQL Server Analysis Services (SSAS) 基于无数企业使用的成熟的 BI 数据建模技术。 同样的技术也是 Power BI 数据…...
Objective-C常用命名规范总结
【OC】常用命名规范总结 文章目录 【OC】常用命名规范总结1.类名(Class Name)2.协议名(Protocol Name)3.方法名(Method Name)4.属性名(Property Name)5.局部变量/实例变量(Local / Instance Variables&…...

页面渲染流程与性能优化
页面渲染流程与性能优化详解(完整版) 一、现代浏览器渲染流程(详细说明) 1. 构建DOM树 浏览器接收到HTML文档后,会逐步解析并构建DOM(Document Object Model)树。具体过程如下: (…...

WordPress插件:AI多语言写作与智能配图、免费AI模型、SEO文章生成
厌倦手动写WordPress文章?AI自动生成,效率提升10倍! 支持多语言、自动配图、定时发布,让内容创作更轻松! AI内容生成 → 不想每天写文章?AI一键生成高质量内容!多语言支持 → 跨境电商必备&am…...

IT供电系统绝缘监测及故障定位解决方案
随着新能源的快速发展,光伏电站、储能系统及充电设备已广泛应用于现代能源网络。在光伏领域,IT供电系统凭借其持续供电性好、安全性高等优势成为光伏首选,但在长期运行中,例如老化、潮湿、隐裂、机械损伤等问题会影响光伏板绝缘层…...

深度学习水论文:mamba+图像增强
🧀当前视觉领域对高效长序列建模需求激增,对Mamba图像增强这方向的研究自然也逐渐火热。原因在于其高效长程建模,以及动态计算优势,在图像质量提升和细节恢复方面有难以替代的作用。 🧀因此短时间内,就有不…...

【JVM】Java虚拟机(二)——垃圾回收
目录 一、如何判断对象可以回收 (一)引用计数法 (二)可达性分析算法 二、垃圾回收算法 (一)标记清除 (二)标记整理 (三)复制 (四ÿ…...

GO协程(Goroutine)问题总结
在使用Go语言来编写代码时,遇到的一些问题总结一下 [参考文档]:https://www.topgoer.com/%E5%B9%B6%E5%8F%91%E7%BC%96%E7%A8%8B/goroutine.html 1. main()函数默认的Goroutine 场景再现: 今天在看到这个教程的时候,在自己的电…...