三层开发中容易犯的错误
2007-03-08 15:34
197 查看
前记:
相信大家对三层开发都已经耳熟能详,可是我却发现新公司的既有代码中有一些违背分层开发思想的东西,现在与大家分享这些错误,我们共勉之。
如果有人觉得对三层开发拿捏得不是太准,请参照李天平的文章:分层开发思想与小笼包,这篇文章用隐喻说明分层开发,是非常好的一篇文章。
正文:
1.界面层参与非界面逻辑,抢业务逻辑层的饭碗
什么是界面逻辑:
界面层应该有的逻辑就是显示的逻辑,例如根据逻辑结果显示某一个Panel不显示另外一个Panel,或者有一个数据集应该在界面上怎么呈现,这是界面层的逻辑
例子场景:
用户登录时首先验证用户输入的用户名是否有效,如果用户名有效,然后再验证用户输入的密码是否和用户名匹配,如果匹配则表示用户可以登录,增加用户的登录次数,然后将用户的信息写入Session中;否则返回错误。在这个过程中除了将用户信息写入Session这一步属于界面逻辑以外其他的操作都应该放在业务逻辑层。
错误代码示例:
private void buttonLogin_Click(object sender, EventArgs ev)
//业务逻辑层的登录方法
public int Login(string userName, string password)
//数据访问层的登录方法
public int Login(string userName, string password)
CREATE PROC Login
@userName varchar(20),
@password varchar(20)
AS
IF NOT EXISTS(SELECT * FROM UserAccount WHERE UserName = @userName)
RETURN -1
IF NOT EXISTS(SELECT * FROM UserAccount WHERE UserName = @userName AND password = @password)
RETURN 1
UPDATE UserAccount
SET LoginTimes = LoginTimes + 1
WHERE UserName = @userName
RETURN 0
分析:从上面三段代码中我们可以很显然得看到登录的业务逻辑已经全部被后移到了数据库的存储过程中。这样使用的三层结构就失去了意义,逻辑层名存实亡了;而数据库的压力会越来越大;我们修改业务逻辑的时候不是到逻辑层修改,而是要到数据库中去修改了。
3.将界面层上的数据组件(如SqlDataSource)作为参数传递到业务逻辑层去赋值
这样做的坏处很明显,本来是界面层依赖于业务逻辑层的,现在业务逻辑层反过来去依赖界面层的类,需要逻辑层引用System.Web命名空间,显然是错误的。
4.为了省事儿,不是直接将参数传递到业务逻辑层,而是通过HttpContext直接获得界面层应该传递的参数
例子:在系统设计的初期没有记录用户登录的IP地址,而到了后期发现了这个问题,要求纪录用户IP了,为了不修改业务逻辑层方法的定义,也不用修改界面层的调用方法,于是便写出了下面的代码:
public int Login(string userName, string password)
{
string userIP = System.Web.HttpContext.Current.Request.UserHostAddress;
//follow is login steps
}
这一点犯的错误和3中的错误相同,导致层之间形成了依赖环。
5.将事务处理放在数据访问层来做
事务处理应该放在业务逻辑层处理,原因是
1)事务的划分是根据业务逻辑来定义的,通常一个事务就代表完成了一个完整的逻辑操作;
2)一个业务逻辑可能有几个数据操作,修改几个表中的数据,而通常数据层的类的划分是根据数据库表来划分的,如果把事务处理放在数据访问层,那么业务层的方法需要调用两个以上的数据层方法时,就会出现执行两个事务的情况,显然这是不合理的。
总结:
1.在三层结构的划分中我们应该使三层各负其责,谁也不能越权,谁也不能懒惰,通常情况下,逻辑层应该在满足各负其责的条件下,尽可能的厚。
2.三层结构中的依赖关系很明确,界面层依赖于逻辑层,逻辑层依赖于数据访问层,不能互相依赖,而形成依赖环。
相信大家对三层开发都已经耳熟能详,可是我却发现新公司的既有代码中有一些违背分层开发思想的东西,现在与大家分享这些错误,我们共勉之。
如果有人觉得对三层开发拿捏得不是太准,请参照李天平的文章:分层开发思想与小笼包,这篇文章用隐喻说明分层开发,是非常好的一篇文章。
正文:
1.界面层参与非界面逻辑,抢业务逻辑层的饭碗
什么是界面逻辑:
界面层应该有的逻辑就是显示的逻辑,例如根据逻辑结果显示某一个Panel不显示另外一个Panel,或者有一个数据集应该在界面上怎么呈现,这是界面层的逻辑
例子场景:
用户登录时首先验证用户输入的用户名是否有效,如果用户名有效,然后再验证用户输入的密码是否和用户名匹配,如果匹配则表示用户可以登录,增加用户的登录次数,然后将用户的信息写入Session中;否则返回错误。在这个过程中除了将用户信息写入Session这一步属于界面逻辑以外其他的操作都应该放在业务逻辑层。
错误代码示例:
private void buttonLogin_Click(object sender, EventArgs ev)
//业务逻辑层的登录方法
public int Login(string userName, string password)
//数据访问层的登录方法
public int Login(string userName, string password)
CREATE PROC Login
@userName varchar(20),
@password varchar(20)
AS
IF NOT EXISTS(SELECT * FROM UserAccount WHERE UserName = @userName)
RETURN -1
IF NOT EXISTS(SELECT * FROM UserAccount WHERE UserName = @userName AND password = @password)
RETURN 1
UPDATE UserAccount
SET LoginTimes = LoginTimes + 1
WHERE UserName = @userName
RETURN 0
分析:从上面三段代码中我们可以很显然得看到登录的业务逻辑已经全部被后移到了数据库的存储过程中。这样使用的三层结构就失去了意义,逻辑层名存实亡了;而数据库的压力会越来越大;我们修改业务逻辑的时候不是到逻辑层修改,而是要到数据库中去修改了。
3.将界面层上的数据组件(如SqlDataSource)作为参数传递到业务逻辑层去赋值
这样做的坏处很明显,本来是界面层依赖于业务逻辑层的,现在业务逻辑层反过来去依赖界面层的类,需要逻辑层引用System.Web命名空间,显然是错误的。
4.为了省事儿,不是直接将参数传递到业务逻辑层,而是通过HttpContext直接获得界面层应该传递的参数
例子:在系统设计的初期没有记录用户登录的IP地址,而到了后期发现了这个问题,要求纪录用户IP了,为了不修改业务逻辑层方法的定义,也不用修改界面层的调用方法,于是便写出了下面的代码:
public int Login(string userName, string password)
{
string userIP = System.Web.HttpContext.Current.Request.UserHostAddress;
//follow is login steps
}
这一点犯的错误和3中的错误相同,导致层之间形成了依赖环。
5.将事务处理放在数据访问层来做
事务处理应该放在业务逻辑层处理,原因是
1)事务的划分是根据业务逻辑来定义的,通常一个事务就代表完成了一个完整的逻辑操作;
2)一个业务逻辑可能有几个数据操作,修改几个表中的数据,而通常数据层的类的划分是根据数据库表来划分的,如果把事务处理放在数据访问层,那么业务层的方法需要调用两个以上的数据层方法时,就会出现执行两个事务的情况,显然这是不合理的。
总结:
1.在三层结构的划分中我们应该使三层各负其责,谁也不能越权,谁也不能懒惰,通常情况下,逻辑层应该在满足各负其责的条件下,尽可能的厚。
2.三层结构中的依赖关系很明确,界面层依赖于逻辑层,逻辑层依赖于数据访问层,不能互相依赖,而形成依赖环。
相关文章推荐
- 三层开发中容易犯的错误
- 三层开发中容易犯的错误
- 三层开发中容易犯的错误
- 三层开发中容易犯的错误
- 三层开发中容易犯的错误
- 三层开发中容易犯的错误(转)
- 三层架构开发中容易犯的错误
- .NET开发人员容易犯的6大安全错误
- 新手开发android容易出现的错误(不断更新中...)
- IOS开发中, 经常容易犯的错误
- .NET开发人员容易犯的6大安全错误
- Web开发和设计上容易被忽视的8个错误
- .NET开发人员容易犯的6大安全错误
- App开发中容易出现5种错误
- [开发] 开发容易犯的错误,更新中...
- Siverlight以及WPF开发技术容易发生的调试发生的错误-自己总结。
- Android开发容易忽略的小错误记录整理
- 微信开发-二维码-生成二维码容易忽略的错误
- java多线程开发容易犯的错误
- jQuery开发中容易忽视的错误