首页 > 代码库 > 设计模式

设计模式

技术分享
 

五种创建型模式

1、工厂模式

2、抽象工厂模式

3、单例模式

4、建造者模式

概述:相比较工厂模式而言,就是建造模式可以一次建造很多个对象,工厂模式一次只能建造一个。

5、原型模式

原型模式的思想就是将一个对象作为原型,对其进行复制、克隆产生一个和元对象类似的新对象,在Java中,复制对象就是通过clone()实现的,先创建一个原型类:
进行实现Cloneable接口,完成克隆,因为Cloneable接口是一个空接口,因此实现类的方法名称可以任意,但是在实现的内部就是必须调用super.clone()方法。

对于对象的复制,主要分为浅复制深复制两种:
浅复制:将一个对象复制后,基本数据类型的变量会重新创建,而对于引用类型,还是指向原来对象
深复制:当然和浅复制有区别就是完全的复制,一般需要采用流的形式读入当前对象的二进制输入,再写出二进制数据对应的对象。

七种结构模式

技术分享
 

适配器模式

对于适配模式可以分为类的适配器模式、对象的适配器模式、接口的适配器模式

类的适配器模式:

技术分享
 

对象的适配

基本思路类的适配是类似的,就是把source类不继承了,而是把source类进行实例,包含在内部。
技术分享
 

接口适配

对于接口适配就是,当我们的一个接口中有多个抽象方法时,我们再写该接口的实现时,就必须实现接口的所有方法,这明显比较浪费,也不是我们想要的,最好的办法就是我们再定义一个抽象类去实现那个接口中的方法,进行方法实现可以实现一些空方法,等到我们自己的类继承该抽象类的时候,我们就可以只关注我们需要的方法就可以了。
技术分享
 
总结:
类的适配:将一个类转换成另一个新接口的类时,可以使用类的适配器模式,创建新类,继承原有的类,实现新的接口即可。
对象的适配:当希望将一个对象转换成满足另一个新接口的对象时,可以创建一个wrapper类,持有原类的一个实例,在wrapper类的方法中,调用实例的方法就行。
接口适配:当不希望实现一个接口中的所有方法,我们可以中间新建要给抽象类,我们就只可以继承抽象类就可以。

装饰器模式的应用场景:

1、需要扩展一个类的功能
2、动态要给对象一个对象增加功能,而且还能动态撤销,
缺点:产生过多相似的对象,不易排出。

装饰模式
首先明白装饰对象和被装饰对象实现同一个接口,装饰对象持有被装饰对象的实例
技术分享
 Source类是被装饰类,Decorator类是一个装饰类,可以为source类动态的添加一些功能。
应用场景:
1、需要扩展一个类的功能
2、动态的为一个对象增加功能,而且还能动态撤销

代理模式

代理模式和装饰者模式的区别就是代理模式可以直接在内部就创建了source对象,不用到最后调用的时候才创建对象,当然创建对象的时机不同而已。
技术分享

应用场景:
1、修改原有的方法来适应,这样违反了“对扩展开放,对修改关闭”的原则
2、采用一个代理类调用原有的方法,并对产生的结果进行控制
外观模式
外观模式就是把含有相同操作或者一系列操作联动起来,好比计算机的开机和关机,其中开机就包含了CPU,内存,硬盘一起启动。关机包含了CPU,内存,硬盘关闭操作
有了computer类,他们之间的关系被放在了computer类里,这就起到了解耦,就是外观模式
桥接模式技术分享
 
桥接模式就是把事物和实现具体分开,使他们可以各自独立的变化,桥接的用意就是:将抽象化和实现化解耦,使得二者可以独立变化。像我们常用的JDBC和DriverManager一样,技术分享
通过对于Bridge类的调用,实现了对接口Sourceable的实现类SourceSub1和SourceSub2的调用,然后我可以类似的结合JDBC数据的原理,进行理解了。技术分享
组合模式
组合模式有时又叫做部分-整体模式,在处理形容树形结构的问题时比较方便,例如二叉树、对于菜单的目录结构都是可以,类似于递归一层一层
技术分享
 

享元模式

