程序猿成长之路之设计模式篇——设计模式简介

embedded/2024/10/9 3:36:32/

无论是对于代码质量还是代码可维护性、可扩展性,使用合适的设计模式都能够起到促进提升的作用,此外在软考的软件工程师、系统架构师职称考试中,设计模式也是必考的一块内容,因此我打算开拓一个新的专栏简单介绍一下设计模式,梳理梳理一些重要的设计模式,帮助各位更好的了解各类型的设计模式以及使用不同类型的设计模式可以带来的好处。

什么是设计模式

如果说代码是一道菜,那么设计模式就如同调料,合理使用可以使代码变得更加得精美;如果说代码是一堆积木,那么设计模式就是搭建积木的手册,合理使用可以使代码变成想要的形状。为了帮助各位了解什么是设计模式,我再举一个例子:
假设现在有1和2两个数字,在不添加其他条件和环境的情况下这两个数字毫无相关性,但是现在有了运算符,有了数学公式,就可以将这两个数字联系起来了,就比如加法运算,1+2 = 3。其中1、2这两个数字可以理解成两个代码片段,而将两个数字相关联的公式可以理解成设计模式,通过设计模式可以将原本看上去不相关的代码片段联系起来,并产生我们想要的结果。

设计模式的好处

  1. 设计模式可以提高代码的可维护性及可扩展性,符合开闭原则(对扩展开放,对修改关闭)。举个例子,我们已经设计开发了一个类,并且该类符合单一职责原则(一个类仅仅满足实现一个特定的功能)就比如说要进行员工行为明细的录入,我们想在尽可能减少代码改动量和不改动原代码的前提下进行功能上的扩展,比如在录入之后还要对针对员工进行消息推送。这时候我们就可以使用适配器、装饰器或者代理设计模式。这样做的好处就是可以在不改动原来代码的基础上实现功能上的扩展。
  2. 设计模式可以保证数据的一致性。比如在项目范围内获取一个容器对象,并且要保证获取的容器对象是唯一的,这时候就可以使用单例设计模式
  3. 设计模式可以减少代码的修改量,比如我们使用组合策略,可以在只改动组合类的代码就可以实现代码的调整。
  4. 设计模式可以优化代码结构。

设计模式有哪些分类

  1. 创建型设计模式:提供了一种在创建对象的同时隐藏创建逻辑的方式,而不是使用new 直接实例化对象。这使得程序在判断针对某个给定实例需要创建哪些对象时更加灵活。常见的创建型设计模式有:工厂模式、抽象工厂模式、单例模式、建造者模式、原型模式、静态工厂模式。
  2. 结构型设计模式:这些设计模式关注类和对象的组合。继承的概念被用来组合接口和定义组合对象获得新功能的方式。常见的结构型设计模式有:装饰器、适配器设计模式、外观设计模式、组合设计模式
  3. 行为型设计模式:关注行为本身的设计模式,比如关注观察者及被观察者通信的观察者设计模式,关注迭代器间调用的迭代器模式、关注不同行为响应策略的策略模式等。

用一个图片来整体描述一下设计模式之间的关系:
在这里插入图片描述

几类设计模式简介

  1. 创建型设计模式
    抽象工厂设计模式:不同工厂类中有不同的产品,但是产品类型是一致的,就比如说海尔有海尔工厂,西门子有西门子工厂,但是无论是海尔还是西门子都生产冰箱等家电产品。如下图所示,ProductA和ProductB都是抽象出来的产品类型,如冰箱和洗衣机,而ConcreteFactory1就可以是海尔集团,ConcreteFactory2就可以是西门子集团,那么ConcreteProductA1就是海尔生产的冰箱而ConcreteProductA2就是西门生产的冰箱,以此类推。
    在这里插入图片描述

  2. 结构型设计模式
    装饰器设计模式
    通过层层嵌套实现完整功能。采用了组合优于继承的策略。
    举例:java中的io代码,
    在这里插入图片描述

java">InputStream in = new FileInputStream("/test.txt");
InputStream bin = new BufferedInputStream(in);
byte[] data = new byte[128];
while(bin.read(data) != -1) {//...
}

其中in嵌套到BufferedInputStream中就用到了装饰器的嵌套,都是基于InputStream的实现类。

其他示例代码:

java">package decorator;
/*** 基础接口* @author zygswo**/
public interface BasePrinter {/*** 打印信息* @param msg*/void print();
}package decorator;/*** child接口* @author zygswo*/
public class ChildPrinter implements BasePrinter{/*** 打印日志*/protected volatile BasePrinter printer;/*** 构造方法* @param printer*/public ChildPrinter(BasePrinter printer) {this.printer = printer;}@Overridepublic void print() {System.out.println("ChildPrinter print start");printer.print();System.out.println("ChildPrinter print end");}
}
package decorator;
/*** parent接口* @author zygswo*/
public class ParentPrinter implements BasePrinter{/*** 打印日志*/protected volatile BasePrinter printer;/*** 构造方法* @param printer*/public ParentPrinter(BasePrinter printer) {this.printer = printer;}@Overridepublic void print() {System.out.println("ParentPrinter print start");printer.print();System.out.println("ParentPrinter print end");}
}package decorator;
/*** 接口传参类* @author zygswo*/
public class Printer implements BasePrinter{private String message;public Printer(String message) {this.message = message;}@Overridepublic void print() {System.out.println(message);}
}package decorator;public class Main {public static void main(String[] args) {BasePrinter myprinter = new Printer("hello world");//装饰器层层嵌套BasePrinter childPrinter = new ChildPrinter(new 		ParentPrinter(myprinter));childPrinter.print();}
}
  1. 行为型设计模式

观察者设计模式:通过设置观察者和被观察者,使得当被观察者的状态发生变化后,可以及时通知观察者。

示例代码:

java">/*** 被观察者* @author zygswo*/
public interface Subject{/*** 绑定观察者*/void registerObserver(Observer observer);/*** 通知观察者*/void notifyObserver(String message);
}/*** 观察者* @author zygswo*/
public interface Observer{/*** 更新观察者状态*/void update(Message message);
}/*** 被观察者* @author zygswo*/
public class ConcreteSubject implements Subject{private List<Observer> observers = new ArrayList<>();@Overridepublic void registerObserver(Observer observer) {this.observers.add(observer);}@Overridepublic void notifyObserver(String message) {for(Observer observer: observers) {observer.update(message); //更新观察者信息}}
}/*** 观察者1* @author zygswo*/
public class ConcreteObserverOne implements Observer{@Overridepublic void update(String message) {System.out.println(message);System.out.println("observer1 is updated");}
}/*** 观察者2* @author zygswo*/
public class ConcreteObserverTwo implements Observer{@Overridepublic void update(String message) {System.out.println(message);System.out.println("observer2 is updated");}
}public class Main {public static void main(String[] args) {Subject subject = new Subject();subject.registerObserver(new ConcreteObserverOne());subject.registerObserver(new ConcreteObserverTwo());subject.notifyObserver("hello world");}
}

http://www.ppmy.cn/embedded/124864.html

相关文章

数据链路层(以太网简介)

一.以太网数据帧结构&#xff1a; 目的地址&#xff0c;源地址&#xff0c;类型这三个被称为帧头&#xff0c;数据则被称为载荷&#xff0c;CRC则被称为帧尾&#xff08;校验和&#xff09; 二.数据帧结构分析 1.目的地址和源地址 i.地址解释 这两个地址指的是mac地址&#x…

OpenGL笔记之事件驱动设计将相机控制类和应用程序类分离

OpenGL笔记之事件驱动设计将相机控制类和应用程序类分离 —— 2024-10-02 下午 bilibili赵新政老师的教程看后笔记 code review! 文章目录 OpenGL笔记之事件驱动设计将相机控制类和应用程序类分离1.代码图片2.分析3.UML4.代码 1.代码图片 运行 Mouse button 1 pressed at (1…

『网络游戏』窗口基类【06】

创建脚本&#xff1a;WindowRoot.cs 编写脚本&#xff1a; 修改脚本&#xff1a;LoginWnd.cs 修改脚本&#xff1a;LoadingWnd.cs 修改脚本&#xff1a;ResSvc.cs 修改脚本&#xff1a;LoginSys.cs 运行项目 - 功能不变 本章结束

pg if条件语句

1.语法&#xff1a; 2.区别 IF 语句&#xff1a; 只能在 PL/pgSQL 中使用&#xff0c;不适合在直接的 SQL 查询中使用。没有返回值&#xff0c;仅仅是控制逻辑流程。适合用在存储过程、函数和触发器中。 CASE 语句&#xff08;在 PL/pgSQL 中&#xff09;&#xff1a; 可以在 P…

命名管道Linux

管道是 毫不相关的进程进程间通信::命名管道 管道 首先自己要用用户层缓冲区&#xff0c;还得把用户层缓冲区拷贝到管道里&#xff0c;&#xff08;从键盘里输入数据到用户层缓冲区里面&#xff09;&#xff0c;然后用户层缓冲区通过系统调用&#xff08;write&#xff09;写…

【Web】portswigger 服务端原型污染 labs 全解

目录 服务端原型污染 为什么服务器端原型污染更难检测&#xff1f; 通过受污染的属性反射检测服务器端原型污染 lab1:通过服务器端原型污染进行权限提升 无需污染属性反射即可检测服务器端原型污染 状态代码覆盖 JSON 空格覆盖 字符集覆盖 lab2:检测没有污染属性反射的…

微信原生小程序

app.json 中配置project.config.json 中配置project.private.config.json 中配置sitemap.json 中配置index.json 中配置常用全局配置常用页面配置WXMLnavigator 组件 基本用法常用属性事件 scroll-view 组件 基本用法 1. 创建可垂直滚动的区域2. 创建可水平滚动的区域事件1. 事…

JumperServer入门

一、安装部署 官方安装文档&#xff1a;快速入门 - JumpServer 文档 机器准备 CentOS7 ip 角色 192.168.252.145 主节点 192.168.252.146 被控节点1 192.168.252.148 被控节点2 安装JumperServer curl -sSL https://resource.fit2cloud.com/jumpserver/jumpserver…