设计模式

2021-03-07  本文已影响0人  知止9528

1、⼯⼚⽅法模式(利⽤创建同⼀接⼝的不同实例):
1.1、普通⼯⼚模式:建⽴⼀个⼯⼚类,对实现了同⼀接⼝的⼀些类进⾏实例的创建;

public class SendFactory { 

 public Sender produce(String type) { 
     if ("mail".equals(type)) { 
        return new MailSender(); 
     } else if ("sms".equals(type)) { 
        return new SmsSender(); 
     } else { 
     System.out.println("请输⼊正确的类型!"); 
        return null; 
     } 
 } 
} 

1.2、多个⼯⼚⽅法模式:提供多个⼯⼚⽅法,分别创建对象;

 public class SendFactory { 
 
     public Sender produceMail(){ 
        return new MailSender(); 
     } 
     
     public Sender produceSms(){ 
        return new SmsSender(); 
     } 
}

1.3、静态⼯⼚⽅法模式:将上⾯的多个⼯⼚⽅法置为静态的,不需要创建⼯⼚实例,直接调⽤即可;
1.4、适⽤场景:凡是出现了⼤量不同种类的产品需要创建,并且具有共同的接⼝时,可以通过⼯⼚⽅法模式进⾏创建。在以上的三种模式中,第⼀种如果传⼊的字符串有误,不能正确创建对象,第三种相对于第⼆种,不需要实例化⼯⼚类,所以,⼤多数情况下,我们会选⽤第三种——静态⼯⼚⽅法模式。


2、抽象⼯⼚模式(多个⼯⼚):创建多个⼯⼚类,提⾼⼯⼚的扩展性,不⽤像上⾯⼀样如果增加产品则要去修改唯⼀的⼯⼚类;


3、单例模式(保证对象只有⼀个实例):保证在⼀个JVM中,该对象只有⼀个实例存在;

1、适⽤场景:
 (1)、某些类创建⽐较频繁,对于⼀些⼤型的对象,这是⼀笔很⼤的系统开销。
 (2)、省去了new操作符,降低了系统内存的使⽤频率,减轻GC压⼒。
 (3)、有些类如交易所的核⼼交易引擎,控制着交易流程,如果该类可以创建多个的话,系统完全乱了。(⽐如⼀个军队出现了多个司
令员同时指挥,肯定会乱成⼀团),所以只有使⽤单例模式,才能保证核⼼交易服务器独⽴控制整个流程。

2、代码:
public class Singleton { 

/* 持有私有静态实例,防⽌被引⽤,此处赋值为null,⽬的是实现延迟加载 */ 
private static Singleton instance = null; 

/* 私有构造⽅法,防⽌被实例化 */ 
private Singleton() { 
} 

 /* 静态⼯程⽅法,创建实例 */ 
 public static Singleton getInstance() { 
 if (instance == null) { 
     instance = new Singleton(); 
 } 
 return instance; 
} 
 
 /* 如果该对象被⽤于序列化,可以保证对象在序列化前后保持⼀致 */ 
 public Object readResolve() { 
     return instance; 
 } 
 }

3、分类:
(1)饿汉式:类初始化时创建单例,线程安全,适⽤于单例占内存⼩的场景,否则推荐使⽤懒汉式延迟加载;
 public class Singleton{ 
     private static Singleton instance = new Singleton(); 
     private Singleton(){} 
     public static Singleton newInstance(){ 
        return instance; 
     } 
 }

(2)懒汉式:需要创建单例实例的时候再创建,需要考虑线程安全(性能不太好):
public class Singleton{ 
    private static Singleton instance = null; 
    private Singleton(){} 
    public static synchronized Singleton newInstance(){ 
        if(null == instance){ 
            instance = new Singleton(); 
        } 
        return instance; 
    } 
 }

(3)双重检验锁:效率⾼;(解决问题:假如两个线程A、B,A执⾏了if (instance == null)语句,它会认为单例对象没有创建,
此时线程切到B也执⾏了同样的语句,B也认为单例对象没有创建,
然后两个线程依次执⾏同步代码块,并分别创建了⼀个单例对象。)

public class Singleton { 
    private static volatile Singleton instance = null;//volatile的⼀个语义是禁⽌指令重排序优化 
    private Singleton(){} 
    public static Singleton getInstance() { 
        if (instance == null) { 
            synchronized (Singleton.class) { 
            if (instance == null) {//2 
            instance = new Singleton(); 
            } 
         } 
     } 
     return instance; 
    } 
}

(4)静态内部类⽅式:可以同时保证延迟加载和线程安全。
 public class Singleton{ 
     private static class SingletonHolder{ 
     public static Singleton instance = new Singleton(); 
     } 
     private Singleton(){} 
     public static Singleton newInstance(){ 
        return SingletonHolder.instance; 
     } 
 }

(5)枚举:使⽤枚举除了线程安全和防⽌反射调⽤构造器之外,还提供了⾃动序列化机制,防⽌反序列化的时候创建新的对象
 public enum Singleton{
     instance; 
     public void whateverMethod(){}
 }

4、原型模式(对⼀个原型对象进⾏复制、克隆产⽣类似新对象):将⼀个对象作为原型,对其进⾏复制、克隆,产⽣⼀个和元对象类似的新对象;


