历久弥新:SSH框架结构的简单优化过程

随手记录一下大学两年来对SSH框架的一些认识。

第一次接触到SSH框架是在大二的暑假,因为偶然的机会答应了老师使用SSH框架进行一个二手书交易网站的项目开发,由于第一次接触框架,只能简单的根据网络上各种简单的例子进行扩充(换种叫法:面向百度的编程),从而实现相应的功能。下面是项目在IDE里的结构图:

整个项目后端仅简单的分为了三大块:ACTION层负责业务处理和功能实现,DAO层为模型类以及POJO类和SERVICE层。简单的用PACKAGE来区分了层次,使得整个项目的结构显得非常繁琐,复杂。我想绝大部分初学者或者初次接触SSH框架的同学都会将框架搭建成上述的样子,然后就是在每个ACTION类里不断的添加各种五花八门的方法,去实现所需的功能。

简单的分析一下上面的结构存在的问题:

①Hibernate逆向生成的各种POJO类和实体类随意的糅合在了一个package下,而且只要你点开每一个表格对应的DAO类,里面的代码几乎都相似,都是对应表格的增删查改方法,代码重复率太高。

②Hibernate实体类映射文件也放在了DAO包下,不符合软件工程开发规范。

③Service层下每个接口及其实现类的方法近乎类似,大部分都是对应着查找单个记录,查找所有记录,以及增删查改的方法,均为直接调用的Dao层里的具体方法,使得Service层显得冗余,(几乎说可以直接删掉Service层,action类直接操作Dao中的方法也没问题)。

总的来说,代码重复率过高以及冗余,各层次实现功能不清晰是这次SSH框架结构上存在的问题。

那么具体里面的代码质量如何呢,下面就由部分截图来进行说明:

①首先先看Struts.xml文件:

由于当时对SSH框架理解不深,针对每一个Action类里面的方法,我均只配置了一个return的值“SUCCESS”,并且每一个方法我都在Struts.xml里添加了跳转目标,导致该文件看起来十分的凌乱,可改善的地方非常的多。

②查看Spring配置文件applicationContext.xml

上面第一个截图里的Spring配置毫无问题,分别是配置了数据源,开启事务以及hibernate层映射文件的引入,当然也是存在可以优化的地方。

但是第二个截图里的Spring配置我相信大家都能看出问题了,将Dao层里的DAO类以及Service类甚至是Action层中的action类均全部配置在了bean里。只要是熟悉SSH框架或SpringMVC的朋友都知道这是非常没必要的做法,导致配置文件过于长杂。因此这里是重点优化的地方。

