看完headfirst设计模式,简单总结一下。

写在最前面:设计模式的关心的问题为“弹性、易于维护、易于扩展”,通过对模式的应用,让自己的代码能够得到良好的可塑性。但是个人认为不能调入为了应用模式而使用模式的陷阱当中,使用模式根本的目的依然还是解决问题,如果程序或系统本身就结构清晰等,完全不必要为了追求某一种模式而可以进行代码更改。

1.策略模式。

  将容易变化的部分从整体中分离出来,对此部分进行抽象,按照对接口编程的原则进行整理,再通过组合整合至整体中。

  优点:避免了一次继承带来的上层修改一点,后面全部都会变化很多的情况

2.观察者模式

  通过订阅的方式让对象与被订阅的对象在一定条件下自动交流。

3.装饰者模式

  不改变现有对象的基础上,通过对对象的再一次包装,使之具有更多的功能。最典型的例子莫过于java中的IO系统,通过对stream,file等的包装,让其能够适应不同的场景

4.工厂模式

  工厂模式用来封装对象创建操作,使得客户不需要去自己new 具体的对象,直接交给工厂即可,同时对于开发者而言,如果要增加新的产品,只需要修改这个工厂即可。

5.单件模式

  适用于:对象在全局中唯一,或是创建独一无二的对象。

  可使用全局变量达到此效果,但使用全局变量的缺点为需要事先在程序员中约定好。使用单件模式就会克服全局变量的缺点。

  其做法为:

  • 将独一无二的对象设置为某一类中的private static量,private可以保证除了这个类以外,其他类均不能访问,static可以保证这个量只会被初始化一次。
  • 将此类的构造函数声明为private,这样保证了只有此类内部可以进行对象的创建,外部无法进行此类对象的创建。
  • 再此类中设置一个public static方法,在这个方法中监测这个对象是否被创建,并返回这个对象,public static 方法提供外界对此类的唯一访问入口,这样就可以得到一个独一无二的对象。

  实例如下:

public class A {
private static A unique;
private A(){ }
public static A getInstance(){
if (unique==null){
unique=new A();
}
return unique;
}
}

  这样,通过此模式,确保了一个类中只有一个实例,并为外界提供了一个全局访问点。

6.命令模式 Command pattern

  如果一种情景为一个事物A请求(命令)另一个事物B,最直接的方法就是A调用B中的方法即可。但这种方法将A和B紧紧绑在一起,A需要了解B中的具体方法是什么,并且如果A若想要在请求事物C,就得在A中添加新代码,不易扩展。

  命令模式所要解决的就是让调用者(如A)与行为执行者(如B,C)解耦,A不需要知道我究竟调了哪个方法,只知道当我创建好我想要的命令后,要得到命令的执行

  

  要达到上述目的,命令模式将命令(请求)封装为接口,具体命令都来实现这个接口。客户端设置给自己设置号具体命令,然后调用接口方法执行即可。在具体命令当中,拥有相对应的执行者实例,通过复写命令的接口方法的来调用执行者中国相应的方法。而在执行者当中,只需要关心自己所能提供的功能与服务即可,不需要考虑谁来调用。(这样便可做到命令的调用和执行解耦)

  参与角色:

  1.抽象命令接口:所有具体命令皆实现此接口。

  2.具体命令:客户端所需要的具体请求或命令。

  3.客户 client:用于创建具体命令(请求),并执行这个命令中的接口方法。

  4.执行者:命令的执行者。

  打个比方来说:我到一家餐馆吃饭,即为客户,我点一盘鱼香肉丝,我所点的这个含有鱼香肉丝的订单即为具体命令,而订单则为抽象命令接口,我不需要知道谁去做,我只需要创建好这个订单并将订单提供给餐厅即可,餐厅将这个订单送给厨师,厨师即为命令的执行者,厨师看到了这份订单,自然就开始进行选择材料制作鱼香肉丝等一系列行为,厨师也不需要知道谁点了这个,只需要知道这个订单需要鱼香肉丝。

  在这个过程中,也许会有个疑问,餐厅所扮演的角色并没有在上述四种角色之中。我在学习命令模式中,大多数命令模式在客户创建完具体命令后都有个调用者(invoker),一般都在客户创建命令之后起到一个传递命令的作用,而整个命令流程可以不需要它即可完成,只是实现方面需要其参与,因此未将其列入上述参与角色当中。

  下图为简单示意图

  

