导图社区 设计模式思维导图
这是一篇关于设计模式的思维导图。该思维导图归纳整理了多种设计模式和方法,以及设计中存在的一些问题,比较详细,可提供借鉴。
编辑于2021-08-17 09:56:06设计模式
三种类型
创建型模式
单例模式
饿汉式
静态常量
1、构造器私有化(防止 new 对象)
2、类内部创建静态对象
3、对外提供一个静态的公共方法 getInstance
静态代码块
1、私有化构造器(防止new对象)
2、对象的创建放入静态代码块中
3、对外提供一个静态的公共方法getInstance
优点:类装载的时候完成实例化,避免线程同步问题 缺点:没有达到lazy loading效果,类被状态可能是很多原因导致的 结论:单例模式可以使用,但是造成内存浪费
懒汉式
线程不安全
优点:起到了lazy loading的效果 缺点:只能在单线程下使用,多线程同时进入if判断中,就创建了多个对象 结论:实际开发中不要使用这种模式
1、私有化构造器
2、对外提供一个静态公共方法getInstance
3、判断实例是否存在
不存在,就new一个实例
存在,就返回实例
线程安全,同步方法
优点:解决了线程安全问题 缺点:效率比较低,每次获取实例,都需要同步,实际上获取一次就可以,以后获取直接return就可以 结论:实际开发过程中不建议使用
懒汉式(线程不安全)与懒汉式(线程安全,同步)的区别是,懒汉式(线程安全,同步)在getInstance方法中加入了synchronized关键字
线程安全,同步代码块
对线程安全同步方法的改进,改进为同步代码块 但是又会造成线程不安全 结论:不能使用这种方式
其实也属于线程不安全,在if判断时,跟线程不安全的情况是一样的
双重检查
1、私有化构造器
2、对外提供一个公共的静态方法getInstance
3、在静态方法内进行双if判断,在第二次if判断外层加入synchronized关键字
解决了线程安全问题,实现了懒加载lazy loading 同时解决了效率问题 实际开发过程中推荐使用这种模式创建单例
静态内部类
1、私有化构造器
2、创建静态内部类
3、静态内部类中有主类的静态实例化
4、对外提供一个公共的静态方法getInstance
3、对外静态方法中返回静态内部来的静态常量
采用类装载机制来保证初始化实例时只有一个线程 静态内部类在主类初始化时,并不会立即实例化 类的静态属性只会在第一次加载类的时候进行初始化 避免了线程不安全,利用静态内部类的特点实现了懒加载lazy loading,同时效率高 结论:推荐使用
枚举
借助JDK1.5中添加的枚举来实现单例模式,不仅能够避免多线程同步问题,而且还能防止反序列化重新创建新的对象 结论:推荐使用
JVM在装载类的时候是线程安全的 1、单例模式保证了系统内存中只存在一个对象,节省了系统资源,对于一些需要频繁销毁的对象,使用单例模式可以提高系统性能; 2、当想实例化一个单例类的时候,必须使用相应的获取对象的方法,而不是使用new对象; 3、单例模式使用场景:需要频繁的进行创建和销毁对象、创建对象时耗时过多或者耗费资源过多(即:重量级对象),但又经常用到的对象、工具类对象、频繁访问数据库或文件的对象(比如数据源,session工厂等)
原型模式
克隆羊解决问题
利用实体类中重写clone方法
浅拷贝
默认使用的clone方法
基本数据类型的属性,会复制一份给拷贝对象
引用类型的属性,只是将该成员的引用值复制给拷贝对象,未进行真正的拷贝
深拷贝
复制对象的所有基本数据类型的成员变量值
为所有引用类型的成员变量申请存储空间,并复制每个引用数据类型成员变量所引用的对象,直到该对象可达的所有对象。也就是说,对对象进行深拷贝,需要对整个对象进行拷贝;
重写clone方法实现深拷贝
通过对象的序列化实现深拷贝
1、创建新的对象比较复杂时,可以利用原型模式简化对象创建过程,同时也能提高效率; 2、不用重新初始化对象,而是动态地获得对象运行时的状态; 3、如果原始对象发生变化(增加或者减少属性),其他克隆对象的也会发生相应的变化,无需修改代码; 4、在实现深度克隆时候,可能需要比较复杂的代码; 缺点:需要为每一个类配备一个克隆方法,对全新的类来说不是很难,但是对已存在的类进行改造时,需要修改器源代码,违背了OCP原则。
建造者模式
注意事项和细节: 1、客户端(使用程序)不必知道产品的内部组成的细节,将产品本身与产品的创建过程解耦,使得相同的创建过程可以创建不同的产品对象; 2、每一个具体建造者都相对独立,而与其他的具体建造者无关,因此可以很方便的替换具体建造者或者增加新的具体建造者,用户使用不同的具体建造者即可得到不同的产品对象; 3、可以更精细的控制产品的创建过程。将复杂产品的创建步骤分解在不同的方法中,使得创建过程更加清晰,也更方便使用程序来控制创建过程。 4、增加新的具体建造者无需修改原有类库代码,指挥者针对抽象建造者类编程,系统扩展方便,符合“开闭原则”; 5、建造者模式所创建的产品一般具有较多的共同点,其组成部分相似,如果产品之间的差异性很大,则不适合使用建造者模式,因此其使用范围受到一定的限制; 6、如果产品的内部变化复杂,可能会导致需要定义很多具体建造者类来实现这种变化,导致系统变得庞大,因此在这种情况下,要考虑是否选择建造者模式; 7、抽象工厂模式VS建造者模式 抽象工厂模式实现对产品家族的创建,一个产品家族是这样的一系列产品:具有不同分类维度的产品组合,采用抽象工厂模式不需要关心构建过程,只关心什么产品由什么工厂产生即可。而建造者模式则是要求按照指定的蓝图建造产品,它的主要目的是通过组装零配件而产生一个新的产品
分为:产品,抽象建造者,具体建造者,指挥者
传统集成方式建造
比较好理解,操作简单
设计的程序结构,过于简单,没有设计缓存层对象,程序的扩展性和维护性不好,把产品和建造产品的过程封装到了一起,耦合性增强了
解决办法:将产品和产品的建造过程解耦
建造者模式
StringBuilder
appendable接口(抽象建造者)
abstractStringBuilder实现了appendable(具体建造者,不能实例化)
stringBuilder继承了abstractStringBuilder;充当了指挥者角色,同时充当了建造者
主要解决差异化很小,同时最大程度上解耦的产品的创建过程
工厂模式
简单工厂模式
工厂方法模式
抽象工厂模式
简单工厂和工厂方法结合
1、将实例化对象的代码提取出来,放到一个类中统一管理和维护,达到和主项目的依赖关系解耦。从而提高项目的扩展性和可维护性; 2、设计模式的依赖抽象原则; 3、不要让类继承具体类,而是继承抽象类或者实现接口; 4、不要覆盖基类中已经实现的方法。
结构性模式
适配器模式
桥接模式
装饰模式
组合模式
外观模式
享元模式
代理模式
行为模式
模板方法模式
命令模式
访问者模式
迭代器模式
观察者模式
中介者模式
备忘录模式
解释器模式(Interpreter模式)
状态模式
策略模式
职责链模式(责任链模式)
层次
第一层:刚开始学习编程,听说过什么是设计模式
第二层:有很长时间的编程经验,自己写了很多代码,其中用到了设计模式,但是自己却不知道
第三层:学习过设计模式,发现自己已经在使用了,并且发现了一些新的模式挺好用的
第四层:阅读了很多别人的源码和框架,在其中看到别人设计模式,并且能够领会设计模式的精妙和带来的好处
第五层:代码写着写着,自己都没有意识到用了设计模式,并且熟练的写了出来