JAVA:设计模式的详细指南

news2024/11/13 10:00:04

请关注微信公众号:拾荒的小海螺
博客地址:http://lsk-ww.cn/

1、简述

设计模式(Design Patterns)是一套被反复使用、多数人知晓的、经过分类编目的、代码设计经验的总结。它们可以帮助开发者以一种更优雅和高效的方式解决常见的软件设计问题。本文将介绍三种常见的设计模式,并通过Java代码示例展示它们的实际应用。

在这里插入图片描述

2、单例模式(Singleton Pattern)

单例模式确保一个类只有一个实例,并提供一个全局访问点。它常用于需要共享资源的场景,比如配置类、日志类等。

2.1 示例代码
public class Singleton {
    // 使用volatile关键字确保多线程环境下的可见性
    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;
    }

    public void showMessage() {
        System.out.println("Hello World from Singleton!");
    }
}
2.2 使用示例:
public class SingletonDemo {
    public static void main(String[] args) {
        Singleton singleInstance = Singleton.getInstance();
        singleInstance.showMessage();
    }
}

3、工厂模式(Factory Pattern)

工厂模式定义一个用于创建对象的接口,但由子类决定实例化哪一个类。它使得类的实例化延迟到子类。

3.1 示例代码:
// 产品接口
interface Shape {
    void draw();
}

// 具体产品类
class Circle implements Shape {
    public void draw() {
        System.out.println("Drawing a Circle");
    }
}

class Square implements Shape {
    public 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;
    }
}
3.2 使用示例:
public class FactoryPatternDemo {
    public static void main(String[] args) {
        ShapeFactory shapeFactory = new ShapeFactory();

        // 获取Circle对象并调用draw方法
        Shape shape1 = shapeFactory.getShape("CIRCLE");
        shape1.draw();

        // 获取Square对象并调用draw方法
        Shape shape2 = shapeFactory.getShape("SQUARE");
        shape2.draw();
    }
}

4、观察者模式(Observer Pattern)

观察者模式定义对象间的一种一对多的依赖关系,使得每当一个对象改变状态,则所有依赖于它的对象都会得到通知并被自动更新。它常用于实现事件处理系统。

4.1 示例代码:
import java.util.ArrayList;
import java.util.List;

// 观察者接口
interface Observer {
    void update(String message);
}

// 被观察者类
class Subject {
    private List<Observer> observers = new ArrayList<>();

    public void attach(Observer observer) {
        observers.add(observer);
    }

    public void detach(Observer observer) {
        observers.remove(observer);
    }

    public void notifyObservers(String message) {
        for (Observer observer : observers) {
            observer.update(message);
        }
    }
}

// 具体观察者类
class ConcreteObserver implements Observer {
    private String name;

    public ConcreteObserver(String name) {
        this.name = name;
    }

    @Override
    public void update(String message) {
        System.out.println(name + " received message: " + message);
    }
}
4.2 使用示例:
public class ObserverPatternDemo {
    public static void main(String[] args) {
        Subject subject = new Subject();

        Observer observer1 = new ConcreteObserver("Observer 1");
        Observer observer2 = new ConcreteObserver("Observer 2");

        subject.attach(observer1);
        subject.attach(observer2);

        subject.notifyObservers("Hello Observers!");
    }
}

5、策略模式(Strategy Pattern)

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

5.1 示例代码:
// 策略接口
interface Strategy {
    int doOperation(int num1, int num2);
}

// 具体策略类
class OperationAdd implements Strategy {
    public int doOperation(int num1, int num2) {
        return num1 + num2;
    }
}

class OperationSubtract implements Strategy {
    public int doOperation(int num1, int num2) {
        return num1 - num2;
    }
}

class OperationMultiply implements Strategy {
    public 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);
    }
}
5.2 使用示例:
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));
    }
}

6、适配器模式(Adapter Pattern)