7.适配器模式与外观模式

  适配器模式:适配器顾名思义就是将不同的接口进行连接,因此适配器模式要解决的最大的问题即将一个接口包装为我们需要的类型。其中涉及的角色有:

  • 客户:通俗意义上的使用者,调用者等
  • 目标接口:客户课调用的接口类型或者说是客户想要的接口类型
  • 被适配接口:现有的不符合客户要求的接口类型
  • 适配器:含有被适配接口并实现目标接口的具体类

  客户通过适配器将被适配接口转换为目标接口,然后再进行使用。用示意图表示如下:

  

  外观模式:一句话说即为将一系列具有流程性质相关性质的方法放入一个统一的方法中,使其在调用时不用再将每一个细节方法都调用一遍。这个打眼一看非常像封装,但和封装最大的区别是外观模式并不阻断用户去调用统一方法中的细节方法,用户依然可以再需要使用细节方法时使用,而封装的话则是将用户与细节方法阻断开,只给用户提供封装后的接口,用户无法调用其中的细节方法。

  外观模式虽然简单,但是其中也不是随便讲一堆方法放进去即可,为了以后的维护或者替换考虑。这里需要有一个简单的指导性原则进行一点点约束:最少知识原则。这个原则内容为:尽可能少的让对象之间的交互。这样做有一个明显的好处,当一个类需要改变时,不会太多的影响其他地方的调用。其具体指在该对象方法内,我们只应该调用属于下列范围的方法:

  1. 对象本身的方法
  2. 作为参数传进来的对象的方法
  3. 对象实例化的方法
  4. 对象的组件

  通过这四个简单原则,可以将对象之间的相互方法调用降到最低(并不绝对需要采用此原则,因为解耦的代价为增加代码量)。

  

