深入理解Java的设计模式

news/2024/9/23 14:35:24/

设计模式(Design Patterns)是软件开发中的宝贵经验总结,提供了解决常见设计问题的模板和最佳实践。在Java开发中,设计模式尤为重要,因为它们能够提高代码的可维护性、可扩展性和可重用性。本篇博客将详细介绍几种常见的设计模式,帮助读者掌握如何在Java开发中应用这些模式。

什么是设计模式

设计模式是软件设计中反复出现的解决方案。它们不是具体的代码,而是关于如何解决某一类型问题的一般性描述。设计模式通常分为三大类:

  1. 创建型模式:关注对象的创建方式。
  2. 结构型模式:关注类和对象的组合。
  3. 行为型模式:关注类和对象之间的交互。

创建型模式

单例模式(Singleton Pattern)

单例模式确保一个类只有一个实例,并提供一个全局访问点。单例模式在需要控制资源的唯一性时非常有用,例如数据库连接、线程池等。

java">public class Singleton {private static Singleton instance;private Singleton() {// 私有构造函数,防止外部实例化}public static Singleton getInstance() {if (instance == null) {instance = new Singleton();}return instance;}
}
优点
  • 控制实例数量,节省资源。
  • 提供全局访问点。
缺点
  • 多线程环境下需要考虑同步问题。
  • 可能违背单一职责原则,因为类既要管理实例的创建,又要执行其他任务。

工厂模式(Factory Pattern)

工厂模式通过定义一个创建对象的接口来实现对象的实例化,而不是直接通过new操作符。这样可以使得创建过程与使用过程分离。

java">interface Shape {void draw();
}class Circle implements Shape {@Overridepublic void draw() {System.out.println("Drawing a Circle");}
}class Square implements Shape {@Overridepublic void draw() {System.out.println("Drawing a Square");}
}class ShapeFactory {public Shape getShape(String shapeType) {if (shapeType == null) {return null;}if (shapeType.equalsIgnoreCase("CIRCLE")) {return new Circle();} else if (shapeType.equalsIgnoreCase("SQUARE")) {return new Square();}return null;}
}
优点
  • 封装创建逻辑,代码更简洁。
  • 易于扩展,增加新类型无需修改现有代码。
缺点
  • 增加了系统的复杂性,需要更多的类和接口。

结构型模式

适配器模式(Adapter Pattern)

适配器模式将一个类的接口转换成客户端期望的另一个接口,使得原本由于接口不兼容而不能一起工作的类可以协同工作。

java">interface MediaPlayer {void play(String audioType, String fileName);
}class AudioPlayer implements MediaPlayer {@Overridepublic void play(String audioType, String fileName) {if (audioType.equalsIgnoreCase("mp3")) {System.out.println("Playing mp3 file. Name: " + fileName);}}
}interface AdvancedMediaPlayer {void playVlc(String fileName);void playMp4(String fileName);
}class VlcPlayer implements AdvancedMediaPlayer {@Overridepublic void playVlc(String fileName) {System.out.println("Playing vlc file. Name: " + fileName);}@Overridepublic void playMp4(String fileName) {// do nothing}
}class Mp4Player implements AdvancedMediaPlayer {@Overridepublic void playVlc(String fileName) {// do nothing}@Overridepublic void playMp4(String fileName) {System.out.println("Playing mp4 file. Name: " + fileName);}
}class MediaAdapter implements MediaPlayer {AdvancedMediaPlayer advancedMusicPlayer;public MediaAdapter(String audioType) {if (audioType.equalsIgnoreCase("vlc")) {advancedMusicPlayer = new VlcPlayer();} else if (audioType.equalsIgnoreCase("mp4")) {advancedMusicPlayer = new Mp4Player();}}@Overridepublic void play(String audioType, String fileName) {if (audioType.equalsIgnoreCase("vlc")) {advancedMusicPlayer.playVlc(fileName);} else if (audioType.equalsIgnoreCase("mp4")) {advancedMusicPlayer.playMp4(fileName);}}
}class AudioPlayerAdapter implements MediaPlayer {MediaAdapter mediaAdapter;@Overridepublic void play(String audioType, String fileName) {if (audioType.equalsIgnoreCase("mp3")) {System.out.println("Playing mp3 file. Name: " + fileName);} else if (audioType.equalsIgnoreCase("vlc") || audioType.equalsIgnoreCase("mp4")) {mediaAdapter = new MediaAdapter(audioType);mediaAdapter.play(audioType, fileName);} else {System.out.println("Invalid media. " + audioType + " format not supported");}}
}
优点
  • 解耦客户端与服务端接口。
  • 增强代码的复用性。
缺点
  • 增加代码复杂性。
  • 可能导致过多的适配器类。

装饰者模式(Decorator Pattern)

装饰者模式通过将对象放入包含行为的特殊封装对象中来动态地扩展对象的功能。

java">interface Shape {void draw();
}class Rectangle implements Shape {@Overridepublic void draw() {System.out.println("Shape: Rectangle");}
}abstract class ShapeDecorator implements Shape {protected Shape decoratedShape;public ShapeDecorator(Shape decoratedShape) {this.decoratedShape = decoratedShape;}public void draw() {decoratedShape.draw();}
}class RedShapeDecorator extends ShapeDecorator {public RedShapeDecorator(Shape decoratedShape) {super(decoratedShape);}@Overridepublic void draw() {decoratedShape.draw();setRedBorder(decoratedShape);}private void setRedBorder(Shape decoratedShape) {System.out.println("Border Color: Red");}
}public class DecoratorPatternDemo {public static void main(String[] args) {Shape rectangle = new Rectangle();Shape redRectangle = new RedShapeDecorator(new Rectangle());System.out.println("Rectangle with normal border");rectangle.draw();System.out.println("\nRectangle with red border");redRectangle.draw();}
}
优点
  • 动态扩展对象功能。
  • 避免使用继承扩展类功能。
缺点
  • 增加了许多小对象,复杂度提高。
  • 不容易调试。

行为型模式

策略模式(Strategy Pattern)

策略模式定义了一系列算法,并将每个算法封装起来,使它们可以相互替换。策略模式让算法独立于使用它的客户端。

java">interface Strategy {int doOperation(int num1, int num2);
}class OperationAdd implements Strategy {@Overridepublic int doOperation(int num1, int num2) {return num1 + num2;}
}class OperationSubtract implements Strategy {@Overridepublic int doOperation(int num1, int num2) {return num1 - num2;}
}class OperationMultiply implements Strategy {@Overridepublic int doOperation(int num1, int num2) {return num1 * num2;}
}class Context {private Strategy strategy;public Context(Strategy strategy) {this.strategy = strategy;}public int executeStrategy(int num1, int num2) {return strategy.doOperation(num1, num2);}
}public class StrategyPatternDemo {public static void main(String[] args) {Context context = new Context(new OperationAdd());System.out.println("10 + 5 = " + context.executeStrategy(10, 5));context = new Context(new OperationSubtract());System.out.println("10 - 5 = " + context.executeStrategy(10, 5));context = new Context(new OperationMultiply());System.out.println("10 * 5 = " + context.executeStrategy(10, 5));}
}
优点
  • 算法可自由切换。
  • 避免使用多重条件判断语句。
  • 提高算法的扩展性。
