设计模式

[size=medium][color=blue]单例模式[/color]

一, 单例模式就是,一个类在java虚拟机有且只有一个实例存在。

它按需求实例化,无论多少条线程需要它,

当它第一次实例化以后,就不会再实例化了,直接返回以生成对象。解决了内存消耗大的原因。

它的缺点就是:因为是单例的,增加了锁机制,降低了效率。

我打个比方来说下单例模式吧(例子:打印机,无论多少人需要打印,一次只能一个人使用)

二,实现单例模式的一般步骤
1.首先提供一个私有的构造函数,使别的类不能实例化它,只能提供给本类使用。

2.提供一个私有的静态的类变量

3.提供一个为外部得到这个对象的公共的,静态方法,但这个方法必须设计成同步,因为当很多线程同时访问这个方法的时候

如果创建对象速度较慢,那么可能产生多个实例。就不符合单例类,只生成一个对象的原则了。)

4.判断是否类变量是否为null,如果是Null就通过私有化构造方法new一个对象,如果不是直接返回类变量。

三.单例类又分为饿汉式单例类,和懒汉式单例类。登记式单例

1.什么是懒汉式单例:第一次被调用的时候,就已经生成了实例,以后直接使用这个实例。

优点:按需求实例化。节约资源
缺点:增加了锁机制,对效率有些影响。

2.什么是恶汉式单例:每次调用静态工厂方法的时候都创建实例对象。

优点:简单,不用考虑同步,并发问题
缺点:当系统部找单例模式的时候就浪费资源了。

四.单例模式的特点:

1.单例类只有一个实例,

2.单例类必须自己创建自己的唯一实例。

3.单例类必须给所有其他对象提供这一实例。

[color=blue]模板模式[/color]

定义:父类定义流程,子类去实现,

原则:这里有一个很重要的原则就是父类里面的定义流程的方法,必须是final修饰,不能让子类去重写

解决的问题:比如说我们在项目中的jdbc实现,根据id删除表一条数据,唯一不同的就是表名,所以我们可以

在父类里面定义删除的流程,再通过一个抽象方法,强制子类实现,由子类提供表名;

这样我们可以直接使用父类的流程,就减少子类的很多重复代码。提高流程的复用率。

[color=blue]策略模式[/color]

概念:就是得到一个功能,有多种不同的实现方法。

比如说我买一件衣服,可以网购,也可以去专卖店,这样都能达到买到衣服的结果。

拿我们项目中来说,有时候我们需要把dao层的实现habernate更换成ibatis。这样用策略模式就非常好。

我们定义一个顶级接口,由DAO的实现类去实现,定义一系列的算法,把它们的实现一个个封装起来,

这样很容易的就能让它们进行替换

解决问题:解决了多种可选择的实现。

[color=blue]简单工厂模式[/color]

工厂模式一般是基于接口的。

概念:它专门定义一个类来负责创建其他类的实例,也就是封装了new关键字生成对象。

1 它封装了其他对象创建的过程,在service层调用dao层的方法,我们可以通过工厂模式。

直接从工厂里得到dao实例。不需要在Service层new一个dao的对象,解决了service和被dao的耦合度。

但是service层还是要定位工厂,使service层又和工厂有耦合了,最好的方式就是使用Spring框架的DI思想。

2 有利于同类对象创建的统一管理和控制,如果更换实现的话,那么就直接修改工厂就行了。

[color=blue]观察者模式[/color]

定义:定义对象间的一种一对多的依赖关系,我们是让多个观察者对象同时监听某一个主题对象。

这个主题对象在状态上发生变化时,会通知所有观察者对象,并进行更新

解决问题:解决多个对象间相互依赖关系的相互通知。

例子:比如说一个模型对应多个视图,(这里的视图是一些显示方式,表单显示,文本显示)

所有的视图监听模型的变化,如果一个视图改变了模型的一些数据,

那么所有依赖模型的视图也会发生相应的更新

在增加一个视图也就是观察者对象,如果是自定义观察者模式,

写个类直接实现视图的公共的接口就行了,如果是基于jdk实现的话,那么要实现observer接口。

重写它的update方法,这样可扩展性非常的强,也不需要修改模式的源代码,

符合我们的对外扩展时开放的,对内修改时封闭的原则。

在项目中我们一般都是自定义观察者模式的,如果基于jdk的实现的话,如果jdk发生版本更新,

