• java面向对象02——常见的设计模式


    目录

    一. 为什么需要学习设计模式

    二. 常见的设计模式

    1.单例模式

    a.概念

    b.使用场景

    c.优缺点

    d.示例

    2.工厂模式

    a. 概念

    b.使用场景

    c.工厂方法

    d.抽象工厂

    3 责任链模式

    a. 概念

    b.使用场景

    c.类图

    4 观察者模式(Obsever)

    a.概念

    b. 使用场景

    c.类图

     d.小结


    一. 为什么需要学习设计模式

    设计模式(Design pattern)代表了最佳的实践,是很多优秀的软件开发人员的经验总结,是解决特定问题的解决方案。它并不是语法规定,也不拘泥于特定语言。 恰当的使用设计模式可以代码的可复用性,可维护性,可扩展性,健壮性及安全性,这些都是系统非常重要的非功能性需求。

    设计模式的广泛使用起始于1995年,GOF(四人帮)出版的《设计模式:可复用面向对象软件基础》。

    本部分相关的示例代码:

    https://gitee.com/lisenaq/patterndemo.git

    二. 常见的设计模式

    1.单例模式

    a.概念

    保证在内存中只用一个实例

    b.使用场景

    比如:系统配置文件的管理,这些配置文件只要使用一个单例对象进行读写即可,系统总其他地方需要使用配置信息时,只要使用该单例对象进行获取就可以了,这样便于统一管理配置信息

    c.优缺点

    优点:

    • 在内存中只有一个对象,节省内存空间;
    • 避免频繁的创建销毁对象,可以提高性能;
    • 避免对共享资源的多重占用,简化访问;
    • 为整个系统提供一个全局访问点。

    缺点:

    • 不适用于变化频繁的对象;
    • 滥用单例将带来一些负面问题,如为了节省资源将数据库连接池对象设计为的单例类,可能会导致共享连接池对象的程序过多而出现连接池溢出;

    d.示例

    饥饿模式

    1. /**
    2. * 单例模式,饥饿加载
    3. */
    4. public class SingletonDemo {
    5. //1. 需要有一个私有的构造函数,防止该类通过new的方式创建实例
    6. private SingletonDemo(){}
    7. //2. 饥饿模式,首先生成一个实例
    8. private static final SingletonDemo instance = new SingletonDemo();
    9. //3. 静态方法,用于获取已经生成的实例
    10. public static SingletonDemo getInstance() {
    11. return instance;
    12. }
    13. public String hello(String name) {
    14. return "hello " + name;
    15. }
    16. }

    这种直线方式简单,且是线程安全的。

    懒汉模式

    第一种写法:

    1. /**
    2. * 单例模式: 懒汉式
    3. */
    4. public class SingletonDemo02 {
    5. private SingletonDemo02(){}
    6. private static SingletonDemo02 singletonDemo02 = null;
    7. public static SingletonDemo02 getInstance() {
    8. if (singletonDemo02 == null) {
    9. singletonDemo02 = new SingletonDemo02();
    10. }
    11. return singletonDemo02;
    12. }
    13. public String hello(String name) {
    14. return "hello " + name;
    15. }
    16. }

    注意: 这种方式在多线程访问时会有问题。

    第二种写法:

    1. /**
    2. * 单例模式: 懒汉式,线程安全,但性能较低
    3. */
    4. public class SingletonDemo03 {
    5. private SingletonDemo03() {
    6. }
    7. private static SingletonDemo03 singletonDemo03 = null;
    8. public static synchronized SingletonDemo03 getInstance(){
    9. if(singletonDemo03 == null) {
    10. singletonDemo03 = new SingletonDemo03();
    11. }
    12. return singletonDemo03;
    13. }
    14. public String hello(String name) {
    15. return "hello " + name;
    16. }
    17. }

    ​​​​​第三种写法:

    1. public class SingletonDemo03 {
    2. private SingletonDemo03() {
    3. }
    4. private static SingletonDemo03 singletonDemo03 = null;
    5. public static SingletonDemo03 getInstance(){
    6. //系统减小同步块来提升性能,可以吗?
    7. if(singletonDemo03 == null) {
    8. synchronized (SingletonDemo03.class) {
    9. singletonDemo03 = new SingletonDemo03();
    10. }
    11. }
    12. return singletonDemo03;
    13. }
    14. public String hello(String name) {
    15. return "hello " + name;
    16. }
    17. }

    该方式依然会有线程安全问题

    第四种写法:

    1. /**
    2. * 单例模式: 懒汉式,双重检查单例
    3. */
    4. public class SingletonDemo03 {
    5. private SingletonDemo03(){
    6. }
    7. private static SingletonDemo03 singletonDemo03 = null;
    8. public static SingletonDemo03 getInstance(){
    9. //减小同步块,并使用双重检查来保证线程安装,可以吗?
    10. if(singletonDemo03 == null) {
    11. synchronized (SingletonDemo03.class) {
    12. if(singletonDemo03 == null) {
    13. singletonDemo03 = new SingletonDemo03();
    14. }
    15. }
    16. }
    17. return singletonDemo03;
    18. }
    19. public String hello(String name) {
    20. return "hello " + name;
    21. }
    22. }

    第五种写法:

    1. /**
    2. * 单例模式: 懒加载, 线程安全
    3. */
    4. public class SingletonDemo04 {
    5. //阻止外部实例化
    6. private SingletonDemo04(){
    7. try {
    8. Thread.sleep(10);
    9. } catch (InterruptedException e) {
    10. e.printStackTrace();
    11. }
    12. }
    13. //使用静态内部类来使用一个SingletonDemo04对象
    14. private static class SingletonDemoHolder {
    15. private final static SingletonDemo04 instance = new SingletonDemo04();
    16. }
    17. public static SingletonDemo04 getInstance() {
    18. return SingletonDemoHolder.instance;
    19. }
    20. public String hello(String name) {
    21. return "hello " + name;
    22. }
    23. }

    第六种写法:

    1. public enum SingletonDemo05 {
    2. INSTANCE;
    3. public String hello(String name) {
    4. return "hello " + name;
    5. }
    6. }

    可以保证单例,且线程安全

    2.工厂模式

    a. 概念

    用于产生对象的方法或者式类,称之为工厂。 上面所讲到的单例模式也可以看作为一个特殊的工厂。

    b.使用场景

    为什么需要工作模式,原来使用new的方式感觉也很简单,且好懂?

    使用工厂的原因是我们可以通过工厂模式,来集中控制对象的创建过程,这样可以给设计带来更多的灵活性。

    比如:spring的IOC容器就是工厂模式的经典实现。

    c.工厂方法

    用于生产指定系列的对象。已鸭子为例,鸭子有真的鸭子,橡皮鸭,电子玩具鸭等。如何能方便的创建出各种鸭子,并将创建过程控制起来,以便于以后的维护和扩展?

    类图:

     

    d.抽象工厂

    用于生成指定产品族,一个产品族中包括多种产品。例如:
    我们都比较熟悉的电脑制造相关行业,有HP,罗技,联想,戴尔,近几年华为,小米也进来了,每个生产商生产的电脑又包括鼠标,键盘,屏幕等等配件。此时我们需要使用工厂模式来进行管理不同的产品族,这时使用简单工厂(也有叫作工厂方法的)已经无法满足要求,此时可以使用抽象工厂。

    类图:

     

    3 责任链模式

    a. 概念

    责任链模式是一个对象的行为模式,很多对象之间形成一条链条,处理请求在这个链条上进行传递,直到责任链的上的某个对象决定处理请求(也可扩展为几个对象处理),这个过程对于用户来说是透明的,也就是说用户并不需要知道是责任链上的哪个对象处理的请求,对请求是否处理由链条上的对象自己决定。

    为了便于理解我们可以想象一下击鼓传花的游戏。

    b.使用场景

    web容器中的过滤器算是责任链模式的一个经典场景。另外举个例子:当在论坛上提交内容时,论坛系统需要对一些关键词进行处理,看看有没有包含一些敏感词汇,而这些敏感词汇我们可以使用责任链模式进行处理。

    c.类图

     

    4 观察者模式(Obsever)

    a.概念

    观察者模式是对象的行为模式,有时也称为“发布/订阅模式”或者“监听器模式”。

    观察者模式定义了观察者和被观察者之间的一点多的关系,让多个观察者对象可以响应一个被观察者对象

    b. 使用场景

    比较经典的使用场景,比如:java中的swing包中对事件的处理。浏览器对鼠标,键盘等事件的处理等, spring中的事件发布机制也是使用该模式

    c.类图

     d.小结

    观察者模式是使用的非常广泛,比如:Listener,Hook,Callback等等,其实都是观察者的一种应用,名称叫法不同而已,思路基本相同。

    这一篇文章就到这里结束了嘿嘿嘿= ̄ω ̄=

     

  • 相关阅读:
    Centos系统中安装软件和在Linux中搭建LAMP环境(Linux一)
    4G/5G卡使用 EC200-CN
    Linux系统内核概述
    Vue学习之--------路由(Router)的基本使用(1)(2022/9/5)
    怎样成为一名销售高手?
    QMetaType和QVariant使用
    闲聊四种旅游方式
    Java基础10——日期和时间
    用openhub无法拿到query里面信息对象的文本
    Android 12(S) 图像显示系统 - drm_hwcomposer 简析(下)
  • 原文地址:https://blog.csdn.net/weixin_64938628/article/details/125384856