设计模式-创建型

算法聆星人
• 阅读 821

设计模式-创建型

目的:实例化过程的解耦

写在前面

​ 发现对于落地这件事情还是要静下心一个一个目标完成,设计模式一直搁浅了好久也没个系统整理,作为网上标配开篇,最近还是补上这个作业吧

  1. 为什么用设计模式

    • 设计模式是前人总结下来的经验,对于扩展性和可维护性有很大帮助
    • 也是为了使设计变得简单,容易阅读
  2. 设计模式原则(SOLID)

    • 单一职责原则(Single Responsibility Principle):可以理解为最好一个类只负责一项职责
    • 开闭原则(Open Close Priciple):尽量对扩展开放,对修改关闭
    • 里氏替换原则(Liskov Substitution Principle):引用父类处可以用任意子类代替
    • 接口隔离原则(Interface Segregation priciple):建立单一接口,最好是一个类依赖一个接口,而不是多个类依赖一个接口
    • 依赖倒置原则 (Dependency InVersion Principle) :调用方和实现方都应该依赖抽象,彼此相互独立,实现类应该依赖抽象,而不能反过来
    • 迪米特法则(Law of Demeter):一个对象保持对其他对象最少的了解
    • 合成复用原则(Composite/Aggregate Reuse Principle):尽量使用组合/聚合,不要使用继承,继承基类会暴露实现破坏封装;基类改变,子类实现也需要改变;实现是静态的,不够灵活
  3. 如何使用设计模式

    以上原则只是设计参考的一个约束,并不绝对,对于“最好的设计模式就是不用设计模式”,我们还没有达到这个境界,只有合适的场景用更合适的方法。

我们原先想获取一个新对象

Object o = new Object();