③Action层中的一个具体方法展示:

  1 package Action;
  2
  3 import java.util.List;
  4
  5 import javax.servlet.http.HttpSession;
  6
  7 import org.apache.struts2.ServletActionContext;
  8
  9 import Dao.Book;
 10 import Dao.Page;
 11 import Dao.Purchase;
 12 import Dao.Shopcar;
 13 import Dao.Users;
 14 import Service.BookService;
 15 import Service.PurchaseService;
 16 import Service.ShopCarService;
 17
 18 import com.opensymphony.xwork2.ActionSupport;
 19
 20 public class ListItemAction extends ActionSupport {
 21     /**
 22      *
 23      */
 24     private static final long serialVersionUID = 1L;
 25     private List<Shopcar> list;
 26     private Shopcar shopCar;
 27     private ShopCarService shopCarService;
 28     private Users users;
 29     private Book book;
 30     private BookService bookService;
 31     private PurchaseService purchaseService;
 32     private Purchase purchase;
 33
 34     public Purchase getPurchase() {
 35         return purchase;
 36     }
 37
 38     public void setPurchase(Purchase purchase) {
 39         this.purchase = purchase;
 40     }
 41
 42     public PurchaseService getPurchaseService() {
 43         return purchaseService;
 44     }
 45
 46     public void setPurchaseService(PurchaseService purchaseService) {
 47         this.purchaseService = purchaseService;
 48     }
 49
 50     private Page page;
 51
 52     public Page getPage() {
 53         return page;
 54     }
 55
 56     public void setPage(Page page) {
 57         this.page = page;
 58     }
 59
 60     public BookService getBookService() {
 61         return bookService;
 62     }
 63
 64     public void setBookService(BookService bookService) {
 65         this.bookService = bookService;
 66     }
 67
 68     public Users getUsers() {
 69         return users;
 70     }
 71
 72     public void setUsers(Users users) {
 73         this.users = users;
 74     }
 75
 76     public Book getBook() {
 77         return book;
 78     }
 79
 80     public void setBook(Book book) {
 81         this.book = book;
 82     }
 83
 84     public List<Shopcar> getList() {
 85         return list;
 86     }
 87
 88     public void setList(List<Shopcar> list) {
 89         this.list = list;
 90     }
 91
 92     public Shopcar getShopCar() {
 93         return shopCar;
 94     }
 95
 96     public void setShopCar(Shopcar shopCar) {
 97         this.shopCar = shopCar;
 98     }
 99
100     public ShopCarService getShopCarService() {
101         return shopCarService;
102     }
103
104     public void setShopCarService(ShopCarService shopCarService) {
105         this.shopCarService = shopCarService;
106     }
107
108     // 往购物车中添加商品,并且检验是否有相同商品已经在购物车中
109     public String execute() throws Exception {
110         if (null == page) {
111             page = new Page();
112         }
113         boolean b = true;
114         book = this.bookService.findByBookId(book.getBookId(), page).get(0);
115         HttpSession session = ServletActionContext.getRequest().getSession();
116         this.users = (Users) session.getAttribute("user");
117         this.list = this.shopCarService.findAllItems(this.users);
118         // 查询此书本是否已经存在于购物车中
119         for (Shopcar s : list) {
120             if (s.getBook().getBookId().equals(book.getBookId())) {
121                 b = false;
122             }
123         }
124         if (b) {
125             this.shopCar.setBook(this.book);
126             this.shopCar.setUsers(this.users);
127             java.util.Date currentTime = new java.util.Date();// 将时间格式化,便于录入数据库
128             java.sql.Date date = new java.sql.Date(currentTime.getTime());
129             this.shopCar.setAddDate(date);
130             this.shopCarService.save(this.shopCar);
131             return SUCCESS;
132         }
133         return ERROR;
134
135     }
136
137     // 将购物车的物品添加到确认支付的物品清单中
138     @SuppressWarnings("unchecked")
139     public String purchase() {
140         HttpSession session = ServletActionContext.getRequest().getSession();
141         list = (List<Shopcar>) session.getAttribute("itemList");
142         for (int i = 0; i < list.size(); i++) {
143             this.purchase = new Purchase();
144             this.purchase.setBook(list.get(i).getBook());
145             this.purchase.setBuyDate(list.get(i).getAddDate());
146             this.purchase.setUsers(list.get(i).getUsers());
147             this.purchase.setNum(list.get(i).getNum());
148             this.purchaseService.save(purchase);
149         }
150         list.clear();
151         session.setAttribute("itemList", list);
152         return SUCCESS;
153     }
154
155     // 购物车中的删除操作
156     public String delete() throws Exception {
157         this.shopCarService.delete(this.shopCar);
158         return SUCCESS;
159     }
160
161     // 显示某个用户的购物车
162     public String findByUserName() throws Exception {
163         HttpSession session = ServletActionContext.getRequest().getSession();
164         users = (Users) session.getAttribute("user");
165         this.list = this.shopCarService.findAllItems(this.users);
166         session.setAttribute("itemList", list);
167         return SUCCESS;
168     }
169
170 }

分析一下上述的action代码:

①私有化的成员变量为了保证成功调用增加的getter和setter方法使得代码篇幅过长,光成员变量的getter和setter方法代码占了100行,实际用于业务逻辑的代码才70行不到

②每一个具体的方法均只返回了SUCCESS类型,对于方法中产生的异常或者逻辑中需要处理对应问题没有添加对应的方法

③方法中开启了session链接,应该使用try和catch块,保证异常的处理

④方法命名没有达到规范

查看Service层及其实现层代码:

 1 package Service;
 2
 3 import java.util.List;
 4
 5 import Dao.Users;
 6
 7 public interface UserService {
 8     public List<Users> findAllUser();
 9
10     public void save(Users user);
11
12     public void delete(Users user);
13
14     public void update(Users user);
15
16     public Users findById(int id);
17
18     public List<Users> findByUsername(Object username);
19 }

......未完待续

时间: 2024-10-23 13:10:55

历久弥新:SSH框架结构的简单优化过程的相关文章

一道简单题目的优化过程——抽签问题

题目来源:挑战程序设计竞赛 题目描述: 给定n个数字,选择四次,可以选择已经选择过的数字,问是否可以选出和为m的四个数. 首先,最基本的做法: 枚举四层,每一层枚举出一个数,求出所有四个数字不同的排列.时间复杂度为O(N^4). for (int i1=1;i1<=n;i++) for (int i2=i1;i2<=n;i2++) for (int i3=i2;i3<=n;i3++) for (int i4=i3;i4<=n;i4++) 让我们来一步步优化吧. 基本做法的本质是,枚

