JAVA设计模式

1.1. 什么是模式
个人感觉模式更多的是项目经验的提炼,是某种特定场景下的经验之谈。

模式是典型场景的解决方案,所谓某典型场景,为有相似目标,有相似约束,且场景具有重复性。

所以设计模式往往是发现,而不是发明。你的设计不自觉地落入到某种设计模式中,无论你事先了解这种模式与否。但若你事先了解,你则可站在巨人的肩膀上,借鉴前人的经验,设计更合理更简单的方案。

1.2. 主要模式简记
1.2.1. 策略模式
策略模式,书上的定义为:定义了算法族,分别封装起来,让它们之间可以互相替换,此模式让算法的变化独立于使用算法的客户。

如下图所示,接口MyBehavior封装了算法。Myway, Yourway为对算法的实现。而Person通过组合的方式使用了算法接口,并且提供方法setMyBehavior可动态选择具体算法。

这里写图片描述
1.2.2. 观察者模式
观察者模式,是一种很容易理解的模式。从字面上即可知大略,让对象与其它对象的变化产生联动。比较完整的定义为:定义了对象之间的一对多的依赖,这样当一个对象改变状态时,它的所有依赖者都会收到通知并自动更新。也可从下图获得比较直观的理解。
这里写图片描述
一个参考的实现为如下图。Observerable和Observer接口分别为被观察者和观察都需要实现的接口。具体功能见代码。ObData为被观察者,Ob1为观察者。
这里写图片描述
在JAVA中,已经内置了观察者模式,java.util包包含了最基本的Observer接口和Obserable类,使使用观察者模式时更为方便,因为许多功能都已在包内准备好了。并且其update的方法更具灵活性:update(Observable o, Object arg),通过Object arg,它可以传递任何数据对象给观察者。(PS,使用方法和上面也略有差异,主要表现在notifyObservers之前需要调用setChanged方法,标记状态已经改变的事实)。同时也有缺点,由于java.util中的Obserable是一个类,而不是接口,而java不支持多重继承,所以其复用潜力有限。

1.2.3. 装饰者模式
装饰者模式动态地将责任附加到对象上,若要扩展功能,装饰者提供比继承更有弹性的替代方案。

在装饰者模式中,装饰者和被装饰者必须是同类型的,因为装饰者必须能够取代被装饰者,因此需要相同的接口,通过继承可以达到类型匹配。与继承相比,装饰者模式的优点为灵活,因为继承则类的行为只能在编译时静态决定,而装饰者可以在任何时候实现新的装饰者,增加新行为。缺点为产生很多小类,过度使用会让程序变得更复杂。

一个参考的实现如下图,通过Toy, Pen去装饰商品,可方便地改变cost行为,方便地获得商品总额。
这里写图片描述
1.2.4. 工厂模式与抽象工厂模式
工厂模式定义了一个创建对象的接口,由子类决定要实例化的类是哪一个。工厂主法把类的实例化推移到子类

抽象工厂模式提供一个接口,用于创建相关或依赖对象的家庭,而不需要明确指定具体类。

从字面上工厂模式和抽象工厂模式不易区分,前者创建对象,后者创建“家庭”。更简单的理解为,抽象工厂是定义一个负责创建一组产品的接口,而不是一个产品。而这个接口内的每个方法负责创建一个产品。工厂使用继承,而抽象工厂使用对象的组合来达到它的目的。同时抽象工厂也常常使用工厂方法来实现具体工厂,即创建那一个个产品。

工厂模式一个重要的作用为使用者和特定实现“分离/解耦”,它的实现方式也很好理解。工厂模式的一个参考实现如下,当需要一本英文的故事书时:BookFactory myFactory = new EnglishBookFactory(); Book myBook = myFactory.createBook(“story”);
这里写图片描述
一个简单的抽象工厂模式实现如下。工厂需要生成一个丛书系列(包含一小说,一诗集),而非单本书。中文出版工厂和英文出版工厂为工厂具体实现。出版社负责创建所有子产品。子产品的实例化也可以套用工厂模式生成具体的某个产品(如一小说),如示例中的英文出版社所示。
这里写图片描述
1.2.5. 单例/Singleton模式
单例模式最直白,确保一个类只有一个实例,并提供一个全局访问点,它主要作用于一些需要全局唯一的对象,比如管理器。此模式最主要的问题是,如何在多线程下保证创建后,对象唯一。如果应用不存在多线程并发场景,则实现会超简单。

下图为一个参考实现,它考虑到了多线程的场景。但在多并发时,速度有点慢,因为大家都需要在方法处等待。如果应用有高并发和提高性能的需求,可以通过instance静态初始化时创建实例,则getinstance方法中直接返回instance。或者将同步的锁放进入方法里面,或者让仅有小部分线程进入同步锁。
这里写图片描述
1.2.6. 适配器模式
适配器模式可以看成两个接口的粘合剂,即类似于现实生活中的转换接头。适配器使用被适配者接口,把用户请求(通过目标接口调用适配器)转换为一个或者多个被适配者的调用接口。书中定义为适配器模式将一个类的接口,转换成客户期望的另一个接口,适配器让原本接口不兼容的类可以合作无间。

下图为一个参考实例,通过适配器用户也可能通过Target接口使用Adaptee的方法/接口。
这里写图片描述
1.2.7. 外观模式
使用外观模式是为了通过实现一个更简单合理的接口的外观类,将一个有着复杂子系统/类的系统更为易用。书中的定义为提供了一个统一的接口,用来访问子系统中的一群接口。外观定义了一个高层接口,让子系统更容易使用。

下图为一个参考实例。从参考实例来看,似乎适配器模式和外观模式挺像。虽然在这个实例中facecade没有implements一个interface,但这并不表明它不可以,只是为了代码简便的缘故。两者的区别觉得可以从以下两点区别。1)适配器的target接口是历史的遗留,或者target的使用者创造者和adaptee的创造者存在一定的交互上的困难(时间上、地点上),而facecade的接口往往是A,B的设计者完成的,因此它考虑的是易用性,而不是和历史代码的兼容整合问题。2)适配器模式中被适配者往往对应的是一个接口(但不绝对),而外观模式中必须要整合一群接口才有意义。(这一点区分度不是太好,但更易量化)
这里写图片描述
1.2.8. 模板方法模式
此模式在一个方法中定义一个算法的骨架,而将一些步骤延迟到子类中。模板方法使得子类可在不改变算法结构的情况下,重新定义算法中的某些步骤。
此模式从示例代码中最容易理解。如下:
这里写图片描述
1.2.9. 状态模式
用if else或者switch来编写状态机存在问题包括,但状态较多,转换条件较多时此函数会变得复杂庞大不易维护。状态模式就是针对此种情况,将状态抽象成对象。将众多的条件语句拆分到各个对象中。状态模式书中定义为允许对象在内部状态改变时改变它的行为,对象看起来好像修改了它的类。此定义不太好理解。
个人感觉来看,状态模式并不能减少代码量,甚至会增加代码量。但代码的可读性,弹性上面有所提高,让代码看上去更“干净”。
一种示例代码如下
这里写图片描述

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值