之后在创建新对象的场景可以参考考虑一下使用以下的思路

  1. 单例模式

    说明:一个类只能有一个实例,提供全局唯一的访问点

    应用场景:控制资源场景,例如数据库连接池,线程池等

    • 匿名内部类

      class SingletonInnerClass {
        // 私有构造器保证不能new 创建新实例
          private SingletonInnerClass() {
          }
      
          public static SingletonInnerClass getInstance() {
              return SingletonInner.instance;
          }
      
          private static class SingletonInner {
              private static final SingletonInnerClass instance = new SingletonInnerClass();
          }
      }
    • 枚举类型

      enum SingletonEnum {
          INSTACN;
      }
    • 双重检查锁

      class SingletonDCL {
          private volatile static SingletonDCL instance;
      
          private SingletonDCL() {
      
          }
      
          public static SingletonDCL getInstance() {
              if (instance == null) {
                  synchronized (SingletonDCL.class) {
                      if (instance == null) {
                          instance = new SingletonDCL();
                      }
                  }
              }
              return instance;
          }
      }
    • Spring单例注册表

      /** Cache of singleton objects: bean name to bean instance. */
      private final Map<String, Object> singletonObjects = new ConcurrentHashMap<>(256);
      /** Cache of singleton factories: bean name to ObjectFactory. */
      private final Map<String, ObjectFactory<?>> singletonFactories = new HashMap<>(16);
      /** Cache of early singleton objects: bean name to bean instance. 
      提前曝光的单例Cache
      */
      private final Map<String, Object> earlySingletonObjects = new HashMap<>(16);
      
      @Nullable
          protected Object getSingleton(String beanName, boolean allowEarlyReference) {
          // 一级缓存 获取单例的bean
              Object singletonObject = this.singletonObjects.get(beanName);
          // 判断bean是否在创建中(并未创建完)
              if (singletonObject == null && isSingletonCurrentlyInCreation(beanName)) {
                  synchronized (this.singletonObjects) {
              // 二级缓存 获取提前曝光的单例
                      singletonObject = this.earlySingletonObjects.get(beanName);
              // 判断是否允许提前引用
                      if (singletonObject == null && allowEarlyReference) {
                // 三级缓存 获取单例bean
                          ObjectFactory<?> singletonFactory = this.singletonFactories.get(beanName);
                          if (singletonFactory != null) {
                  // 放入二级缓存 并删除三级缓存中的bean
                              singletonObject = singletonFactory.getObject();
                              this.earlySingletonObjects.put(beanName, singletonObject);
                              this.singletonFactories.remove(beanName);
                          }
                      }
                  }
              }
              return singletonObject;
          }

      上面也直接说了spring 对于循环依赖的解决方案

  2. 简单工厂

    说明:根据传入的变量决定输出什么样的实例

    interface Product {
        void use();
    }
    // 产品实现
    class ProductA implements Product {
        @Override
        public void use() {
            System.out.println("product A");
        }
    }
    
    class ProductB implements Product {
    
        @Override
        public void use() {
            System.out.println("product B");
        }
    }
    // 工厂
    class Factory {
        public Product produce(String type) {
            if ("A".equals(type)) {
                return new ProductA();
            } else if ("B".equals(type)) {
                return new ProductB();
            } else {
                return null;
            }
        }
    }
  3. 工厂方法

    说明:创建对象行为进行抽象,在子类里实现逻辑

    适用场景:

    • 如下是spring中的工厂方法接口

      public interface FactoryBean<T> {
          @Nullable
          T getObject() throws Exception;
      
          @Nullable
          Class<?> getObjectType();
      
          default boolean isSingleton() {
              return true;
          }
      }
    • jdk中Collection类

      
      public interface Collection<E> extends Iterable<E> {
        ...
          // 这是一个工厂方法
           Iterator<E> iterator();
        ...
      }
      //   实现在子类中
      public abstract class AbstractList<E> extends AbstractCollection<E> implements List<E> {
         public Iterator<E> iterator() {
              return new Itr();
          }
      }
  4. 抽象工厂

    说明:创建相关或依赖对象的家族,而无需明确指定具体类

    适用场景:对象的创建和使用隔离开来

    • Collection类中抽象了多个工厂方法,本身又是一个抽象的创建类
  5. 建造者模式

    说明:封装一个对象复杂的构建过程

    适用场景:crud时候,优化繁琐的实体构建过程

    • lombok @Builder

      Builder builder = Builder
                         .age(10)
                          .name("builder")
                          .build();
  6. 原型模式

    说明:实例对象的复制获取新实例

    //浅拷贝,仅对象内的引用也被复制时为深拷贝
    @Data
    @AllArgsConstructor
    class Prototype implements Cloneable {
        private String name;
        private Map<String, String> map;
    
        @Override
        public Prototype clone() throws CloneNotSupportedException {
            Prototype prototype = (Prototype) super.clone();
            prototype.map = map;
            prototype.name = name;
            return prototype;
        }
    }
  7. 总结

    以上是对创建型的设计模式的一些demo及一些源码的引用,目的是尽快的理解和快速的用起来,后续会补全UML图

    其中最常用的是单例模式/工厂方法/抽象工厂/建造者模式,设计模式的主要目的也是为了代码的可维护性和可扩展性,把会变动的地方和不变的地方隔离开来

如有不正确的地方欢迎大佬指正