适配器模式使得原本由于接口不兼容而不能一起工作的那些类可以一起工作。它通过将一个类的接口转换成客户希望的另一个接口来实现。

6.1 示例代码:
// 目标接口
interface MediaPlayer {
    void play(String audioType, String fileName);
}

// 被适配的接口
interface AdvancedMediaPlayer {
    void playVlc(String fileName);
    void playMp4(String fileName);
}

// 具体的被适配类
class VlcPlayer implements AdvancedMediaPlayer {
    public void playVlc(String fileName) {
        System.out.println("Playing vlc file. Name: " + fileName);
    }
    public void playMp4(String fileName) {
        // 什么也不做
    }
}

class Mp4Player implements AdvancedMediaPlayer {
    public void playVlc(String fileName) {
        // 什么也不做
    }
    public 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();
        }
    }

    public void play(String audioType, String fileName) {
        if (audioType.equalsIgnoreCase("vlc")) {
            advancedMusicPlayer.playVlc(fileName);
        } else if (audioType.equalsIgnoreCase("mp4")) {
            advancedMusicPlayer.playMp4(fileName);
        }
    }
}

// 具体的播放器类
class AudioPlayer implements MediaPlayer {
    MediaAdapter mediaAdapter;

    public void play(String audioType, String fileName) {
        // 播放mp3音乐文件的内置支持
        if (audioType.equalsIgnoreCase("mp3")) {
            System.out.println("Playing mp3 file. Name: " + fileName);
        }
        // mediaAdapter 提供播放其他文件格式的支持
        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");
        }
    }
}
6.2 使用示例:
public class AdapterPatternDemo {
    public static void main(String[] args) {
        AudioPlayer audioPlayer = new AudioPlayer();

        audioPlayer.play("mp3", "beyond the horizon.mp3");
        audioPlayer.play("mp4", "alone.mp4");
        audioPlayer.play("vlc", "far far away.vlc");
        audioPlayer.play("avi", "mind me.avi");
    }
}

7、装饰器模式(Decorator Pattern)

装饰器模式允许向一个现有的对象添加新的功能,同时又不改变其结构。它是作为现有的类的一个包装。

7.1 示例代码:
// 组件接口
interface Shape {
    void draw();
}

// 具体组件类
class Rectangle implements Shape {
    public void draw() {
        System.out.println("Shape: Rectangle");
    }
}

class Circle implements Shape {
    public void draw() {
        System.out.println("Shape: Circle");
    }
}

// 装饰器抽象类
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);
    }

    @Override
    public void draw() {
        decoratedShape.draw();
        setRedBorder(decoratedShape);
    }

    private void setRedBorder(Shape decoratedShape) {
        System.out.println("Border Color: Red");
    }
}
7.2 使用示例:
public class DecoratorPatternDemo {
    public static void main(String[] args) {
        Shape circle = new Circle();

        Shape redCircle = new RedShapeDecorator(new Circle());

        Shape redRectangle = new RedShapeDecorator(new Rectangle());
        System.out.println("Circle with normal border");
        circle.draw();

        System.out.println("\nCircle with red border");
        redCircle.draw();

        System.out.println("\nRectangle with red border");
        redRectangle.draw();
    }
}

8、总结

设计模式为我们提供了应对常见软件设计问题的解决方案。在Java中,除了单例模式、工厂模式、观察者模式,我们还介绍了策略模式、适配器模式和装饰器模式。通过合理使用这些设计模式,可以让我们的代码更加简洁、灵活和可维护。希望本文能够帮助你更好地理解和应用设计模式,提高编程效率和代码质量。

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

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

相关文章

【WPS备考AI工具】一款小众且免费的个人题库导入刷题神器,学习提分必备小程序!

这篇文章的诞生&#xff0c;是因为我即将踏上一场超级有趣的挑战——备考全国计算机等级二级WPS Office高级应用与设计的冒险之旅&#xff01; WPS的分值&#xff1a; 单项选择题20分(含公共基础知识部分10分)。 WPS处理文字文档操作题30分。 WPS处理电子表格操作题30分。 …

