浅谈设计模式

简介: 设计模式

 设计模式

为什么要用设计模式?

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

设计模式的类型

创建型模式

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

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

结构型模式

常见的设计模式

工厂模式

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

优点:

    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


                      相关文章
                      |
                      设计模式 算法 关系型数据库
                      23种设计模式总结
                      23种设计模式总结
                      103 0
                      |
                      6月前
                      |
                      设计模式 存储 算法
                      |
                      7月前
                      |
                      设计模式 算法
                      什么是设计模式,有哪些设计模式,设计模式用来做什么
                      什么是设计模式,有哪些设计模式,设计模式用来做什么
                      |
                      设计模式 存储 算法
                      |
                      设计模式 关系型数据库
                      设计模式介绍
                      设计模式介绍
                      106 0
                      |
                      设计模式
                      设计模式——里氏替换
                      设计模式——里氏替换
                      |
                      设计模式 Java
                      23种设计模式
                      23种设计模式
                      145 0
                      |
                      设计模式 Java
                      23种设计模式-总揽篇
                      23种设计模式-总揽篇
                      23种设计模式-总揽篇
                      |
                      设计模式 Arthas Java
                      设计模式(四)
                      设计模式
                      202 0
                      |
                      设计模式 XML 存储