那么可能导致项目的不兼容性。

项目中怎么用的:

我以前参与开发过一个网上书城系统,就是用了观察者模式其被观察者是书,

订阅者是观察者,当书城增加一些新书的时候,

会通知手机订阅者,或者网上订阅者。

它的优点:实现了表示层与数据逻辑层的分离。

它的缺点:如果一个主题对象有很多直接和间接的观察者的话,将所有的观察者都通知到会花费很多时间。

[color=blue]组合模式[/color]

1.组合模式的定义:将对象以树形结构组织起来,以达到“部分与整体”的层次结构,使客户使用单个对象和组合

对象的具有一致性。

2.解决问题:树形结构的方案。

4.例子:我们有些管理系统中,总会出现总公司里面很多分公司,分公司下面有很多部门,部门又有很多员工,

如果我们公司效益好,需要集体加薪,不需要每个的进行加薪的方法,直接在根节点上加就行了,

与它有关的子节点都会进行相应的操作。

如果我们分公司增加一个部门,

加到节点里面去就行了,不需要修改模式的源代码,符合我们的

对外扩展是开放的,对内修改时封闭的原则。

3.适用性:
<1>表示对象的部分-整体层次结构
<2>忽略组合对象与单个对象的不同,用户将统一地使用组合结构中的所有对象

[color=blue]命令模式[/color]

定义:命令模式就是将一个客户端请求封装成一个对象,

解决问题:它使我们只关心行为,无需了解接收这个请求的处理细节,

好处:1.这样就隐藏了具体实现,使代码看起来更加安全

2.解决了发送者与接收者的耦合关系,因为使用命令模式,那么发送者就无需知道接受者的任何接口。

缺点:就是使简单的东西复杂化了。因为它使用了第三方来调用接受者方法进行处理。

例子:在我们实际中,一些文本编辑器的快捷方式,当我们使用的时候,其实它就是通过命令模式对这个命令进行了封装

我们可以不用关心它具体是如何实现的。知道如何执行就可以了。

项目中的使用:
1.我们首先会定义一个命令角色:也就是声明执行操作的接口,定义一个执行方法

2.再写一些具体命令角色:也就是每一个动作都绑定到的类,这个类是实现命令角色这个接口,

并重写它的执行方法。

3.这样我们可以直接使用命令模式了。

[color=blue]门面模式[/color](外观模式)

门面模式:就是为子系统中的各类提供一个简明一致的界面,

好处:隐藏子系统的复杂性,使子系统更加容易使用。

减少了客户程序和子系统之间的耦合,增强了可维护性。

解决的问题:子接口繁多,调用复杂,内部交互地方较多的问题。

例子:新生报道来说,我们会先接到通知,然后通过交通工具到学校,再到新生报道的地点,登记,缴费,核实等等,

面对这些非常繁琐的事情,如果我们不去和他们打交道,现在的大学生一般让父母陪同去,有父母帮我们负责这些事情,

我们只要跟父母打交道,父母就相当于一个门面。

拿我们项目中来说,在我们项目中的jdbc操作数据库执行sql语句,

通常先会得到连接,得到statement对象,执行sql,再关闭等。

如果我们把它抽取出来,封装在一个类里面。以后可以直接调用,非常简便

[color=blue]装饰模式[/color]

定义:
动态地给一个对象添加一些额外的职责

解决问题:
一个对象需要经常动态增加属性或职责

特征:
1.被装饰的对象和装饰器实现共同的接口。

2.装饰器持有一个被装饰的实例。
例子:比如说一部手机,在接受来电的时候,会发出声音提示主人,而现在我们需要为该手机增加

一项功能,在接受来电的时候,不仅发声,而且振动,还有灯光闪烁。这时候用到装饰器模式就

非常好了,它是在不修改原功能的情况下,添加了新增的功能。可扩展性非常强

在项目中使用:
定义一个接口,被装饰的类,和装饰器都需要实现它,这个装饰器我们把它设置为抽象类,

并提供一个抽象增加功能方法供子类实现,如果我们想增加一个职责就生成一个类继承这个抽象类

并重写它的方法就可以了。

[color=blue]状态模式[/color]

定义:状态模式就是不同的状态,有不同的行为,或者说:每个状态有着相应的行为。

