浅谈java设计模式

在对Java的设计模式进行学习,有了一些简单认识后,本文针对Java设计模式写了一些自己的理解:设计模式是什么?为什么要使用设计模式?

设计模式(DesignPattern)是什么东西呢,百度百科是这样解释的:设计模式是一套被反复使用、多数人知晓的、经过分类编目的、代码设计经验的总结。使用设计模式是为了可重用代码、让代码更容易被他人理解、保证代码可靠性。 毫无疑问,设计模式于己于他人于系统都是多赢的;设计模式使代码编制真正工程化;设计模式是软件工程的基石脉络,如同大厦的结构一样。其实说白了,把整个项目看作一盘精心准备的菜,设计模式就相当于让这盘菜味道更甚的调味品。注意我的描述,设计模式是调味品,不是说没有它项目就一定不能成功,它更像是老一辈架构师、程序员总结出来的经验。如果只是为了让项目变得更加高大上强行加上设计模式而不顾整个系统的协调的话往往会事倍功半,不能起到设计模式应有的效果。

正确使用设计模式能让编码更轻松,让整个项目的架构思路更清晰。而怎样才算正确使用设计模式呢,从需求出发,需求是项目从开发阶段到测试阶段都需要遵循和依赖的东西,任何开发脱离需求都是没有意义的,包括设计模式。因此接下来我用一个二手书籍交易平台的实例来简单谈谈几种设计模式(设计模式一共有23种,全部讲一遍很不现实,而且有的设计模式用得很少,本人既不是很了解也觉得没有讲的必要性)。

设计模式的概念

先很仪式感地讲几个设计模式的概念:

工厂方法模式:定义一个用于创建对象的接口,让接口子类通过工厂方法决定实例化哪一个类

适配器模式:适配器模式将某个类的接口转换成客户端期望的另一个接口表示,目的是消除由于接口不匹配所造成的类的兼容性问题

桥接模式:桥接模式就是把事物和其具体实现分开,使他们可以各自独立的变化。桥接的用意是:将抽象化与实现化解耦,使得二者可以独立变化

装饰者模式:装饰模式就是给一个对象增加一些新的功能,而且是动态的,要求装饰对象和被装饰对象实现同一个接口,装饰对象持有被装饰对象的实例

迭代器模式:迭代器模式就是顺序访问聚集中的对象,这句话包含两层意思:一是需要遍历的对象,即聚集对象,二是迭代器对象,用于对聚集对象进行遍历访问。

这几个设计模式就是我将要在实例中用到的,先声明几点:

  1. 我把这个小实例做成了一个web项目,是因为本人比较熟悉web项目开发,所以把整个项目放在了springMVC的框架中,不懂的人可以先百度下,很简单的,不然很难看懂下面的代码。
  1. 为了篇幅看起来不那么吓人,我只贴了主程序的代码,所以有需要全部代码的童鞋可以私聊博主
  1. 本人其实水平有限,只是刚学完才有感而发写的东西,如果里面有什么写得不对的地方欢迎拉出来讨论

为什么使用设计模式

接下来从需求来分析一下为什么要用以上几个设计模式

a. 使用工厂方法模式是因为为了方便创建类,不再去new一个类,在项目中主要体现为根据用户的对专业和书籍类型的选择而返回代表该书籍的一个类,而这个判断和返回过程则是交给工厂方法来处理

b. 由于在书籍Book的接口里只定义了购买书这一个方法,因此在所有实现接口的子类里面都重写了购书这一方法,现在有一个特殊的类实现了每次购买书都产生日志的功能,所以需要运用适配器模式,在子类中实现接口的同时继承该特殊的类,使得被适配的类在每次购书后都可以生成日志

c. 书籍可以根据专业和类型两个层面进行分类,为了不在创建类的时候产生过多的对象,采用桥接模式另外写一个书籍类型BookType(比如工具书、课本)的接口,使得两个接口在实现类的时候可以独立变化,互不影响,同时又可以保证扩展性,在不改变原有类的基础上增加新的书籍类型(比如杂志类)的类