爬虫模拟实操-全平台模式化规范

一.总体概述 本套教程适用于还没进入爬虫界的宝宝们 这套流程基本涵盖了全平台&#xff08; x抖 x快 x头 xB x淘 x知 x红 &#xff09;个人信息->作品->评论&#xff0c;为不侵权&#xff0c;有兴趣可以拉到最后进行交流 二.爬虫过程 随便拿个平台举例 老规矩f12 返…

深入探索PDF源码解析:从PDF到Excel的数据统计分析找到正文

在数字化时代&#xff0c;数据已成为企业决策和业务运营的关键。PDF文档作为一种广泛使用的文件格式&#xff0c;其中蕴含着大量有价值的信息。然而&#xff0c;PDF文档的结构和格式使得直接对其进行数据提取和分析变得复杂。为了解决这个问题&#xff0c;我们采取了一种创新的…

⌈ 传知代码 ⌋ 基于ROS的气体浓度建图

&#x1f49b;前情提要&#x1f49b; 本文是传知代码平台中的相关前沿知识与技术的分享~ 接下来我们即将进入一个全新的空间&#xff0c;对技术有一个全新的视角~ 本文所涉及所有资源均在传知代码平台可获取 以下的内容一定会让你对AI 赋能时代有一个颠覆性的认识哦&#x…

免杀笔记--->地狱之门(Hell ‘s Gate)保姆级解析

还记得我前面一篇文章讲到的在Ring3 对抗Hook吗&#xff1f;&#xff1f; 我讲到的一种方法就是系统调用&#xff01;&#xff01; 那么今天就来讲一下一个很出名的直接系统调用(Syscall)-----> [!] 地狱之门&#xff08;Hell s Gate&#xff09;[!] 目录 1.Syscall 2.…

Python爬虫:下载4K壁纸

&#x1f381;&#x1f381;创作不易&#xff0c;关注作者不迷路&#x1f380;&#x1f380; 目录 &#x1f338;完整代码 &#x1f338;分析 &#x1f381;基本思路 &#x1f381;需要的库 &#x1f381;提取图片的链接和标题 &#x1f453;寻找Cookie和User-Agent &…

Golang 并发编程

Golang 并发编程 Goroutine 什么是协程 创建 Goroutine 主 goroutine &#xff08;main函数&#xff09;退出后&#xff0c;其它的工作 goroutine 也会自动退出 package mainimport ("fmt""time" )func myFunc() {i : 0for {ifmt.Println("func: …

【C++】深入理解类和对象(3)

励志冰檗&#xff1a;形容在清苦的生活环境中激励自己的意志。&#x1f493;&#x1f493;&#x1f493; 目录 ✨说在前面 &#x1f34b;知识点一&#xff1a;再探构造函数 &#x1f34b;知识点二&#xff1a;类型转换 &#x1f34b;知识点三&#xff1a;static成员 &…

spl注入实战thinkphp

目录 一、环境的部署 二、本地创建数据库 三、填写数据库连接文件 四、编写控制器 五、访问分析 debug报错会显示物理路径 原因是config.php文件相关配置 六、注入分析 七、进入断点调试 八、通过mysql执行语句查看结果 九、总结&#xff1a; 一、环境的部署 二、本地…

【51单片机仿真】基于51单片机设计的智能六位密码锁(匿*输入/密码修改/警示/保存/恢复/初始密码)源码仿真设计文档演示视频——文末资料下载

基于51单片机设计的智能六位密码锁 演示视频 基于51单片机设计的智能六位密码锁 功能简介 - 能够从键盘中输入密码&#xff0c;并相应地在显示器上显示"*" - 能够判断密码是否正确&#xff0c;正确则开锁&#xff0c;错误则输出相应信息 - 能够实现密码的修改 -…

日志审计系统