例子:手机设置的情景模式有多种:标准 安静 振动 耳机,不同的情节模式对应不同的响铃及或振动方式
(电子琴有很多按键,不同的按键发出与之相对应的声音。电子琴的声音就相当于属性,而电子琴按键就相当于状态了)

解决问题:主要解决状态更换频繁的一些问题

优点:封装了转换过程,也就是转换规则。它是一个类代表一个行为,解决以前我们的if,else进行状态切换的耦合度。

使代码更加容易维护。

[color=blue]链模式[/color]

定义:为了避免发送者和接受者之间的耦合关系,使多个接收对象都有机会处理请求,将这些对象连成一条链,

并沿着这条链传递该请求,直到有一个对象处理它为止。这就是链模式

例子:比如有一个作业任务,先有一个对象对其负责处理,之后又交给其他的一个对象处理,

一次传递下去,这是最通俗最简单的责任链模式的应用。

在我们实际项目当中jsp,Servlet的filter就是使用了链模式。

解决问题 :组织处理复杂的流程。

1 有多个的对象可以处理一个请求,哪个对象处理该请求运行时刻自动确定。

2 你想在不明确指定接受者的情况下,向多个对象中的一个提交一个请求。

3 可处理一个请求的对象集合应该被动态指定。

优缺点: 1.降低耦合度 职责链可以简化相互之间的连接, 增强了给对象指派职责的灵活性,
2.当这个链结构比较长,比较复杂的话,会产生很多的内存垃圾对象。

让我们来看一下链表的典型特征:

1. 链表是一个链状结构,每个节点有一个next属性去指向他的下一节点。

2. 链表有一个Header节点,然后用户每次必须通过头节点,然后去遍历寻找每一个节点。

3. 链表遍历操作的复杂度是O(n),但是插入和删除指定节点的复杂度是常数级。

[color=blue]抽象工厂[/color]

定义:提供一个创建一系列相关或相互依赖对象的接口,则无需指定它们具体的类。

解决的问题:产生相互依赖的一系列结果。

例子:苹果 北方苹果, 南方苹果。
用途:一个系统要独立它的产品而创建,组合,和表示时.
2.一个系统要由多个产品中的一个来配置时。
3.当你要强调一系列相关的产品对象的设计以便进行联合使用时。
4.当你提供一个产品类库,而只想显示它们的接口而不是实现时。

[color=blue]适配器模式[/color]

定义: 适配器模式又称变压器模式。将一个类的接口转换成客户希望的另外一个接口,

它主要是将两个不相关的类,提供一个中间类,让它们可以在一起使用。而不修改它们的源代码。

解决的问题:已经存在类似功能的类或接口,但是方法的签名不一样。

例子:Windows的纸牌游戏未经修改,便在Linux运行。可以知道这个游戏提供了从Windows到Linux

图形界面的适配器,它使Linux的图形界面能在Windows下面运行,这样就不需要修改任何的图形界面,

便可以使两者兼容。

适用性:你想使用一个已经存在的类,但它的接口不符合你的需求。

你想创建一个可以复用的类,该类可以与不相关的类或不可预见的类协同工作。

你想使用一些已经存在的子类,但是不可能对每一个都进行子类化以匹配它们的接口,对象适配器可以

适配它的父类接口。

类适配器和对象适配器:对象适配器要好些,因为它是引用别的接口的,类适配器时实现它们的接口的,

容易产生接口污染。体现了组合优于继承的思想。

[color=blue]构建模式[/color]

定义:对类的实例化进行了抽象,

目的:将一个复杂对象的构建,与它的表示分离,使得同样的构建创建过程可以创建不同的表示。

适用性:当创建复杂对象的算法应该独立于该对象的组成部分以及它们的装配方式时。

当构建过程必须允许被构建的对象有不同的表示时。

[color=blue]代理模式[/color]

定义:为其他对象提供一个代理来控制对这个对象的访问,也就是说我们是通过代理对象来调用真实对象。

作用:一个客户不想或者不能够直接去引用一个对象,而代理对象就可以在客户端和目标对象之间起到中间的作用

例子: 再举个通俗的例子,你想找某局长帮你做一件事情,但局长官位显赫,你又不能轻易见着,

你就想到了找他的秘书,通过她传话给局长,这样你就等于请他的秘书帮你办成了那件事。

秘书为什么就可以找到局长呢,因为秘书和局长之间有一定的关系。