5、适配器模式(接⼝兼容):将某个类的接⼝转换成客户端期望的另⼀个接⼝表示,⽬的是消除由于接⼝不匹配所造成的类的兼容性问题。
使⽤场景:


6、装饰模式(给对象动态增加新功能,需持有对象实例):装饰模式就是给⼀个对象增加⼀些新的功能,⽽且是动态的,要求装饰对象和被装
饰对象实现同⼀个接⼝,装饰对象持有被装饰对象的实例:
使⽤场景:


7、代理模式(持有被代理类的实例,进⾏操作前后控制):采⽤⼀个代理类调⽤原有的⽅法,且对产⽣的结果进⾏控制。


8、外观模式(集合所有操作到⼀个类):外观模式是为了解决类与类之间的依赖关系的,像spring⼀样,可以将类和类之间的关系配置到配置
⽂件中,⽽外观模式就是将他们的关系放在⼀个Facade类中,降低了类类之间的耦合度。


9、桥接模式(数据库驱动桥接):桥接模式就是把事物和其具体实现分开,使他们可以各⾃独⽴的变化。桥接的⽤意是:将抽象化与实现化解耦,使得⼆者可以独⽴变化,像我们常⽤的JDBC桥DriverManager⼀样,JDBC进⾏连接数据库的时候,在各个数据库之间进⾏切换,基本不需要动太多的代码,甚⾄丝毫不⽤动,原因就是JDBC提供统⼀接⼝,每个数据库提供各⾃的实现,⽤⼀个叫做数据库驱动的程序来桥接就⾏了。


10、组合模式(部分整体模式):组合模式有时⼜叫部分-整体模式在处理类似树形结构的问题时⽐较⽅便。


11、享元模式(共享池、数据库连接池):享元模式的主要⽬的是实现对象的共享,即共享池,当系统中对象多的时候可以减少内存的开销,
通常与⼯⼚模式⼀起使⽤。当⼀个客户端请求时,⼯⼚需要检查当前对象池中是否有符合条件的对象,如果有,就返回已经存在的对象,如果没有,
则创建⼀个新对象,如数据库连接池;


12、策略模式(多种算法封装):策略模式定义了⼀系列算法,并将每个算法封装起来,使他们可以相互替换,且算法的变化不会影响到使⽤
算法的客户。需要设计⼀个接⼝,为⼀系列实现类提供统⼀的⽅法,多个实现类实现该接⼝:


13、模板⽅法模式(抽象⽅法作为⻣架,具体逻辑让⼦类实现):定义⼀个操作中算法的框架,⽽将⼀些步骤延迟到⼦类中,使得⼦类可以不改
变算法的结构即可重定义该算法中的某些特定步骤。完成公共动作和特殊动作的分离。


14、观察者模式(发布-订阅模式):当⼀个对象变化时,其它依赖该对象的对象都会收到通知,并且随着变化!对象之间是⼀种⼀对多的关
系。类似于邮件订阅和RSS订阅,当你订阅了该⽂章,如果后续有更新,会及时通知你。


15、迭代器模式(遍历集合):迭代器模式就是顺序访问聚集中的对象。


16、责任链模式(多任务形成⼀条链,请求在链上传递):有多个对象,每个对象持有对下⼀个对象的引⽤,这样就会形成⼀条链,请求在
这条链上传递,直到某⼀对象决定处理该请求。但是发出者并不清楚到底最终那个对象会处理该请求,所以,责任链模式可以实现,在隐瞒客户端的
情况下,对系统进⾏动态的调整。


17、命令模式(实现请求和执⾏的解耦):命令模式的⽬的就是达到命令的发出者和执⾏者之间解耦,实现请求和执⾏分开,熟悉Struts的
同学应该知道,Struts其实就是⼀种将请求和呈现分离的技术,其中必然涉及命令模式的思想!


18、备忘录模式(保存和恢复对象状态):主要⽬的是保存⼀个对象的某个状态,以便在适当的时候恢复对象


19、状态模式(对象状态改变时改变其⾏为):当对象的状态改变时,同时改变其⾏为。状态模式就两点:1、可以通过改变状态来获得不同
的⾏为。2、你的好友能同时看到你的变化。


20、访问者模式(数据接⼝稳定,但算法易变):访问者模式把数据结构和作⽤于结构上的操作解耦合,使得操作集合可相对⾃由地演化。
访问者模式适⽤于数据结构相对稳定算法⼜易变化的系统。因为访问者模式使得算法操作增加变得容易。访问者模式就是⼀种分离对象数据结构与⾏
为的⽅法,通过这种分离,可达到为⼀个被访问者动态添加新的操作⽽⽆需做其它的修改的效果。


21、中介者模式:中介者模式也是⽤来降低类类之间的耦合的。如果使⽤中介者模式,只需关⼼和Mediator类的关系,具体类类之间的关系
及调度交给Mediator就⾏,这有点像spring容器的作⽤。


22、解释器模式(对于⼀些固定⽂法构建⼀个解释句⼦的解释器,如正则表达式):解释器模式⽤来做各种各样的解释器,如正则表达式等的
解释器。


23、建造者模式(创建复合对象):⼯⼚类模式提供的是创建单个类的模式,⽽建造者模式则是将各种产品集中起来进⾏管理,⽤来创建复合对
象,所谓复合对象就是指某个类具有不同的属性

上一篇 下一篇

猜你喜欢

热点阅读