缺点
  • 客户端必须知道所有策略类,并自行决定使用哪一个策略类。
  • 策略模式会增加系统中类的数量。

观察者模式(Observer Pattern)

观察者模式定义了对象间的一对多依赖关系,当一个对象改变状态时,其所有依赖者都会收到通知并自动更新。

java">import java.util.ArrayList;
import java.util.List;class Subject {private List<Observer> observers = new ArrayList<>();private int state;public int getState() {return state;}public void setState(int


http://www.ppmy.cn/news/1466100.html

相关文章

如何高效管理团队任务?强大的在线管理团队多任务的神器-YesDev

任务是最小的工作项&#xff0c;工时是可以对研发产能进行量化。 一员工工时 工作组工时登记配置 针对于工作组&#xff0c;你可以开启/关闭工时登记。关闭工作组的工时登记后&#xff0c;整个工作组将取消工时登记&#xff0c;重新开启后恢复。 在同一个工作组内&#xff0c…

R语言 | 安装ggpubr R包时编译语句中出现 WARNING: ignoring environment value of R_HOME 而报错

在安装 ggpubr 时&#xff0c;出现报错。 1. 环境介绍 系统&#xff1a;CentOS7.9 $ R --version R version 4.3.2 (2023-10-31) – “Eye Holes” $ gcc --version gcc (GCC) 12.3.0 2. 缺少cmake $ sudo yum install cmake3> system("/usr/bin/cmake3 --versio…

MongoDB CRUD操作:插入文档

MongoDB CRUD操作&#xff1a;插入文档 文章目录 MongoDB CRUD操作&#xff1a;插入文档使用MongoDB Atlas UI插入文档插入单个文档插入多个文档插入行为自动创建集合_id字段原子性写确认 在MongoDB中插入文档的集中方式&#xff1a; 使用编程语言提供的驱动程序&#xff0c;在…

milvus索引

Milvus是一个开源的向量数据库引擎&#xff0c;旨在支持大规模向量相似度搜索和分析。索引在Milvus中扮演着非常重要的角色&#xff0c;它们用于加速向量数据的检索。下面详细介绍一下Milvus中的索引&#xff1a; 1. 索引类型 Milvus支持多种索引类型&#xff0c;每种类型都适…

脑图工具 在学习系统架构中的使用

系统&#xff0c;有人把它比作一个黑盒&#xff0c;有人比作一个树洞。呃&#xff0c;其实二者都隐含的表达了一个意思&#xff0c;盘根错节&#xff0c;一言难尽&#xff0c;欲说还休&#xff0c;说了又像是隔靴搔痒&#xff0c;感觉没说透。 学习&#xff0c;理解和展示一个…

如何让 LightRoom 每次导入照片后不自动弹出 SD 卡 LR

如何让 LightRoom 每次导入照片后不自动弹出 SD 卡 LR 在导入窗口左上角有个选项&#xff1a; 导入后弹出 把这个去掉就可以了

Python爬虫实战(实战篇)—16获取【百度热搜】数据—写入Ecel(附完整代码)

文章目录 专栏导读背景结果预览1、爬取页面分析2、通过返回数据发现适合利用lxmlxpath3、继续分析【小说榜、电影榜、电视剧榜、汽车榜、游戏榜】4、完整代码总结 专栏导读 &#x1f525;&#x1f525;本文已收录于《Python基础篇爬虫》 &#x1f251;&#x1f251;本专栏专门…

计算机网络——TCP / IP 网络模型

OSI 七层模型 七层模型是国际标准化的一个网络分层模型&#xff0c;大体结构可以分成七层。每层提供不同的功能。 图片来源 JavaGuide 但是这样七层结构比较复杂&#xff0c;不太实用&#xff0c;所以有了 TCP / IP 模型。 TCP / IP 网络模型 TCP / IP 网络模型可以看作是 O…