关于设计模式的理解与介绍已经有很多大牛写出了非常优秀的文章,所以仅在此记录自己的学习过程与总结。
这是我参考学习的一个系列博客http://www.cnblogs.com/justinw/archive/2006/11/28/574573.html,在此对博主表示衷心的感谢!
参考书籍《HeadFirst设计模式》。
废话不多说了,进入正题:
1、找到系统中变化的部分,将变化的部分同其它稳定的部分隔开;
2、面向接口编程,而不要面向实现编程;3、优先使用对象组合,而非类继承;
4、类应该对扩展开放,对修改关闭;
5、单一责任:一个类应该只有一个引起变化的原因;
Context(应用场景):
需要使用ConcreteStrategy提供的算法。
内部维护一个Strategy的实例。
负责动态设置运行时Strategy具体的实现算法。
负责跟Strategy之间的交互和数据传递。
Strategy(抽象策略类):
定义了一个公共接口,各种不同的算法以不同的方式实现这个接口,Context使用这个接口调用不同的算法,一般使用接口或抽象类实现。
ConcreteStrategy(具体策略类):
实现了Strategy定义的接口,提供具体的算法实现
总结:策略模式使用在这样的场景中,B是A的一部分,但B可能有多种不同的实现方式,如果不加处理,那么之后如果B增加了实现,那么就要重新写一个A类来实现这个不同的B,随着扩展的加深,我们就会看到自己的包里有A1.java、A2.java……像这样的文件就会越来越多。而策略模式就是先将B抽象出来,使得A只需要包含一个B的抽象,待到具体应用时再将A中的B实例化,而B的实现则可以在A之外随意扩展。
就像三国演义里诸葛亮给赵云的锦囊妙计一样,为了保护要去吴国的刘备,诸葛亮在临走前给了赵云三个锦囊,说在危急的时刻拿出来看一下便可化险为夷。这里即可看做是一个策略模式。对赵云来说,给他的计策是变化的,诸葛亮要把计策教给赵云,最简单的就是在临走前把计策都给赵云说一遍,这样就会有知道计策一的赵云、知道计策二的赵云等等,要是计策多了那诸葛亮可能就得说上个一两天,这么做还有个问题,就是如果诸葛亮哪天有个新想法他都要和赵云说一遍,如果情况有变有一些计策不用了那他就白费口舌了。不科学!所以诸葛亮想到了用锦囊,对赵云来说这个锦囊就是个抽象,他不需要知道具体细节,只需要知道怎么打开锦囊看内容就可以了,而这里就只有一个知道怎么打开锦囊的赵云,于是诸葛亮为赵云准备了三个锦囊,到了吴国,赵云眼看情况不对,拿出第一个锦囊,这里就相当于将锦囊实例化了,然后赵云打开锦囊读内容,这里就相当于实例化了一个知道计策一的赵云,之后赵云执行计策内容,大功告成!
所以这里赵云 = Context,锦囊 = Strategy,(锦囊一、二、三)= ConcreteStrategy。
规定ConcreteSubject的统一接口;
每个Subject可以有多个Observer;
ConcreteSubject(具体被观察对象)
维护对所有具体观察者的引用的列表;
状态发生变化时会发送通知给所有注册的观察者。
Observer(观察者接口)
规定ConcreteObserver的统一接口;
定义了一个update()方法,在被观察对象状态改变时会被调用。
ConcreteObserver(具体观察者)
维护一个对ConcreteSubject的引用;
特定状态与ConcreteSubject同步;
实现Observer接口,通过update()方法接收ConcreteSubject的通知。
总结:观察者模式可以看做是现实中的报纸订阅模式,客户是观察者(Observer),报社是被观察者(Subject),客户要看报纸了解各种新闻事件,就首先要向报社订阅要看的报纸,这样只要出了新报纸,报社就会把报纸送到客户手上。
总结:装饰者模式主要用于灵活扩展类对象的功能,而不需要通过继承来实现。该模式的核心部分在装饰者(Decorator),他继承自Component(被装饰对象),同时还包含了一个Component的引用,这么做使得装饰者的本质不发生变化,可以继续被装饰,也就是说装饰者同时可以做为被装饰者。举个例子,咖啡是一个被装饰者,是一个基类(Component),黑咖啡是他的一种具体对象(Concrete Component)。现在我们想给黑咖啡装饰一下,加些牛奶,得到加牛奶的黑咖啡。关键就在这里,加了牛奶的黑咖啡的依然是咖啡,也就是他的本质没有变化,这样就可以继续进行装饰,比如加糖变成加糖加牛奶的黑咖啡。具体做法就像上面的类图展示的,先定义一个装饰者抽象类(Decorator)--咖啡装饰类;然后继承得到具体的装饰类(Concrete Decorator)--加牛奶咖啡装饰类,加糖咖啡装饰类。这样只要将咖啡类的实例作为参数传入装饰者,就可以得到装饰了的对象,大功告成!装饰者的一个典型的应用即是java中的I/O类的应用,inputstream、outputstream。