1.1日志审计基础性知识 什么是日志&#xff1f; 传统的日志概念 信息系统中所有系统和应用必须包含的描述其自身运行和操作的特定数据记录。 广义的日志概念 针对特定记录目的&#xff0c;通过各种探测手段采集的信息数据&#xff0c;包括运行状态、所有事件及操作&#x…

从零开始实现循环神经网络

本节我们通过使用MXnet&#xff0c;来从零开始的实现一个含有隐藏状态的循环神经网络。 前序工作 数据集预处理进行采样 实现循环神经网络 完成前序工作后&#xff0c;即可开始实现循环神经网络。本文首先构建一个具有隐状态的循环神经网络。其结构如图所示&#xff1a; 接…

力扣面试经典算法150题:最后一个单词的长度

最后一个单词的长度 今天的题目是力扣面试经典150题中的数组的简单题: 最后一个单词的长度 题目链接&#xff1a;https://leetcode.cn/problems/length-of-last-word/description/?envTypestudy-plan-v2&envIdtop-interview-150 题目描述 给定一个仅包含大小写字母和空…

Broken靶机

查看靶机的mac地址 使用kail进行扫描ip 探测靶机主机&#xff0c;端口&#xff0c;服务 nmap -sS -sS -A -p- 192.168.154.137 进行目录扫描 dirsearch -u http://192.168.154.137 拼接后没什么发现 访问靶机ip 访问readme.md 发现是十六进制的值 将内容写入到readme.md中 使…

坐牢第二十五天20240813(网络通信)

一、TCP机械臂测试 通过w(红色臂角度增大)s&#xff08;红色臂角度减小&#xff09;d&#xff08;蓝色臂角度增大&#xff09;a&#xff08;蓝色臂角度减小&#xff09;按键控制机械臂 注意&#xff1a;关闭计算机的杀毒软件&#xff0c;电脑管家&#xff0c;防火墙 1&#x…

C语言问答进阶--5、基本表达式和基本语句

赋值表达式 表达式是什么&#xff1f;表达式是由运算符和操作数组成的式子。 如下的代码 #include "iostream.h" int main() { int a1,b2,sum; cout<<(sumab)<<endl; return 0; } 那么如下的呢&#xff1f; #include "iostream.h" int mai…

智能建筑系统,实现智慧城市的可持续发展

智能建筑系统是指通过现代技术和通信技术&#xff0c;对建筑系统进行全方位、智能化的管理和控制。该系统可以通过各种传感器、安全监控系统和计算机设备对工程建筑的内外环境进行认知和控制&#xff0c;进而监控和管理建筑工程设备和信息。 智能建筑系统可以调节室温、湿度等环…

基于Hadoop的汽车大数据分析系统设计与实现【爬虫、数据预处理、MapReduce、echarts、Flask】

文章目录 有需要本项目的代码或文档以及全部资源&#xff0c;或者部署调试可以私信博主项目介绍爬虫数据概览HIve表设计Cars Database Tables1. cars_data2. annual_sales_volume3. brand_sales_volume4. city_sales_volume5. sales_volume_by_year_and_brand6. sales_distribu…

Mysql的完整性约束

主键约束&#xff1a;一个表中只有一个主键&#xff0c;通过主键找到唯一的记录。主键不能为空不能重复。 CREATE TABLE s1&#xff08;id TINYINT PRIMARY KEY UNSIGNEDINT AUTO_INCREAMENT,name VARCHAR(20) NOT NULL UNIQUE ,age TINYINT DEFAULT 18&#xff09;;…

镜像仓库认证信息加密初始化脚本

文章目录 一、场景说明二、脚本职责三、参数说明四、操作示例五、注意事项 一、场景说明 本自动化脚本旨在为提高研发、测试、运维快速部署应用环境而编写。 脚本遵循拿来即用的原则快速完成 CentOS 系统各应用环境部署工作。 统一研发、测试、生产环境的部署模式、部署结构、…