工厂方法模式(利用创建同一接口的不同实例):
1.普通工厂模式:建立一个工厂类,对实现同一接口的一些类进行实例的创建:
2.多个工厂方法模式:提供多个工厂方法,分别创建对象:
3.静态工厂方法模式:将上面的多个工厂设置为静态的,不需要创建工厂实例,直接调用即可;
工厂模式的适用场景:凡是出现了大量不同种类的产品需要创建,而且具有共同的接口时,可以通过工厂方法模式进行创建,在以上三种模式中,第一种如果传入的字符串有误,不能正确创建对象,第三种相对于第二种,不需要实例化工厂类,所以,大多数情况下,我们会选择用第三种方法
抽象工厂模式(多个工厂):创建多个工厂类,提高工厂的拓展性,不用像上面一样如果增加产品则要去修改唯一的工厂类
单例模式:保证对象只有一个实例,保证在JVM中这个对象只有一个实例存在
适用场景:1.某些类创建比较频繁,对于一些大型的对象,这是一笔很大的系统开销 2.需要减少GC压力 3.要求高安全,例如交易所的核心交易引擎,控制着交易流程
典型代码:
public class test8 { /* 持有私有静态实例例,防⽌止被引⽤用,此处赋值为null,⽬目的是实现延迟加载 */ private static test8 instance = null; /* 私有构造⽅方法,防⽌止被实例例化 */ private test8() { } /* 静态⼯工程⽅方法,创建实例例 */ public static test8 getInstance() { if (instance == null) { instance = new test8(); } return instance; } /*如果这个对象被序列化,保证对象序列化前后一致*/ public Object readResolve(){ return instance; } }
饿汉式:类初始化时候创建单例,线程安全,适用于单例占内存小的场景
public class test8 { private static test8 instance = new test8(); private test8(){} public static test8 newInstance(){ return instance; } }
懒汉式:需要创建单例实例的时候再创建,需要考虑线程安全
public class test8{ private static test8 instance = null; private test8(){} public static synchronized test8 newInstance(){ if(null == instance){ instance = new test8(); } return instance; } }
双重检验锁:效率高(可以解决,两个线程同时进行了if(instance = null)语句,它会认为单例对象没有创建,然后两个线程一次执行同步代码块,并分别创建了一个单例对象)
public class Singleton { //禁止指令重排序优化 private static volatile Singleton instance = null; private Singleton(){} public static Singleton getInstance(){ if (instance ==null){ synchronized (Singleton.class){ if (instance == null){ instance = new Singleton(); } } } return instance; } }
静态内部类方式:可以同时保证延迟加载和线程安全
public class Singleton { private static class SingletonHolder{ public static Singleton instance = new Singleton(); } private Singleton(){} public static Singleton newInstance(){ return SingletonHolder.instance; } }
原型模式(对一个原型对象进行复制,克隆产生新对象):将一个对象作为原型进行复制克隆等操作
核心:原型类prototype,需要实现Cloneable接口实现深拷贝
作用:直接操作内存中的二进制流,对象小的时候很方便,大的时候则性能差距明显
适配器模式:(接口兼容)将某一个类的接口转换成客户端期待的另一个接口表示。目的是消除由于接口不匹配所造成的类的兼容性问题
核心的思想就是有一个Source类,拥有一个方法,待适配,目标接口Targetable,通过Adapter类,将Source类的功能拓展到Targetable里面
使用场景:类的适配器模式:当希望将一个类转换成另一个新接口的对象时,可以使用类的适配器模式,创建一个新类。继承原有的类,实现新的接口即可。
对象的适配器器模式:当希望将⼀一个对象转换成满⾜足另⼀一个新接⼝口的对象时,可以创建⼀一个Wrapper类,持有原类的⼀一个实例,在
Wrapper类的方法中,调用实例的方法就行。
接口的适配器模式:当不希望实现一个接口中所有的方法时,可以创建一个抽象类Wrapper,实现所有方法,我们写别的类的时
候,继承抽象类即可。
装饰模式(对对象动态增加新功能,需持有对象实例):动态的对一个对象增加一些新功能,要求装饰对象和被装饰对象实现同一个接口
使用场景:
需要扩展一个类的功能。
动态的为一个对象增加功能,而且还能动态撤销。(继承不能做到这一点,继承的功能是静态的,不能动态增删。)
代理模式:持有被代理类的实例,进行操作前后控制,采用一个代理类调用原有的方法,且对产生的结果进行控制
外观模式 (集合所有操作到一个类):外观模式是为了解决类与类之间的依赖关系的,像spring⼀一样,可以将类和类之间的关系配置到配置
文件中,而外观模式就是将他们的关系放在一个Facade类中,降低了类之间的耦合度。
桥接模式:就像mysql.Driver一样,把事物和具体的操作分开,是他们可以各自独立的变化,桥接的用意是:将抽象化和实现化解耦
组合模式(部分整体模式): 组合模式有时又叫部分-整体模式在处理类似树形结构的问题时比较方便。
享元模式(共享池、数据库连接池): 享元模式的主要目的是实现对象的共享,即共享池,当系统中对象多的时候可以减少内存的开销,
通常与工厂模式一起使用。当一个客户端请求时,工厂需要检查当前对象池中是否有符合条件的对象,如果有,就返回已经存在的对象,如果没有,则创建⼀一个新对象,如数据库连接池;
策略模式(多种算法封装): 策略略模式定义了了一系列列算法,并将每个算法封装起来,使他们可以相互替换,且算法的变化不会影响到使用算法的客户。需要设计一个接⼝口,为一系列实现类提供统一的方法,多个实现类实现该接口。
模板方法模式(抽象方法作为骨架,具体逻辑让子类实现):定义一个操作中算法的框架,而将一些步骤延迟到子类中,使得子类可以不改
变算法的结构即可重定义该算法中的某些特定步骤。完成公共动作和特殊动作的分离。
观察者模式(发布-订阅模式): 当一个对象变化时,其它依赖该对象的对象都会收到通知,并且随着变化!对象之间是一种一对多的关
系。类似于邮件订阅和RSS订阅,当你订阅了该文章,如果后续有更新,会及时通知你。
迭代器模式(遍历集合): 迭代器模式就是顺序访问聚集中的对象。
责任链模式(多任务形成⼀条链,请求在链上传递): 有多个对象,每个对象持有对下一个对象的引用,这样就会形成一条链,请求在
这条链上传递,直到某一对象决定处理理该请求。但是发出者并不清楚到底最终那个对象会处理该请求,所以,责任链模式可以实现,在隐瞒客户端的情况下,对系统进行动态的调整。
命令模式(实现请求和执行的解耦): 命令模式的目的就是达到命令的发出者和执行者之间解耦,实现请求和执行分开Struts其实就是一种将请求和呈现分离的技术
备忘录模式(保存和恢复对象状态): 主要目的是保存一个对象的某个状态,以便在适当的时候恢复对象。
状态模式(对象状态改变时改变其行为): 当对象的状态改变时,同时改变其行为。状态模式就两点:1、可以通过改变状态来获得不同
的行为。2、你的好友能同时看到你的变化。
访问者模式(数据接口稳定,但算法易变): 访问者模式把数据结构和作用于结构上的操作解耦合,使得操作集合可相对自由地演化。
访问者模式适用于数据结构相对稳定算法又易变化的系统。因为访问者模式使得算法操作增加变得容易。访问者模式就是一种分离对象数据结构与行为的方法,通过这种分离,可达到为一个被访问者动态添加新的操作而无需做其它的修改的效果。
中介者模式: 中介者模式也是用来降低类之间的耦合的。如果使用中介者模式,只需关心和Mediator类的关系,具体类之间的关系
及调度交给Mediator就行,这有点像spring容器的作用。
解释器模式 (对于一些固定文法构建一个解释句子的解释器,如正则表达式):解释器模式用来做各种各样的解释器,如正则表达式等的
解释器。
建造者模式 (创建复合对象):工厂类模式提供的是创建单个类的模式,而建造者模式则是将各种产品集中起来进行管理,用来创建复合对
象,所谓复合对象就是指某个类具有不同的属性
JDK中的设计模式