java设计模式之常用设计模式分析

常用的设计模式有:工厂模式(工厂方法模式,简单工厂模式,抽象工厂模式),单例模式,组合模式,模板模式,代理模式(动态代理),缺省适配器模式,装饰模式,策略模式,mvc模式

(1).缺省适配器模式:是为了一个接口提供缺省实现,这样子类型可以从这个缺省实现进行扩展,而不必从原有接口进行扩展,

是适配器模式的特例

(2).策略模式:http://yangguangfu.iteye.com/blog/815107

四、策略模式的优点

它的优点有:

1. 策略模式提供了管理相关的算法族的办法。策略类的等级结构定义了一个算法或行为族。恰当使用继承可以把公共的代码移到父类里面,从而避免重复的代码。

2. 策略模式提供了可以替换继承关系的办法。继承可以处理多种算法或行为。如果不是用策略模式,那么使用算法或行为的环境类就可能会有一些子类,每一个子类提供一个不同的算法或行为。但是,这样一来算法或行为的使用者就和算法或行为本身混在一起。决定使用哪一种算法或采取哪一种行为的逻辑就和算法或行为的逻辑混合在一起,从而不可能再独立演化。继承使得动态改变算法或行为变得不可能。

3. 使用策略模式可以避免使用多重条件转移语句。多重转移语句不易维护,它把采取哪一种算法或采取哪一种行为的逻辑与算法或行为的逻辑混合在一起,统统列在一个多重转移语句里面,比使用继承的办法还要原始和落后。

(3).策略模式的缺点

策略模式的缺点有:

1. 客户端必须知道所有的策略类,并自行决定使用哪一个策略类。这就意味着客户端必须理解这些算法的区别,以便适时选择恰当的算法类。换言之,策略模式只适用于客户端知道所有的算法或行为的情况。

2. 策略模式造成很多的策略类。有时候可以通过把依赖于环境的状态保存到客户端里面,而将策略类设计成可共享的,这样策略类实例可以被不同客户端使用。换言之,可以使用享元模式来减少对象的数量。

接口的作用是什么?定义共性

(4).组合模式:主要是

1.用来描述整体与部分的关系,用的最多的地方就是树形结构,我们先来说说组合模式的几个角色:

抽象构件角色(Component):定义参加组合的对象的共有方法和属性,可以定义一些默认的行为或属性;

比如我们例子中的getInfo 就封装到了抽象类中。

叶子构件(Leaf):叶子对象,其下再也没有其他的分支。

树枝构件(Composite):树枝对象,它的作用是组合树枝节点和叶子节点;

2.组合模式有两种模式,透明模式和安全模式,这两个模式有什么区别呢 

组合模式的优点有哪些呢?第一个优点只要是树形结构,就要考虑使用组合模式,这个一定记住,只

要是要体现局部和整体的关系的时候,而且这种关系还可能比较深,考虑一下组合模式吧。组合模式有一

个非常明显的缺点:使用了实现类而不是接口,违背了面向接口编程

(5).模板方法模式:

1.那我们总结一下模板方法模式,模板方法模式就是在模板方法中按照一个的规则和顺序调用基本方法,

具体到我们上面那个例子就是run 方法按照规定的顺序(先调用start,然后再调用engineBoom,再调用

alarm,最后调用stop)调用本类的其他方法,并且由isAlarm 方法的返回值确定run 中的执行顺序变更,

2.其中TemplateMethod 就是模板方法,operation1 和operation2 就是基本方法,模板方法是通过汇总

或排序基本方法而产生的结果集。

3.作为模板的方法定义在父类(父类为抽象类),而方法定义使用抽象方法,实现抽象方法的是子类,要在子类实现方法,

才能决定具体的操作。如果在不同的子类执行不同实现就可以发展出不同的处理内容。

不过,无论在哪个子类执行任何一种实现,处理的大致流程都还是要依照父类制定的方式。

(6).缺省适配器模式:

文章链接:http://jzinfo.iteye.com/blog/558373

1.这个时候我们可以考虑使用一个中间类来解决这个问题,这个中间类空实现接口的所有方法,

同时,我们将这个中间类定义为抽象的,使其不可能被实例化,实例化中间过渡类没有任何实际的意义。 

然后让具体的类继承这个中间类只让他覆盖自己所需的方法即可。

2.我们将这个中间过渡类称为 “缺省适配类”,这个模式也叫做缺省适配模式(Default Adapter)。

(7).装饰模式:

文章链接:http://www.iteye.com/topic/121149

优点:装饰模式和继承都是对功能的扩展,而装饰模式使用的是组合,可以不用继承而达到这一效果.使用过多的继承会增加系统的复杂性和偶合性

它通过传对象的形式(构造函数传参数)达到增强的目的,而不是继承

缺点:装饰模式要产生一些辅助性的对象,但这些对象看上去都比较像,不是很容易检查(好的命名应该是提高检查的一个办法)

(8).代理模式:

文章链接:http://www.iteye.com/topic/517835