Java 设计模式学习的更多相关文章

  1. Java设计模式学习资源汇总

    本文记录了Java设计模式学习书籍.教程资源.此分享会持续更新: 1. 设计模式书籍 在豆瓣上搜索了一把,发现设计模式贯穿了人类生活的方方面面.还是回到Java与程序设计来吧. 打算先归类,再浏览,从 ...

  2. Java设计模式学习记录-模板方法模式

    前言 模板方法模式,定义一个操作中算法的骨架,而将一些步骤延迟到子类中.使得子类可以不改变一个算法的结构即可重新定义该算法的某些特定步骤. 模板方法模式 概念介绍 模板方法模式,其实是很好理解的,具体 ...

  3. Java设计模式学习记录-状态模式

    前言 状态模式是一种行为模式,用于解决系统中复杂的对象状态转换以及各个状态下的封装等问题.状态模式是将一个对象的状态从该对象中分离出来,封装到专门的状态类中,使得对象的状态可以灵活多变.这样在客户端使 ...

  4. Java设计模式学习记录-观察者模式

    前言 观察者模式也是对象行为模式的一种,又叫做发表-订阅(Publish/Subscribe)模式.模型-视图(Model/View)模式. 咱们目前用的最多的就是各种MQ(Message Queue ...

  5. Java设计模式学习记录-备忘录模式

    前言 这次要介绍的是备忘录模式,也是行为模式的一种 .现在人们的智能手机上都会有备忘录这样一个功能,大家也都会用,就是为了记住某件事情,防止以后自己忘记了.那么备忘录模式又是什么样子的呢?是不是和手机 ...

  6. Java设计模式学习记录-迭代器模式

    前言 这次要介绍的是迭代器模式,也是一种行为模式.我现在觉得写博客有点应付了,前阵子一天一篇,感觉这样其实有点没理解透彻就写下来了,而且写完后自己也没有多看几遍,上次在面试的时候被问到java中的I/ ...

  7. Java设计模式学习记录-解释器模式

    前言 这次介绍另一个行为模式,解释器模式,都说解释器模式用的少,其实只是我们在日常的开发中用的少,但是一些开源框架中还是能见到它的影子,例如:spring的spEL表达式在解析时就用到了解释器模式,以 ...

  8. Java设计模式学习记录-命令模式

    前言 这次要介绍的是命令模式,这也是一种行为型模式.最近反正没有面试机会我就写博客呗,该投的简历都投了.然后就继续看书,其实看书也会给自己带来成就感,原来以前不明白的东西,书上已经给彻底的介绍清楚了, ...

  9. Java设计模式学习记录-享元模式

    前言 享元模式也是一种结构型模式,这篇是介绍结构型模式的最后一篇了(因为代理模式很早之前就已经写过了).享元模式采用一个共享来避免大量拥有相同内容对象的开销.这种开销最常见.最直观的就是内存损耗. 享 ...

  10. Java设计模式学习记录-外观模式

    前言 这次要介绍的是外观模式(也称为门面模式),外观模式也属于结构型模式,其实外观模式还是非常好理解的,简单的来讲就是将多个复杂的业务封装成一个方法,在调用此方法时可以不必关系具体执行了哪些业务,而只 ...

随机推荐

  1. footer绝对定位但是不在页面最下边解决方案

    方案一 html { height: 100%; } body { position: relative; min-height: 100%; box-sizing: border-box; padd ...

  2. Asp.net管道模型(管线模型)

    Asp.net管道模型(管线模型)   前言 为什么我会起这样的一个标题,其实我原本只想了解asp.net的管道模型而已,但在查看资料的时候遇到不明白的地方又横向地查阅了其他相关的资料,而收获比当初预 ...

  3. Scrum Meeting 12-20151218

    任务安排 姓名 今日任务 明日任务 困难 董元财 无 网络连接框架优化 无 胡亚坤 无 修复商品列表排列混乱) 无 刘猛 无 无 马汉虎 无 无 赖彦俞 无 无 燃尽图 团队照片 代码签入记录 今天开 ...

  4. python成长之路【第九篇】:网络编程

    一.套接字 1.1.套接字套接字最初是为同一主机上的应用程序所创建,使得主机上运行的一个程序(又名一个进程)与另一个运行的程序进行通信.这就是所谓的进程间通信(Inter Process Commun ...

  5. Toolbar设置回退箭头的方法

    Toolbar toolbar = (Toolbar) findViewById(R.id.toolbar); setSupportActionBar(toolbar); //关键下面两句话,设置了回 ...

  6. Vue刨坑

    vue常见问题 1.在自定义组件里,你可以像任何普通元素一样用v-for.eg1: <my-component v-for="item in items"></m ...

  7. Mina的ProtocolEncoderOutput之坑

    这个问题是之前测试上万个连接的pingpong发现的,调了很久,但当时急着做其他事,就没有详细记录下来,现在回想起来也有点记不清具体哪儿了. 表现是在测试上万个连接的pingpong时会出现服务器挂起 ...

  8. PHP Switch case 条件并用实例

    众所周知,Switch循环比if...else...循环效率要好的多,当case有相同代码结构的时候,怎么样来简化代码结构,能让代码更具有通用性呢? 在网上找了一下,好多都是复制粘贴,还有的看起来太复 ...

  9. Python’s SQLAlchemy vs Other ORMs[转发 3]Django's ORM

    Django's ORM Django is a free and open source web application framework whose ORM is built tightly i ...

  10. 怎么让我们自己开发的Android程序设为默认启动

    怎么让我们自己开发的Android程序设为默认启动呢?其实很简单,只要在AndroidManifest.xml文件中配置一下首次启动的那个Activity即要. <activity        ...