高斯模糊算法的全面优化过程分享(二)。

      相关链接: 高斯模糊算法的全面优化过程分享(一) 在高斯模糊算法的全面优化过程分享(一)一文中我们已经给出了一种相当高性能的高斯模糊过程,但是优化没有终点,经过上一个星期的发愤图强和测试,对该算法的效率提升又有了一个新的高度,这里把优化过程中的一些心得和收获用文字的形式记录下来. 第一个尝试   直接使用内联汇编替代intrinsics代码(无效) 我在某篇博客里看到说intrinsics语法虽然简化了SSE编程的难度,但是他无法直接控制XMM0-XMM7寄存器,很多指令中间都会用内

linux小白-基础篇-系统简单优化

作为一个刚刚接触Linux的小白,通过一段时间的学习,将我自己的部分笔记整理后拿出来,请求大家指点:因为是"0"基础学起很多地方了解的都不够深入,希望各位前辈能够指点一下:予人玫瑰,手留余香,谢谢! 因为条件有限环境是用VM搭建起来的,下文主要是根据"老男孩教育视频"中的内容整理出来的系统简单优化,希望各位前辈看过以后可以给出建议: 已学习进步为目的,不喜勿喷!谢谢! 系统简单优化    命令 一.关闭selinux                         

编译安装nginx及简单优化配置

一.背景 使用源码包安装lnmp架构及简单的优化配置 二.实验环境 rhel6.5 三.安装过程 1.nginx(提前装好gcc等编译器) (1) 下载源码包  http://nginx.org/ (2) tar -zxf nginx-1.8.1.tar.gz (3) cd nginx-1.8.1 vim auto/cc/gcc 修改第179行 (将本行注释,意为取消debug模式,) (4) ./configure --prefix=/usr/local/lnmp/nginx \ --with

Kali Linux 优化过程

修改输入法横向候选字 vim ~/.config/fcitx/conf fcitx-classic-ui.config 修改此行 为 false  :VerticalList=False   mb这玩意百度真不好找  fuck一句 web版酷狗 http://forum.ubuntu.org.cn/viewtopic.php?t=287968 Netspeed显示当前网络上传下载速度 apt-get install netspeed Alt+鼠标右键面板选择Add to Panel,添加nets

记一次内存泄露优化过程

背景 项目目前存在使用久了或者重复打开关闭某个页面,内存会一直飙升,居高不下,频繁发生GC.静置一段时间后,情况有所改善,但是问题依旧明显,如图1-1.1-2. 图1-1.操作时的内存使用情况 图1-2.静置时的内存使用情况 如上图1-1,是通过Android Studio查看内存(灰色)和CPU(红色)使用情况,可以看出内存有发生抖动并且是处于比较高的状态,再者,从logcat可以看到一直发生GC,如下图1-3: 图1-3. 出现这些情况,是有很多因素造成的,最主要的原因是发生了内存泄露:页面

完整构建LNMP,简单优化实现超高并发访问!

LNMP简介 1.什么是LNMP? 也许大家对LAMP比较熟悉,LAMP代表Linux下Apache.MySQL.PHP这种网站服务器架构:同上LNMP代表的就是Linux下Nginx.MySQL.PHP这种网站服务器架构. 2.我们为什么要采用LNMP这种架构呢? 使用Linux.PHP外加MySQL的优点我就无需多说相信大家也都很明了. Nginx是一个轻量级且高效的Linux下的Web服务器软件,最初是由 Igor Sysoev 为俄罗斯访问量第二的 Rambler.ru 站点开发的反向代

【Android UI】ListView的使用和简单优化

ListView是每个app中都要使用的,所以今天我来总结下ListView的使用和一些简单的优化. 先看下运行效果: 一.创建数据库 为了模拟数据,这里将数据保存数据库中,顺便复习一下SQLite的知识,将数据保存到数据库的好处就是很容易模拟网络请求的延迟. 1.创建数据库打开帮助类BlackNumberDBOpenHelper,它继承自SQLiteOpenHelper package com.yzx.listviewdemo.db; import android.content.Contex

C# 实现寻峰算法的简单优化(包含边峰,最小峰值,峰距)

原文:C# 实现寻峰算法的简单优化(包含边峰,最小峰值,峰距) 核心寻峰算法的原理参考Ronny,链接:投影曲线的波峰查找, C#翻译原理代码参考sowhat4999,链接:C#翻译Matlab中findpeaks方法 前人种树,后人乘凉.感谢原作者详细的解释说明. 这里先把翻译代码贴一下(略微的修改了sowhat4999代码中的几个参数) //调用方法 List<double> data = new List<double>{25, 8, 15, 5, 6, 10, 10, 3,