代理模式:给某一对象提供代理对象,并由代理对象控制具体对象的引用. 

代理,指的就是一个角色代表另一个角色采取行动,就象生活中,一个红酒厂商,是不会直接把红酒零售客户的,

都是通过代理来完成他的销售业务的.而客户,也不用为了喝红酒而到处找工厂,他只要找到厂商在当地的代理就行了,

具体红酒工厂在那里,客户不用关心,代理会帮他处理. 

代理模式涉及的角色: 

1:抽象主题角色.声明了代理主题和真实主题的公共接口,使任何需要真实主题的地方都能用代理主题代替. 

2:代理主题角色.含有真实主题的引用,从而可以在任何时候操作真实主题,代理主题功过提供和真实主题相同的接口,

使它可以随时代替真实主题.代理主题通过持有真实主题的引用,

不但可以控制真实主题的创建或删除,可以在真实主题被调用前进行拦截,或在调用后进行某些操作. 

3:真实代理对象.定义了代理角色所代表的具体对象. 

java主要是通过Proxy类和InvocationHandler接口来给实现对代理模式的支持的. 

,拦截机制是代理模式的重要使用方式之一, 

除了拦截,代理模式还常用于资源加载,当我们要加载的资源很大时,我们可以让真实主题角色在后台加载资源,让代理主题角色负责处理前台的等待提示信息. 

还有就是授权机制,通过代理能拦截真实主题的能力,来控制真实主题的访问权限.

讲到代理常常要讲到动态代理, 

如果代理是静态的,那么看起来和装饰器无二,所以代理常常都和动态以及反射联系在一起,总是和语言本身的能力有关…… 

代理模式通常是对原有对象的控制,不会增加新的行为,比如说原来干什么还是干什么,常见的比如cglib加上事务机制,但是没有增加新的行为,原有的服务未变。 

但是装饰模式通常会加上新的行为,而且行为可以动态进行组合,可以有任意顺序,比如给墙刷颜色,先刷底色,再刷红色,再刷绿色,也可以先刷底色,

再刷绿色,再刷红色。 

代理模式和装饰模式都可以构造成在新类中引用对原有类,构成原有类的委托,这样就可以对原有类进行控制了,可以加新的行为,也可以加上其他控制。 

不过有一点疑问,代理者和被代理者是聚合关系吗??聚合关系是整体和局部的关系,但是离开整体局部还可以生存,比如飞机场和飞机,

代理模式两者关系,我觉得应该是依赖关系,更像是user-a关系,正因为是依赖关系,所以我们使用接口进行了解耦,而不是显示依赖直接注入实现类 

(9).适配器模式

文章链接:http://chjl2020.iteye.com/blog/262370

适配器:基于现有类所提供的服务,向客户提供接口,以满足客户的期望 

过程:

1>客户通过目标接口调用适配器方法对适配器发出请求

2>适配器使用被适配者接口把请求转化成被适配者的一个或多个调用接口

3>客户接收到调用结果,但并未察觉这一切是适配器在起转换作用

1>当需要使用一个现有的类而其接口丌符合你的要求时,就需要使用适配器模式

2>适配器模式将一个对象包装起来改变其接口,装饰者模式将一个对象包装起来增加新的行为戒责仸

3>适配器的意图是将接口转换为丌同的接口

(10).观察着模式Observer

文章链接:http://lykke.iteye.com/blog/1309952

是希望两个(或多个)对象,我们称之为Subject和Observer,当一方的状态发生改变的时候,

另一方能够得到通知。也就是说,作为Observer的一方,能够监视到Subject的某个特定的状态变化,

并为之做出反应。一个简单的例子就是:当一个用户视图中的数据被用户改变后,后端的数据库能够得到更新,

而当数据库被其他方式更新后,用户视图中的数据显示也会随之改变。

观察者模式实际上没什么高深的东西,就是运用了java的继承和接口,在被观察者的抽象类里设置一个状态标志,

通过该标志判断是否通知观察者对象。在学习该模式的同时,

我们更应该学习java的继承和接口的灵活应用,其实所有的设计模式都是继承、接口、多态的灵活应用

(11).责任链模式:

文章链接:http://haolloyin.blog.51cto.com/1177454/342166

职责链模式(Chain of Responsibility):使多个对象都有机会处理请求,从而避免请求的发送者和接收者之间的耦合关系。将这些对象连成一条链,并沿着这条链传递该请求,直到有一个对象处理它为止。

适用场景:

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

2、在不明确指定接收者的情况下,向多个对象中的一个提交一个请求;

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

不足之处:

1、对于每一个请求都需要遍历职责链,性能是个问题;

2、抽象处理者 AbstractHandler 类中的 handleRequest() 方法中使用了递归,栈空间的大小也是个问题。

 个人看法:

职责链模式对于请求的处理是不知道最终处理者是谁,所以是运行动态寻找并指定;而命令模式中对于命令的处理时在创建命令是已经显式或隐式绑定了接收者。

猜你喜欢

转载自lvwenwen.iteye.com/blog/1550391