享元模式的主要目的就是实现对象的共享,即共享池,当系统中对象多的时候可以减少内存的开销,通常与工厂模式一起使用。
技术分享
 FlyWeightFactory负责创建和管理享元单元,当一个客户端请求时,工具需要检查当前对象池中是否有符合条件的对象,如果有,就返回已经存在的对象,如果没有,就创建一个新的对象,FlyWeight是超类,一提到共享池,我们就很容易联想到java里面的连接池,想想每个连接的特点,我们不难总结出:适用于作共享的一些个对象,他们有一些共有的属性,就拿数据库连接池来说,url、driverClassName、username、password及dbname,这些属性对于每个连接来说都是一样的,所以就适合用享元模式来处理,建一个工厂类,将上述类似属性作为内部数据,其它的作为外部数据,在方法调用时,当做参数传进来,这样就节省了空间,减少了实例的数量。
技术分享
 

行为模式

其中行为模式主要包含:
父类与子类的关系实现:策略模式、模版方法模式、
两个类之间关系:观察者模式、迭代子类模式、责任链模式、命令模式、
类的状态:备忘录模式、状态模式、
通过中间类:访问者模式、中介者模式、解释器模式
技术分享

 策略模式

自己理解就是:声明很多类是指实现同一个接口、继承同一个类,在实现接口中的方法时,调用父类的方法。对于不同的子类实现不同的功能。
技术分享
 
ICalculator提供同意的方法、AbstractCalculateor是辅助类,提供辅助方法。
应用场景:策略模式的决定权在用户,系统本身提供不同的算法的实现,新增或者删除算法,对各种算法做封装,因此,策略模式多用在算法决策系统中,外部用户需要决定用哪个算法即可。

模板方法模式
模板模式核心思想:声明一个抽象类,其中包含一个主方法,主方法实现对本类中其他方法的调用,其他的子方法可以为抽象方法或者实现方法,子类继承该抽象父类时,只需重写相关的抽象方法,即可完成调用。
技术分享
 
在AbstractCalculator类中定义一个主方法calculate,calculate()调用spilt()等,Plus和Minus分别继承AbstractCalculator类,通过对AbstractCalculator的调用实现对子类的调用 。

观察者模式

     在观察者模式中自己理解了一个,当一个抽象类去实现一个还有很多方法的接口的时候,此时自己原以为抽象类应该全部的实现接口里面的方法,但是实际上可以不用全部实现,可以交给去继承这个抽象类的子类来实现。
    在观察者模式中,整体结构中,主要是继承抽象类的子类去实现相关关键操作,或者调用父类中的方法,然后最后的test中声明时声明为接口,但实际指向子类的对象,进行add。remove操作。主要的内在含义就是当依赖的相关方法,当他发生变化时,我们就可以及时的收到通知,不用修改代码。
技术分享
     MySubject类就是我们的主对象,Observer1和Observer2是依赖于MySubject的对象,当MySubject变化时,Observer1和Observer2必然变化。AbstractSubject类中定义着需要监控的对象列表,可以对其进行修改:增加或删除被监控对象,且当MySubject变化时,负责通知在列表内存在的对象。

迭代子模式

在迭代子模式中意识到了在两个接口之间就可一个接口调用另一个接口
说到迭代我们自然意识到类似于链表一样,有专门表示链表之间关联关系的描述一块和内部数据一块同样在迭代子模式中,一是需要遍历的对象,即聚集对象、二是迭代器对象,用于对聚集对象进行遍历访问。
技术分享
Mycollection中定义了集合的一些操作,MyIterator中定义了一系列迭代操作,且持有Collection实例。

 在实现的过程中和Java底层的集合类的操作过程类似,做了一些优化。

责任链模式

        声明一个抽象类,在抽象类含有一个接口的引用,声明一个类继承抽象类实现那个接口,
        对于责任链就是每一个对象都持有下一个对象的引用,形成一条链,请求在这条链上传递,直到某一对象决定处理该请求,但是发出者并不清楚到底最终那个对象处理该请求。责任链模式可以实现,在隐瞒客户端的情况下,对系统进行动态的调整。