d. 使用装饰者模式是因为除了购买功能,系统还将实现加入购物车和加入收藏夹的功能,装饰角色Decorator实现Book接口,收藏夹类的购物车类同时继承装饰角色并实现自己的添加功能

e. 在系统中有查看所有书籍的功能,所以需要采用迭代器模式将所有的书籍遍历出来,首先自定义一个迭代器接口,里面声明了基本的迭代器方法(比如:判断是否为第一个元素,判断是否存在下一个元素等等)。然后自定义一个聚合类,在类里面采用内部类的方式定义迭代器,可以使用外部类的属性。然后遍历迭代器内所有元素获取所有书本。

下面是根据以上描述画的几个类图(为了看起来简单把所有所有属性和大部分方法去掉了):

class1

class2

class3

class4

接下来是整个Controller的代码(Controller控制页面跳转,数据传输,类的实例化,所以最重要):

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
public String home(){
return "main";
}
@RequestMapping(value="/findBook",method=RequestMethod.POST)
public String findBook(String major,String bookType,Map<String,Object>map){
Book book=BookFactory.Createfactory(major,bookType);
map.put("book", book);
map.put("major",major);
return "main";
}
@RequestMapping("/books")
public String checkAll(Map<String,Object>map){
ConcreteMyAggregate cma=new ConcreteMyAggregate();
//List<Object>cma=AggregateObj.getList();
cma.addObj("系统分析与设计");
cma.addObj("网络工程工具书");
cma.addObj("土木工程工具书");
cma.addObj("信息安全工具书");
cma.addObj("计算机科学工具书");
cma.addObj("软件工程导论");
cma.addObj("网络工程课本");
cma.addObj("土木工程课本");
cma.addObj("信息安全课本");
cma.addObj("计算机科学课本");
cma.addObj("软件工程杂志");
cma.addObj("网络工程杂志");
cma.addObj("土木工程杂志");
cma.addObj("信息安全杂志");
cma.addObj("计算机科学杂志");
map.put("books", cma);
return "books";
}
@RequestMapping(value="purchase",method=RequestMethod.POST)
public String purchase(String major,String bookType,int number,String bookName,Map<String,Object>map){
Book book= BookFactory.Createfactory(major,bookType);
String result=book.purchase(number, bookName);
map.put("result", result);
return "result";
}
@RequestMapping("addCollection/{bookName}")
public String addCollection(@PathVariable String bookName,Map<String,Object>map){
BookImpl book=new BookImpl();
CollectBook collectBook=new CollectBook(book);
list1.add(bookName);
map.put("collectBookName", list1);
System.out.println(collectBook.Collect());
return "collect";
}
@RequestMapping("addShoppingCart/{bookName}")
public String addShoppingCart(@PathVariable String bookName,Map<String,Object>map){
BookImpl book=new BookImpl();
ShoppingCartBook shoppingCartBook=new ShoppingCartBook(book);
list2.add(bookName);
map.put("ScBookName", list2);
System.out.print(shoppingCartBook.ShoppingCart());
return "shoppingCart";
}

下面是程序截图:

program1

收藏夹页面:

program2

购物车页面:

program3

总结

建一个优秀的系统最困难之处不在于编码,而是在早期做出的设计上的决定。设计是软件开发生命周期中的关键阶段,好的设计能产生好的产品,而不当的设计则会影响最终产品的质量,在此次学习中我深刻地体会到了设计模式给系统设计带来的便利,在给系统添加功能的时候轻松了许多,不会显得那么困难,不会让系统机构看起来那么松散。并且大多数设计模式还能使得系统更容易修改和维护,而究其根本就是因为他们都是久经考验的解决方案,它们的结构都是经过长期发展形成的,比新构思的解决方案更善于应对变化。而且,这些模式所用代码往往更易于理解——从而使代码更易维护。