浅谈设计模式

简介: 设计模式

 设计模式

为什么要用设计模式?

设计模式是编程随时间发展下来总结的经验和套路,它可以让写出来的代码复用性更好、拓展性更强、易于维护等等优点

设计模式的类型

创建型模式

提供一种在创建对象的同时隐藏创建逻辑的方式,让程序在不同情境下可以灵活的选择创建对象的类型

工厂模式、抽象工厂模式、单例模式、建造者模式等

结构型模式

常见的设计模式

工厂模式

意图:定义一个工厂接口,实现不同的创建对象方式,使用者直接使用实现类创建对象。

优点:

    1. 可以屏蔽复杂的创建过程,调用者只关心通过哪个工厂创建。
    2. 扩展性强,如果需要添加一种创建方式,只需要实现一个新的工厂类

    缺点:

      1. 每次定义一种类的时候就需要一个配套的对象工厂,一定程度上增加了复杂度,所以如果简单的类型直接new就好了。

      使用场景:

        1. Spring的BeanFactory接口就是工厂模式,它的实现类可以通过配置文件的信息生产Bean,也可以通过getBean获取实例时就是向工厂获取指定的Bean

        抽象工厂模式

        与简单工厂模式的区别

        简单工厂模式只针对单个”产品的生产“,而抽象工厂模式中有多个产品需要生产,并且各个产品之间又有依赖关系。

        例子:

        我们需要生产矿泉水,如果用简单工厂模式就是需要三个工厂,一个产水一个产瓶子,然后还要有一个工厂把水填进瓶子里。显然水和瓶子是有逻辑上的关系的,使用抽象工厂模式后,在抽象工厂中定义生产水、生产瓶子和灌装水的方法,具体的实现类都实现后就可以在一个工厂中生产出矿泉水了。

        单例模式

        意图: 保证一个类只有一个实例,全局只访问这一个,避免一个相同的类被频繁的创建和销毁

        例子:

          1. Spring当中的Bean默认都是单例模式
          2. 计数器使用的也是单例,然后保证同步访问。
          3. 数据库的连接池也算吧,固定几个连接,它们都是不同的对象,可以理解成单个?然后实现复用

          懒汉式实现

          //懒汉式实现是在实际使用时才创建
          public class Singleton {
            private static Singleton singleton = null;
            // 构造得声明成私有的,不会被外部随意实例化
            private SingleTon(){}
            // 方法体加锁
            public static synchronized SingleTon() {
              if (singleton == null) {
                singleton = new Singleton();
              }
              return singleton;
            }
            // 双重锁定
            public static SingleTon() {
              // 两次判空是因为,等待锁时可能已经被人初始化过了,如果不再判断可能会重复初始化。
              if (singleton == null) {
                synchronized(this) {
                  if (singleton == null) {
                    singleton = new Singleton(); 
                  } 
                }
              }
              return singleton;
            }
          }
          image.gif

          饿汉式实现

          // 饿汉式在类初始化时就已经初始化了静态实例
          public class Singleton {
            private static Singleton singleton = new Singleton();
            private SingleTon(){}
            public static SingleTon() {
              return singleton;
            }
          }
          image.gif

          建造者模式

          意图: 将一个复杂对象的创建分离成各个步骤,使得一个复杂对象可以在多次组合当中创建出来。

          实例:

            1. StringBuilder就是其中一种,例如输出一段日志的前缀都是相同的,但是程序执行中可能成功或者失败,那么可以根据不同的结果append拼接,最后组合出整个字符串对象。

            适配器模式

            意图: 适配器模式使得原本不相兼容的接口可以一起工作,日常生活中常见的图片查看器就是一种“适配器”,可以查看不同格式的图片。

            实例:

              1. SpringMVC中就有HandleAdepter,用于适配Controller的不同实现方式(注解、配置、实现Controller接口、实现HTTPRequestHandle接口)的调用。

              实现

              public interface JPG extend PictureFormat{
                void display();
              } 
              public class JPGPlayer{
                void display(){
                  ....
                }
              }
              public interface PicturePlayer {
                void displayPicture();
              }
              public class PlayerAdepter implement PicturePlayer{
                PictureFormat format = null;
                public PlayerAdepter(PictureFormat format){
                  this.format = format;
                }
                void displayPicture() {
                  // 额外处理
                  format.display();
                  // 额外处理
                }
              }
              image.gif

              装饰器模式

              意图: 动态地给一个对象添加一些额外的功能,同时不改变其原有的结构。相比起继承装饰者模式更加灵活。

              实例:

                1. JDK 中Collections.SynchronizedMap,生成线程安全的集合类,将其所有修改方法都加上了同步锁

                实现:

                public interface Human {
                  void talk();
                }
                public class Man implement Human{
                  void talk(){
                    //打印hello
                  }
                }
                public abstract class HumanDecorator implement Human {
                  private Human human = null;
                  public HumanDecorator(Human human) {
                        this.human = human;
                  }
                  void talk() {
                    human.talk();
                  }
                }
                public class StudentDecorator extends HumanDecorator {
                  public StudentDecorator(Human human) {
                        super(human);
                  }
                  @Override
                  void talk() {
                    human.talk();
                    readBook();
                  }
                  private void readBook(){
                    //读书
                  }
                }
                image.gif

                代理模式

                意图: 为其他对象提供一种代理的方式控制这个对象的访问。

                实例:

                  1. JDK中的动态代理
                  2. Spring AOP

                  与适配器模式的区别

                  适配器模式需要考虑其中对不同对象的适配,代理模式代理的对象一旦确定是不能改变的

                  与装饰者模式的区别

                  其实差别不大,只是使用的本意不同,装饰器模式是为了增加额外的功能,代理模式是为了加以控制

                  实现:

                  静态代理、动态代理、

                  观察者模式

                  意图: 定义对象之间一种一对多的依赖关系,当一个对象的状态发生改变时,通知依赖于它的观察者对象执行对应的处理方法。它类似于广播通讯。用途可以用于广播通知更改、也可以做一个回调机制

                  实例:

                    1. Spring的事件驱动模型就是观察者模式的应用,它有各种Listener对应到各个事件中,例如ApplicationContext初始化完成后打印日志、Environment环境对象初始化完成后读取用户的Application.properties等等

                    实现:

                      1. 首先得定义事件类型Event,和一个或者多个Listener,Listener统一实现一个接口的事件触发执行方法。
                      2. 事件中心类EventObject中维护Event和Listener的一对多关系。
                      3. 从事件中心类中发布事件后,调用对应事件中的所有观察者。

                      策略模式

                      意图: 定义一系列函数,把他们封装起来,并且使他们之间能互相替换,它可以解决在有多种解决方式的情况下使用if..else所带来的复杂度。

                      实现:

                      public interface Strategy{
                      void algorithmInterface();
                      }
                      public class ConcreteStrategyA extends Strategy {
                       @Override
                       public void algorithmInterface() {
                           System.out.println("算法A实现");
                       }
                      }
                      public class ConcreteStrategyB extends Strategy {
                       @Override
                       public void algorithmInterface() {
                           System.out.println("算法B实现");
                       }
                      }
                      public class Client {
                       public static void main(String[] args) {
                           Context context;
                           context = new Context(new ConcreteStrategyA());
                           context.contextInterface();
                           context = new Context(new ConcreteStrategyB());
                           context.contextInterface();
                           context = new Context(new ConcreteStrategyC());
                           context.contextInterface();
                       }
                      }
                      image.gif

                      模板模式

                      意图:定义一个程序执行流程的骨架,封装好公共的步骤,将一些步骤延迟到子类当中实现。

                      实例:

                      Spring中的各种Template类,RedisTemplate、JDBCTemplate等

                      实现:

                      public abstract class Template {
                          abstract void run();
                          abstract void destroy();
                          void init() {
                              System.out.println("初始化");
                          }
                          public final void play(){
                              init();
                              run();
                              destroy();
                          }
                      }
                      class GameTemplate extends Template {
                          @Override
                          void run() {
                              System.out.println("执行");
                          }
                          @Override
                          void destroy() {
                              System.out.println("销毁");
                          }
                      }
                      image.gif


                      相关文章
                      |
                      5月前
                      |
                      设计模式 算法 Java
                      设计模式篇
                      设计模式篇
                      161 0
                      |
                      存储 运维 监控
                      API明细日志及运维统计日志全面提升API可运维性
                      在数字化转型的大潮中,数据已成为企业最宝贵的资产之一。而数据服务API可快速为数据应用提供数据接口。面对越来越多的API以及越来越多的应用调用,如何快速查看API的服务情况、异常情况及影响范围,以及查看API的调用详情,进行API的性能优化、错误排查变得越来越重要,本文将介绍如何配置和开通API运维统计及明细日志,以及如何查看日志进行介绍。
                      628 0
                      |
                      11月前
                      |
                      人工智能 算法 Serverless
                      《主动式智能导购AI助手构建》解决方案用户评测
                      在部署体验过程中,官方提供的详尽文档和图表帮助新手轻松上手,但环境变量设置等问题仍需改进。解决方案采用Multi-Agent架构,百炼大模型实现精准推荐,函数计算优化响应速度。生产环境部署指导全面,但仍需加强异常处理和面向新手的教学资源。整体架构清晰高效,建议完善数据流描述及Router Agent算法逻辑的阐述。
                      313 10
                      《主动式智能导购AI助手构建》解决方案用户评测
                      |
                      存储 NoSQL 关系型数据库
                      一文探索应运而生的数据库们
                      本文系统性回顾了数据库技术的发展历程与现状,从层次数据库 IMS 到新兴的向量数据库 Milvus,每一类数据库的诞生都映射了特定时代的技术挑战与应用需求。
                      RTMP协议详解及Wiresahrk抓包分析(三)
                      RTMP协议详解及Wiresahrk抓包分析
                      419 1
                      |
                      应用服务中间件 Linux nginx
                      高并发下Nginx配置限流
                      【8月更文挑战第16天】
                      229 1
                      |
                      存储 编解码 内存技术
                      RTMP协议详解及Wiresahrk抓包分析(二)
                      RTMP协议详解及Wiresahrk抓包分析
                      432 0
                      |
                      测试技术
                      性能测试包括哪些方面?
                      性能测试是评估电力系统响应时间、吞吐量和资源利用率的关键步骤,确保系统在不同负载下表现良好。它包括响应时间、吞吐量、资源利用率和稳定性测试,通过负载、压力、基准和故障恢复测试来检验系统性能。性能测试对于系统正常运行、问题发现及优化升级至关重要。
                      性能测试包括哪些方面?
                      |
                      存储 网络协议 网络安全
                      RTMP协议详解及Wiresahrk抓包分析(一)
                      RTMP协议详解及Wiresahrk抓包分析
                      1370 2
                      |
                      前端开发 JavaScript
                      vue的v-model、v-if、v-for用react语法实现
                      vue的v-model、v-if、v-for用react语法实现