技术分享
 Abstracthandler类提供了get和set方法,方便MyHandle类设置和修改引用对象,MyHandle类是核心,实例化后生成一系列相互持有的对象,构成一条链
在链接的请求可以是一条链,可以是树,一个环,模式本事不约束这些,同时在一个时刻,命令只允许由一个对象传给另一个对象,而不允许传给多个对象。

命令模式
对于一个操作的执行,从将军下达命令,命令传输,士兵执行,这三部分进行了分离。
技术分享
 Invoke是调用者(司令员)、Receive是被调用者(士兵)、MyCommand是命令,实现Command接口,持有接受对象。
备忘录模式
主要目的就是保存一个对象的某个状态,以便在适当的时候恢复对象,个人觉得叫备份模式更形象些,通俗的讲下,假设有原始类A,A中有各种属性,A可以决定需要备份的属性,备忘录类B用来存储A的一些内部状态,类C呢,就是一个用来存储备忘录的,且只能存储,不能修改等操作。
技术分享
 Original类是原始类,里面有需要保存的属性value及创建一个备忘录类,用来保存value值。Memento类是备忘录类,Storage类是存储备忘录的类,持有Memento类的实例

新建原始类时,value被初始化为egg,后经过修改,将value的值置为niu,最后倒数第二行进行恢复状态,结果成功恢复了。其实我觉得这个模式叫“备份-恢复”模式最形象。

状态模式

对于不同的状态,显示不同的状态,执行不同操作。
技术分享
 
(今天还在想对于admin用户的操作什么的就是根据这个判断的)做网站的时候,我们有时希望根据对象的某一属性,区别开他们的一些功能,比如说简单的权限控制等。

访问者模式

访问者模式就是一个类中一个方法调用另一个类中的方法,然后又回调调用本类中的另一个方法获取一些值。
技术分享

来看看原码:一个Visitor类,存放要访问的对象,


  1. public interface Visitor {  
  2.     public void visit(Subject sub);  
  3. }  
  1. public class MyVisitor implements Visitor {  
  2.   
  3.     @Override  
  4.     public void visit(Subject sub) {  
  5.         System.out.println("visit the subject:"+sub.getSubject());  
  6.     }  
  7. }  
Subject类,accept方法,接受将要访问它的对象,getSubject()获取将要被访问的属性,
  1. public interface Subject {  
  2.     public void accept(Visitor visitor);  
  3.     public String getSubject();  
  4. }  


  1. public class MySubject implements Subject {  
  2.   
  3.     @Override  
  4.     public void accept(Visitor visitor) {  
  5.         visitor.visit(this);  
  6.     }  
  7.   
  8.     @Override  
  9.     public String getSubject() {  
  10.         return "love";  
  11.     }  
  12. }  
测试:


  1. public class Test {  
  2.   
  3.     public static void main(String[] args) {  
  4.           
  5.         Visitor visitor = new MyVisitor();  
  6.         Subject sub = new MySubject();  
  7.         sub.accept(visitor);      
  8.     }  
  9. }  
输出:visit the subject:love

该模式适用场景:如果我们想为一个现有的类增加新功能,不得不考虑几个事情:1、新功能会不会与现有功能出现兼容性问题?2、以后会不会再需要添加?3、如果类不允许修改代码怎么办?面对这些问题,最好的解决方法就是使用访问者模式,访问者模式适用于数据结构相对稳定的系统,把数据结构和算法解耦,


中介者模式

User类统一接口,User1和User2分别是不同的对象,二者之间有关联,如果不采用中介者模式,则需要二者相互持有引用,这样二者的耦合度很高,为了解耦,引入了Mediator类,提供统一接口,MyMediator为其实现类,里面持有User1和User2的实例,用来实现对User1和User2的控制。这样User1和User2两个对象相互独立,他们只需要保持好和Mediator之间的关系就行,剩下的全由MyMediator类来维护! 

技术分享
 




解释器模式

技术分享
 
Context类是一个上下文环境类,Plus和Minus分别是用来计算的实现,
解释器模式用来做各种各样的解释器,如正则表达式等的解释器等等!



















设计模式