本文由博客群发一文多发等运营工具平台 OpenWrite 发布
点赞
收藏
评论区
推荐文章
Wesley13 Wesley13
4年前
java中的23种设计模式
java中一共23种设计模式!按照目的来分,设计模式可以分为创建型模式、结构型模式和行为型模式。创建型模式用来处理对象的创建过程;结构型模式用来处理类或者对象的组合;行为型模式用来对类或对象怎样交互和怎样分配职责进行描述。创建型模式用来处理对象的创建过程,主要包含以下5种设计模式:工厂方法模
系统认知篇:防腐层、门面模式及适配模式的本质 | 京东云技术团队
门面模式和适配器模式是代码级的设计模式,而防腐层本质是一种防御型策略,在更高的层级对系统进行解耦
Wesley13 Wesley13
4年前
java24种设计模式
一、设计模式定义  设计模式(DesignPattern)是一套被反复使用、多数人知晓的、经过分类编目的、代码设计经验的总结,使用设计模式是为了可重用代码、让代码更容易被他人理解并且保证代码可靠性。二、设计模式分类  经典模式只有23个(还有简单工厂模式),它们各具特色,每个模式都为某一个可重复的设计问题提供了一套解决方案。  根据它们的用
灯灯灯灯 灯灯灯灯
4年前
「超全超细」Java设计模式图文详解!!!
java设计模式—原型模式Java原型模式1、概述  啥是原型模式?  原型模式属于设计模式中的创建型中的一员,  原型模式:使用原型实例指定待创建对象的类型,并且通过复制这个原型来创建新的对象!  说大白话就是自己复制自己,通过原生对象复制出一个新的对象,这两个对象结构相同且相似;  需要注意的是,原型对象自己不仅是个对象还是个工厂!并且通过克隆方式创
九路 九路
5年前
Java实现 一篇文章说尽设计模式之六大原则
我们知道,设计模式很有用,学好设计模式不但能让你写出更简洁,优雅的代码,还能使得代码的结构更清晰,也更有利于扩展当然设计模式也不是万能的,一成不变的.设计模式只是前人总结出来的一种经验,一种特定问题的解决方法,不能看作是死的东西不一定非要生搬硬套,非得按照设计模式书上来来,只要我们写的代码符合一定的一些原则,一样可以看作是自己的模式.但是前人总结
Wesley13 Wesley13
4年前
Java 设计模式(1)
设计模式(Designpattern)是一套被反复使用、多数人知晓的、经过分类编目的、代码设计经验的总结。使用设计模式是为了可重用代码、让代码更容易被他人理解、保证代码可靠性。毫无疑问,设计模式于己于他人于系统都是多赢的,设计模式使代码编制真正工程化,设计模式是软件工程的基石,如同大厦的一块块砖石一样。项目中合理的运用设计模式可以完美的解决很多问题,每种
Wesley13 Wesley13
4年前
Java设计模式之三种工厂模式
工厂模式实现了创建者和调用者的分离,实现了更好的解耦。详细分类:1)简单工厂模式(静态工厂模式);2)工厂方法模式;3)抽象工厂模式面向对象设计的基本原则:1)      OCP(开闭原则,OpenClosedPrinciple):一个软件的实体应当对扩展开放,对修改关闭。2)      
Wesley13 Wesley13
4年前
23种设计模式(1):单例模式
定义:确保一个类只有一个实例,而且自行实例化并向整个系统提供这个实例。类型:创建类模式类图:!23种设计模式(1):单例模式第1张|快课网(http://static.oschina.net/uploads/img/201407/05200605_0dij.gif"23种设计模式(1):单例模式
Wesley13 Wesley13
4年前
00_设计模式之语言选择
设计模式之语言选择设计模式简介背景设计模式是一套被反复使用的、多数人知晓的、经过分类编目的、代码设计经验的总结。设计模式(Designpattern)代表了最佳的实践,通常被有经验的面向对象的软件开发人员所采用。设计模式是软件开发人员在软件开发过程中面临的
Wesley13 Wesley13
4年前
23种设计模式(面向对象语言)
一、设计模式的分类总体来说设计模式分为三大类:创建型模式,共五种:工厂方法模式、抽象工厂模式、单例模式、建造者模式、原型模式。创建型模式是用来创建对象的模式,抽象了实例化的过程,帮助一个系统独立于其他关联对象的创建、组合和表示方式。所有的创建型模式都有两个主要功能:  1.将系统所使用的具体类的信息封装起来  2.隐藏
设计模式-单例模式概述 | 京东云技术团队
我们常把23种经典的设计模式分为三类:创建型、结构型、行为型,其中创建型设计模式主要解决“对象的创建”问题,将创建和使用代码解耦,结构型设计模式主要解决“类或对象的组合或组装”问题,将不同功能代码解耦,行为型设计模式主要解决“类或对象之间的交互”问题,将不