Java常用的设计模式,如单例模式、工厂模式、观察者模式等

设计模式是软件工程中的一种解决方案,用于应对常见的设计问题和挑战。它们提供了一种标准化的方式来解决设计难题,使代码更加灵活、可扩展和易于维护。

单例模式(Singleton Pattern)

概述

单例模式确保一个类只有一个实例,并提供一个全局访问点来访问这个实例。这在需要全局共享资源时非常有用,例如数据库连接池、配置管理器等。

实现

在Java中,实现单例模式有多种方式,以下是最常见的几种:

饿汉式(Eager Initialization)
public class Singleton {private static final Singleton instance = new Singleton();private Singleton() {// 私有构造函数,防止实例化}public static Singleton getInstance() {return instance;}
}

这种方法在类加载时就创建实例,线程安全,但如果实例过大且未被使用,会浪费资源。

懒汉式(Lazy Initialization)
public class Singleton {private static Singleton instance;private Singleton() {// 私有构造函数,防止实例化}public static synchronized Singleton getInstance() {if (instance == null) {instance = new Singleton();}return instance;}
}

这种方法在第一次调用时才创建实例,节省资源,但需要同步以确保线程安全。

双重检查锁(Double-Checked Locking)
public class Singleton {private static volatile Singleton instance;private Singleton() {// 私有构造函数,防止实例化}public static Singleton getInstance() {if (instance == null) {synchronized (Singleton.class) {if (instance == null) {instance = new Singleton();}}}return instance;}
}

这种方法结合了懒汉式的延迟加载和线程安全的优点。

静态内部类(Static Inner Class)
public class Singleton {private Singleton() {// 私有构造函数,防止实例化}private static class Holder {private static final Singleton INSTANCE = new Singleton();}public static Singleton getInstance() {return Holder.INSTANCE;}
}

这种方法利用类加载机制实现延迟加载,且线程安全。

工厂模式(Factory Pattern)

概述

工厂模式通过创建一个工厂类来处理对象的创建,提供了一种将实例化逻辑与使用逻辑分离的方式。常见的工厂模式有简单工厂模式、工厂方法模式和抽象工厂模式。

实现
简单工厂模式(Simple Factory Pattern)
public class SimpleFactory {public Product createProduct(String type) {if (type.equals("A")) {return new ProductA();} else if (type.equals("B")) {return new ProductB();}return null;}
}

这种方法通过一个工厂类创建不同类型的产品实例。

工厂方法模式(Factory Method Pattern)
public interface Product {void use();
}public class ProductA implements Product {public void use() {System.out.println("Using Product A");}
}public class ProductB implements Product {public void use() {System.out.println("Using Product B");}
}public abstract class Factory {public abstract Product createProduct();
}public class FactoryA extends Factory {public Product createProduct() {return new ProductA();}
}public class FactoryB extends Factory {public Product createProduct() {return new ProductB();}
}

这种方法通过定义一个抽象工厂接口和具体工厂类,提供了灵活的产品创建方式。

抽象工厂模式(Abstract Factory Pattern)
public interface AbstractFactory {ProductA createProductA();ProductB createProductB();
}public class ConcreteFactory1 implements AbstractFactory {public ProductA createProductA() {return new ProductA1();}public ProductB createProductB() {return new ProductB1();}
}public class ConcreteFactory2 implements AbstractFactory {public ProductA createProductA() {return new ProductA2();}public ProductB createProductB() {return new ProductB2();}
}

这种方法提供了创建一系列相关或依赖对象的接口,而无需指定它们的具体类。

观察者模式(Observer Pattern)

概述

观察者模式定义了一种一对多的依赖关系,让多个观察者对象同时监听某一个主题对象。当主题对象发生变化时,它会通知所有观察者,使它们能够自动更新。

实现
import java.util.ArrayList;
import java.util.List;public interface Observer {void update(String message);
}public class ConcreteObserver implements Observer {private String name;public ConcreteObserver(String name) {this.name = name;}public void update(String message) {System.out.println(name + " received message: " + message);}
}public interface Subject {void attach(Observer observer);void detach(Observer observer);void notifyObservers();
}public class ConcreteSubject implements Subject {private List<Observer> observers = new ArrayList<>();private String message;public void attach(Observer observer) {observers.add(observer);}public void detach(Observer observer) {observers.remove(observer);}public void notifyObservers() {for (Observer observer : observers) {observer.update(message);}}public void setMessage(String message) {this.message = message;notifyObservers();}
}

这种方法通过定义主题和观察者接口,确保观察者可以被通知到主题的任何变化。

其他常见设计模式

适配器模式(Adapter Pattern)

适配器模式将一个类的接口转换成客户希望的另一个接口,使原本接口不兼容的类可以一起工作。

public interface Target {void request();
}public class Adaptee {public void specificRequest() {System.out.println("Specific request");}
}public class Adapter implements Target {private Adaptee adaptee;public Adapter(Adaptee adaptee) {this.adaptee = adaptee;}public void request() {adaptee.specificRequest();}
}
装饰器模式(Decorator Pattern)

装饰器模式动态地给对象添加一些额外的职责。相比生成子类,更加灵活。

public interface Component {void operation();
}public class ConcreteComponent implements Component {public void operation() {System.out.println("ConcreteComponent operation");}
}public abstract class Decorator implements Component {protected Component component;public Decorator(Component component) {this.component = component;}public void operation() {component.operation();}
}public class ConcreteDecorator extends Decorator {public ConcreteDecorator(Component component) {super(component);}public void operation() {super.operation();additionalOperation();}private void additionalOperation() {System.out.println("Additional operation");}
}
策略模式(Strategy Pattern)

策略模式定义了一系列算法,并将每个算法封装起来,使它们可以相互替换,客户端可以选择不同的算法实现。

public interface Strategy {void execute();
}public class ConcreteStrategyA implements Strategy {public void execute() {System.out.println("Strategy A executed");}
}public class ConcreteStrategyB implements Strategy {public void execute() {System.out.println("Strategy B executed");}
}public class Context {private Strategy strategy;public Context(Strategy strategy) {this.strategy = strategy;}public void executeStrategy() {strategy.execute();}
}
外观模式(Facade Pattern)

外观模式为一组复杂的子系统提供一个更高级的统一接口,使子系统更容易使用。

public class SubsystemA {public void operationA() {System.out.println("Subsystem A operation");}
}public class SubsystemB {public void operationB() {System.out.println("Subsystem B operation");}
}public class Facade {private SubsystemA subsystemA;private SubsystemB subsystemB;public Facade() {subsystemA = new SubsystemA();subsystemB = new SubsystemB();}public void operation() {subsystemA.operationA();subsystemB.operationB();}
}
模板方法模式(Template Method Pattern)

模板方法模式在一个方法中定义一个算法的骨架,而将一些步骤延迟到子类中实现,使得子类可以不改变算法结构的情况下重新定义算法的某些步骤。

public abstract class AbstractClass {public final void templateMethod() {primitiveOperation1();primitiveOperation2();concreteOperation();}protected abstract void primitiveOperation1();protected abstract void primitiveOperation2();private void concreteOperation() {System.out.println("Concrete operation");}
}public class ConcreteClass extends AbstractClass {protected void primitiveOperation1() {System.out.println("Primitive operation 1");}protected void primitiveOperation2() {System.out.println("Primitive operation 2");}
}

设计模式是软件开发中的重要工具,能够显著提高代码的可维护性、灵活性和可扩展性。掌握这些模式并灵活应用,可以帮助开发者更好地设计和构建高质量的软件系统。

黑马程序员免费预约咨询

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

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

相关文章

Java——LinkedList

1、链表 1.1 链表的概念及结构 链表在逻辑层面上是连续的&#xff0c;在物理层面上不一定是连续的 链表结构可分为&#xff0c;单向或双向、带头或不带头、循环或非循环&#xff0c;组合共计8种 重点&#xff1a;无头单向非循环链表、无头双向链表 1.2 模拟实现无头单向非…

拥抱开源,构建未来:王嘉树与 TDengine 的开源之旅

在当代的技术浪潮中&#xff0c;开源文化不仅催生了无数创新技术&#xff0c;也为广大技术爱好者提供了一个展示才华、相互学习的平台。我们今天采访到的这位北京邮电大学电子工程学院的研究生&#xff0c;就是在这样的背景下&#xff0c;通过开源活动不断探索、学习并实现自我…

数据分析常用6种分析思路(下)

作为一名数据分析师&#xff0c;你又没有发现&#xff0c;自己经常碰到一些棘手的问题就没有思路&#xff0c;甚至怀疑自己究竟有没有好好学过分析&#xff1f; 在上篇文章里&#xff0c;我们讲到了数据分析中的流程、分类、对比三大块&#xff0c;今天&#xff0c;我们继续讲…

【ElasticSearch】windows server 2019安装ES8.9.1 + kibana8.9.1 + IK分词器

目录 准备工作 ES Kibana IK 安装 es es访问测试 将es安装为系统服务 Kibana 配置es 运行kibana 访问测试 IK 补充 准备工作 ES8.9.1 kibana8.9.1 IK的版本最好要对应上&#xff01;&#xff01;&#xff01; ES es8.9.1&#xff1a; https://artifa…

笔记 | 用go写个docker

仅作为自己学习过程的记录&#xff0c;不具备参考价值 前言 看到一段非常有意思的话&#xff1a; 很多人刚接触docker的时候就会感觉非常神奇&#xff0c;感觉这个技术非常新颖&#xff0c;其实并不然&#xff0c;docker使用到的技术都是之前已经存在过的&#xff0c;只不过旧…

操作系统——信号

将信号分为以上四个阶段 1.信号注册&#xff1a;是针对信号处理方式的规定&#xff0c;进程收到信号时有三种处理方式&#xff1a;默认动作&#xff0c;忽略&#xff0c;自定义动作。如果不是自定义动作&#xff0c;这一步可以忽略。这个步骤要使用到signal/sigaction接口 2.…

5. 条件和递归

5. 条件和递归 本章主要话题是if表达式, 它根据程序的状态执行不同的代码. 但首先介绍两个操作符号: 向下取整除法操作符和求模操作符.5.1 向下取整除法操作符和求模操作符 向下取整除法操作符(//)对两个数除法运算, 并向下取整得到一个整数. 假设, 一个电影的播放时长为105分…

Java | Leetcode Java题解之第150题逆波兰表达式求值

题目&#xff1a; 题解&#xff1a; class Solution {public int evalRPN(String[] tokens) {int n tokens.length;int[] stack new int[(n 1) / 2];int index -1;for (int i 0; i < n; i) {String token tokens[i];switch (token) {case "":index--;stack…

vi/vim使用命令

你是否在编辑文件时以为键盘坏了&#xff0c;为什么不能删除呢&#xff0c;为什么不能敲代码呢&#xff0c;等你初识vi&#xff0c;会觉得这个东西为什么设计得这么难用&#xff0c;这篇教程带你熟练得用上这款经典的工具 Vi 是在 Unix 系统上广泛使用的编辑器&#xff0c;Vim …

Unity与Js通信交互

目录 1.Js给Unity传递消息 2.Unity给Js传递消息 简介: Unity 与 JavaScript 通信交互是指在 Unity 项目中实现与 JavaScript 代码进行数据交换和功能调用的过程。 在 Unity 中&#xff0c;可以通过特定的接口和技术来与外部的 JavaScript 环境进行连接。这使得 Unity 能够利…

进击算法工程师深度学习课程

"进击算法工程师深度学习课程"旨在培养学员在深度学习领域的专业技能和实战经验。课程涵盖深度学习基础理论、神经网络架构、模型优化方法等内容&#xff0c;通过项目实践和算法实现&#xff0c;帮助学员掌握深度学习算法原理和应用&#xff0c;提升在算法工程师领域…

EasyExcel文件导出,出现有文件但没有数据的问题

一开始由于JDK版本过高&#xff0c;我用的17&#xff0c;一直excel没有数据&#xff0c;表头也没有&#xff0c;后来摸索了好久&#xff0c;找了资料也没有&#xff0c;后来改了代码后报了一个错误&#xff08;com.alibaba.excel.exception.ExcelGenerateException: java.lang.…

【抽代复习笔记】19-群(十三):奇偶置换、循环置换的几个定理及例题

定义&#xff1a; ①在Sn中&#xff0c;能够表示为奇数多个对换乘积的置换称为“奇置换”&#xff0c;能够表示为偶数多个对换乘积的置换称为“偶置换”&#xff1b; ②所有偶置换的集合记为An。 例1&#xff1a;&#xff08;1&#xff09;计算S1和S2中奇、偶置换的数目&…

数据中台-知识图谱平台

【数据分析小兵】专注数据中台产品领域,覆盖开发套件,包含数据集成、数据建模、数据开发、数据服务、数据可视化、数据治理相关产品以及相关行业的技术方案的分享。对数据中台产品想要体验、做二次开发、关注方案资料、做技术交流的朋友们&#xff0c;可以关注我。 1. 概述 随着…

ResNet——Deep Residual Learning for Image Recognition(论文阅读)

1.什么是ResNet ResNet是一种残差网络&#xff0c;咱们可以把它理解为一个子网络&#xff0c;这个子网络经过堆叠可以构成一个很深的网络。下面是ResNet的结构。 2.为什么要引入ResNet 理论上来说&#xff0c;堆叠神经网络的层数应该可以提升模型的精度。但是现实中真的是这…

智慧守护 畅游无忧——北斗应急呼叫柱,为景区安全加码

在大自然的怀抱中&#xff0c;中型及大型公园、景区以其壮丽风光吸引着成千上万的游客前来探索&#xff0c;成为了人们休闲娱乐的好去处。然而&#xff0c;广袤的区域、复杂的地形和分散的人流也给安全保障带来了前所未有的挑战。传统的巡逻方式难以覆盖每一个角落&#xff0c;…

【第六篇】SpringSecurity的权限管理

一、权限管理的实现 服务端的各种资源要被SpringSecurity的权限管理控制可以通过注解和标签两种方式来处理。 放开了相关的注解后在Controller中就可以使用相关的注解来控制了 JSR250注解 /*** JSR250*/ @Controller @RequestMapping("/user") public class UserC…

物理隔离后数据怎么导入和导出?安全U盘一键解决

政府单位、军工和科研所、航空航天企业、金融机构、医疗单位、电力企业、生物制药实验室等企业及单位&#xff0c;因研发和生产过程、或日常经营中涉及大量敏感信息和技术&#xff0c;需要通过物理隔离来确保网络的安全性。因此&#xff0c;多采用物理隔离的方式进行网络建设。…

前端 CSS 经典:在 Vue3 中使用渐进式图片

1. 什么是渐进式图片 当我们网站会加载很多图片的时候&#xff0c;有些图片尺寸很大&#xff0c;加载就会很慢&#xff0c;会导致页面长时间陷入白屏状态&#xff0c;用户体验很不好。所以可以使用渐进式图片&#xff0c;先给用户展示模糊图&#xff0c;这些图尺寸小&#xff…

django学习入门系列之第二点《浏览器能识别的标签3》

文章目录 列表表格往期回顾 列表 无序列表 <!-- <ul </ul> 无序列表 --> <ul><li> 内容1 </li><li> 内容2 </li><li> 内容3 </li><li> 内容4 </li> </ul>有序列表 <!-- <ol> &…