项目中的使用:在以前做过的一个每日英语系统中,在执行一些操作之前,总要进行一些权限判断,

这里我就使用了代理模式,直接通过代理来判断是否符合权限,如果符合就执行真实对象。

这样就不需要在每个执行流程前,都进行权限判断,减少了耦合度。

[color=blue]中介者模式[/color]

定义:用一个中介对象来封装一系列的对象交互,通俗的来说就是将两个相互引用的对象通过一个中间类来实现。

例子:房屋中介所。

+1解决的问题:在软件构建过程中,经常会出现多个对象相互交联交互的情况,对象之间常常会

维持一种复杂的引用关系,如果遇到一些需要的更改,这种直接的引用关系,将面临不断变化。

在这种情况下,我们可使用一个“中介对象”来管理对象间的关联关系,

作用:避免相互交互的对象之间的紧耦合引用关系,从而更好地抵御变化。

-1解决的问题:一组对象以定义良好,但是复杂的方式进行通信,产生的相互依赖关系结构混乱且难以理解。

一个对象引用其它很多对象,并且直接与这些对象通信,导致难以复用该对象。

想定制一个分布在多个类中的行为,而又不想生成太多的子类。

与门面模式的区别:门面模式是界于客户程序跟子系统之间的,而中介者模式是基于子系统与子系统之间的。[/size]

1,单一职责原则

2,开关原则

3,里氏替换原则

4,依赖倒置原则

5,接口隔离原则

6,迪米特法则

1.单一职责原则(策略模式):一个类或者方法只能做一件事情,

应用:在构造对象时,将对象的不同职责分离到两个到多个类中,确保引起该类变化的原因只有一个。

例子:在我们的状态模式中,每个状态都有与之相对应的行为。这就很好的体现了单一职责原则。

优点:提高内聚,减少耦合度。

缺点:可能会导致资源文件过多,而管理不便。

2.(Open-close-principle 开关原则)体现的模式:策略模式,装饰器模式,模板模式

对扩展是开放的,对修改是封闭的,即在不修改源码的情况下对其进行扩展,

我们的面向接口编程,这就有效的体现了这一原则。

比如说我们的一个项目需要进行增加一个功能。就增加一个实现类就可以。不需要修改它的源代码。

好处:提高了灵活性,可重用性,可维护性。

难点:OCP的关键是抽象父类,或者接口,创建正确的抽象发费时间和精力,也增加了软件设计的复杂性。

正确的做法:只对程序中频繁变化的做出抽象。

3.里氏替换原则(LSP)(工厂模式)

定义:用子类去替换父类。即凡是父类能够出现的地方,子类就一定能够出现,反之则不成立。

工厂模式就很好的实现了这一原则,比如说dao层,父类并不知道是生成那一个子类的对象。

而我们的子类是知道它实现的是那个接口。

这样子类替换就非常的容易。可以在无需修改的情况下进行修改。

LSP使OCP成为可能的主要原则之一,

4.依赖倒置原则:(模板模式)

定义:高层模板不依赖于底层模板,它们都应该依赖于抽象。

抽象不应该依赖于细节,细节应该依赖于抽象。

也就是说它父类不应该依赖子类的东西。

例子:拿我们项目中来说,比如说dao,和dao的实现,我们dao层不应该知道dao实现的具体的操作。

如果dao层需要修改的话,那么还会影响到dao的实现,这样耦合度就非常的高。

5.接口隔离原则:(观察者模式)

定义:不要强迫客户依赖于它们不用的方法。

让一个类对另外一个类的依赖性应当是建立在最小的接口上的。

例子:如果我们一个类需要一些方法,避免实现方法过多的接口。

作用:避免接口污染

一个接口代表一个角色,不应当将不同的角色都交给一个接口。

6.迪米特原则 (体现了门面模式)

定义:又叫最少知识原则,一个对象对其他对象应该有尽可能少的了解,这是一个送耦合的的法则。

例子:我们在程序中通常把能私有化的属性,方法,都要尽量的私有化。

这样我们修改一些模板对其他模板的影响就少些,使代码也更加安全。

我们可以使用门面模式来实现这一原则,门面模式就是隐藏子系统的复杂性。与客户程序打交道

只有一个类而已。

缺点:在系统中造出大量的小方法,管理不要方便。
  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值