最近做了两个项目,开始接触到所谓的 MS Pet Shop 采用的 3 层架构。虽然说项目的开发过程依然不大规范,但还是从中学到了不少东西。
开始做第一个项目时,我主要负责的是展示层的工作,后来也负责数据访问层的工作。问题也就是在那时发现的:最初我拿到需求后,发现数据访问层提供给我的接口远远无法满足展示的需求。有时我为了显示某些数据,不得不连续调用2~3个 DAL 接口,有些甚至是在 for 或者 foreach 循环中调用的。例如,我要显示用户列表,但是数据访问层给我的接口是这样的:
public interface IUser
{
// 
// 其它接口
// 
IList<int> GetUsers();
UserInfo GetUserInfo(int userId);
// 
// 其它接口
// 
}
首先,那个 GetUsers 没有分页不说,返回的一个 UserId 的 IList 实例根本就无法用于显示(总不能给用户看一串数字吧)。
于是,我不得不通过下面的代码来依次获取用户的信息,连分页都要处理了:
public void BindData(int pageSize, int pageIndex)
{
int lowerBound = (pageIndex - 1) * pageSize;
int upperBound = pageIndex * pageSize;
IList<int> userIds = DalFactory.CreateUser().GetUsers();
List<UserInfo> userInfos = new List<userInfo>();
for(int i = lowerBound; i < upperBound; i++)
{
userInfos.Add(DalFactory.CreateUser().GetUserInfo(userIds[i]));
}
// 数据绑定操作
// 
}
这类数据绑定的方法效率之低是显而易见的,于是我向做 DAL的人提了建议。这才稍微改了过来,直接返回 IList<UserInfo>,这样大大方便了展示的操作。
然而,提交 DEMO 之后,问题又来了,上边说是效率很低,很多功能没法正常工作,之后也就把 DAL 交给我们几个本来做展示层的处理了。研究了一番 DAL 代码之后,发现他很多的工作都不是必要的。比如,搜索用户时,要显示的只有用户名、用户头像、用户积分和简短的用户描述这几条信息,为了创建链接还需要用户的 Id,然而,DAL 做的是把 User 的所有信息都读了出来;更新用户详细信息时,部分不应该被更新的信息,如注册时间、发帖数、积分等也被当作参数传到服务器,但却找不到方法来单独更新用户的发帖数和积分——于是要更新这些信息时,不得不把整个 UserInfo 读出来,修改相应数据后再整个更新进去(在这种情况下,大部分内容都没有更新)……而且将近一半数据库操作都是通过直接拼接 SQL 语句实现的……于是不得不开始进行优化工作:为几乎所用的读取大量数据的方法都提供了分页,将一些常用的更新局部数据的方法都单独拿了出来,将 Sql 语句转换为存储过程,减掉了一些不应当被更新的参数,添加了很多视图,将数据库中的表的数据联系起来——总的原则就是减少访问数据库的次数,尽可能一次调用接口方法就能得到必要的数据而且无须进一步处理,仅读取必要的数据,采用一定的缓存机制…………最终来说,性能是有所提高了,但接口中的方法数却多了一些。听前辈说,接口层要尽可能的轻便,但是就实际需求而言,接口的过分轻便可能导致难以根据需要来获取或者更新数据,会造成性能问题。前辈们也没有给我比较好的范例让我参照。于是,在迷茫于摸索中,第一个 Web 项目就这么结束了……也许,我的一些看法是错误的,但至少我们几个做展示层的觉得,修改后的数据访问层更好使用了,页面上要做的处理也少了。
如果有那位高人知道如何处理好接口中方法数目与做到合理读取/更新数据的关系,希望能告诉下小弟。
开始做第一个项目时,我主要负责的是展示层的工作,后来也负责数据访问层的工作。问题也就是在那时发现的:最初我拿到需求后,发现数据访问层提供给我的接口远远无法满足展示的需求。有时我为了显示某些数据,不得不连续调用2~3个 DAL 接口,有些甚至是在 for 或者 foreach 循环中调用的。例如,我要显示用户列表,但是数据访问层给我的接口是这样的:
public interface IUser
{
// 
// 其它接口
// 
IList<int> GetUsers();
UserInfo GetUserInfo(int userId);
// 
// 其它接口
// 
}首先,那个 GetUsers 没有分页不说,返回的一个 UserId 的 IList 实例根本就无法用于显示(总不能给用户看一串数字吧)。
于是,我不得不通过下面的代码来依次获取用户的信息,连分页都要处理了:
public void BindData(int pageSize, int pageIndex)
{
int lowerBound = (pageIndex - 1) * pageSize;
int upperBound = pageIndex * pageSize;
IList<int> userIds = DalFactory.CreateUser().GetUsers();
List<UserInfo> userInfos = new List<userInfo>();
for(int i = lowerBound; i < upperBound; i++)
{
userInfos.Add(DalFactory.CreateUser().GetUserInfo(userIds[i]));
}
// 数据绑定操作
// 
}然而,提交 DEMO 之后,问题又来了,上边说是效率很低,很多功能没法正常工作,之后也就把 DAL 交给我们几个本来做展示层的处理了。研究了一番 DAL 代码之后,发现他很多的工作都不是必要的。比如,搜索用户时,要显示的只有用户名、用户头像、用户积分和简短的用户描述这几条信息,为了创建链接还需要用户的 Id,然而,DAL 做的是把 User 的所有信息都读了出来;更新用户详细信息时,部分不应该被更新的信息,如注册时间、发帖数、积分等也被当作参数传到服务器,但却找不到方法来单独更新用户的发帖数和积分——于是要更新这些信息时,不得不把整个 UserInfo 读出来,修改相应数据后再整个更新进去(在这种情况下,大部分内容都没有更新)……而且将近一半数据库操作都是通过直接拼接 SQL 语句实现的……于是不得不开始进行优化工作:为几乎所用的读取大量数据的方法都提供了分页,将一些常用的更新局部数据的方法都单独拿了出来,将 Sql 语句转换为存储过程,减掉了一些不应当被更新的参数,添加了很多视图,将数据库中的表的数据联系起来——总的原则就是减少访问数据库的次数,尽可能一次调用接口方法就能得到必要的数据而且无须进一步处理,仅读取必要的数据,采用一定的缓存机制…………最终来说,性能是有所提高了,但接口中的方法数却多了一些。听前辈说,接口层要尽可能的轻便,但是就实际需求而言,接口的过分轻便可能导致难以根据需要来获取或者更新数据,会造成性能问题。前辈们也没有给我比较好的范例让我参照。于是,在迷茫于摸索中,第一个 Web 项目就这么结束了……也许,我的一些看法是错误的,但至少我们几个做展示层的觉得,修改后的数据访问层更好使用了,页面上要做的处理也少了。
如果有那位高人知道如何处理好接口中方法数目与做到合理读取/更新数据的关系,希望能告诉下小弟。

浙公网安备 33010602011771号