设计模式-创建型
目的:实例化过程的解耦
写在前面
发现对于落地这件事情还是要静下心一个一个目标完成,设计模式一直搁浅了好久也没个系统整理,作为网上标配开篇,最近还是补上这个作业吧
-
为什么用设计模式
- 设计模式是前人总结下来的经验,对于扩展性和可维护性有很大帮助
- 也是为了使设计变得简单,容易阅读
-
设计模式原则(SOLID)
- 单一职责原则(Single Responsibility Principle):可以理解为最好一个类只负责一项职责
- 开闭原则(Open Close Priciple):尽量对扩展开放,对修改关闭
- 里氏替换原则(Liskov Substitution Principle):引用父类处可以用任意子类代替
- 接口隔离原则(Interface Segregation priciple):建立单一接口,最好是一个类依赖一个接口,而不是多个类依赖一个接口
- 依赖倒置原则 (Dependency InVersion Principle) :调用方和实现方都应该依赖抽象,彼此相互独立,实现类应该依赖抽象,而不能反过来
- 迪米特法则(Law of Demeter):一个对象保持对其他对象最少的了解
- 合成复用原则(Composite/Aggregate Reuse Principle):尽量使用组合/聚合,不要使用继承,继承基类会暴露实现破坏封装;基类改变,子类实现也需要改变;实现是静态的,不够灵活
- 如何使用设计模式
以上原则只是设计参考的一个约束,并不绝对,对于“最好的设计模式就是不用设计模式”,我们还没有达到这个境界,只有合适的场景用更合适的方法。
我们原先想获取一个新对象
Object o = new Object();
之后在创建新对象的场景可以参考考虑一下使用以下的思路
-
单例模式
说明:一个类只能有一个实例,提供全局唯一的访问点
应用场景:控制资源场景,例如数据库连接池,线程池等
-
匿名内部类
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 对于循环依赖的解决方案
-
-
简单工厂
说明:根据传入的变量决定输出什么样的实例
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; } } }
-
工厂方法
说明:创建对象行为进行抽象,在子类里实现逻辑
适用场景:
-
如下是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(); } }
-
-
抽象工厂
说明:创建相关或依赖对象的家族,而无需明确指定具体类
适用场景:对象的创建和使用隔离开来
- Collection类中抽象了多个工厂方法,本身又是一个抽象的创建类
-
建造者模式
说明:封装一个对象复杂的构建过程
适用场景:crud时候,优化繁琐的实体构建过程
-
lombok @Builder
Builder builder = Builder .age(10) .name("builder") .build();
-
-
原型模式
说明:实例对象的复制获取新实例
//浅拷贝,仅对象内的引用也被复制时为深拷贝 @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; } }
-
总结
以上是对创建型的设计模式的一些demo及一些源码的引用,目的是尽快的理解和快速的用起来,后续会补全UML图
其中最常用的是单例模式/工厂方法/抽象工厂/建造者模式,设计模式的主要目的也是为了代码的可维护性和可扩展性,把会变动的地方和不变的地方隔离开来
如有不正确的地方欢迎大佬指正
本文由博客群发一文多发等运营工具平台 OpenWrite 发布
**粗体** _斜体_ [链接](http://example.com) `代码` - 列表 > 引用
。你还可以使用@
来通知其他用户。