<2009年7月>
2829301234
567891011
12131415161718
19202122232425
2627282930311
2345678


转载请保留链接

我的标签

随笔档案

宝宝孕历

  • 宝宝孕历
  • 宝宝孕历准爸爸准妈妈的好朋友-获得孕期每月每周的注意事项和温馨提示,记录宝宝诞生期间甜酸苦辣的甜蜜艰辛
  • 当当卓越比价程序
  • 用当当卓越比价程序,网上买书省钱省时。java与模式可以省10将近块钱
  • 怀孕书,育儿书,孕妇装
  • 宝宝孕历孕前准备书,怀孕书,育儿书,孕妇装,靠枕等新鲜出炉了
  • 孕期知识
  • 孕期的相关知识
  • 孕味广场
  • 孕期论坛,讨论怀孕,孕期注意事项,孕检等

最新随笔

最新评论

阅读排行榜

评论排行榜

前记:

相信大家对三层开发都已经耳熟能详,可是我却发现新公司的既有代码中有一些违背分层开发思想的东西,现在与大家分享这些错误,我们共勉之。

如果有人觉得对三层开发拿捏得不是太准,请参照李天平的文章:分层开发思想与小笼包,这篇文章用隐喻说明分层开发,是非常好的一篇文章。

正文:

1.界面层参与非界面逻辑,抢业务逻辑层的饭碗

什么是界面逻辑:

界面层应该有的逻辑就是显示的逻辑,例如根据逻辑结果显示某一个Panel不显示另外一个Panel,或者有一个数据集应该在界面上怎么呈现,这是界面层的逻辑

例子场景:

用户登录时首先验证用户输入的用户名是否有效,如果用户名有效,然后再验证用户输入的密码是否和用户名匹配,如果匹配则表示用户可以登录,增加用户的登录次数,然后将用户的信息写入Session中;否则返回错误。在这个过程中除了将用户信息写入Session这一步属于界面逻辑以外其他的操作都应该放在业务逻辑层。

错误代码示例:

private void buttonLogin_Click(object sender, EventArgs ev)
        
{
            
string userName = textBoxUserName.Text;
            
string password = textPassword.Text;

            
if (Business.Account.Exists(userName))
            
{
                
bool success = Business.Account.Login(userName, password);
                
if (success)
                
{
                    Business.Account.AddLoginTime(userName);

                    Session[
"user"= new User(userName, password);
                    Redirect(
"/");
                }

                
else
                
{
                    
this.labelMessage.Text = "登录失败。";
                }

            }

            
else
            
{
                
this.lableMessage.Text = "用户名不存在。";
            }

        }

 

分析:在上面的代码中一个UI层的一个事件中调用了三次rules层的方法:

Business.Account.Exists(userName)

Business.Account.Login(userName, password)

Business.Account.AddLoginTime(userName);

还附加有条件判断,这种方法在执行效果上面是没有什么错误的,可是却造成了逻辑前移;本来应该在逻辑层执行的判断放在了界面层,是不合适的。

2.数据访问层参与了大量的业务逻辑

这种现象经常出现在大量使用存储过程的系统中,将一大堆逻辑统统放在一个存储过程中实现了,乍一看可能很有效率,其实造成了系统结构的失调,给维护带来困难,数据访问层甚者数据库要抢逻辑层的饭碗了。

还以用户登录为例:

下面是业务逻辑层的登录方法: 

//业务逻辑层的登录方法
        public int Login(string userName, string password) 
        
{
            
return DataAccess.UserAccount.Login(userName, password);
        }


 

下面是数据层的登录方法: 

//数据访问层的登录方法
        public int Login(string userName, string password)
        

            SqlParameter[] parameters 
= new SqlParameter[]{
                
// 
            }
;
            
return SqlHelper.ExecuteProcedure("Login",parameters);
        }


 

下面是登录的存储过程: 

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.三层结构中的依赖关系很明确,界面层依赖于逻辑层,逻辑层依赖于数据访问层,不能互相依赖,而形成依赖环。

posted on 2007-03-08 15:34 玉开 阅读(7404) 评论(134)  编辑 收藏 网摘 所属分类: 软件设计

FeedBack:
评论共2页: 上一页 1 2 
#101楼 2007-03-08 17:12 lyb      
不想多说,这样的问题早发现了.不用存储过程?要不搞个调查,基于这样的三层的有多少不用sp的.
三层用一个,失败一个.不讲那么多大道理.只要一用,就是sp满天飞,业务逻辑名存实亡.到最后就是没有办法扩展.bug 一大堆.

究其根本原因,这样的三层不是OO.
OO是要设计的,这样的三层没有设计.

  回复  引用  查看    
#102楼 2007-03-08 17:14 非我      
设计就是要在遵循原则和灵活自由间寻求平衡,过犹不及
  回复  引用  查看    
#103楼[楼主] 2007-03-08 17:15 玉开      
@ttyp
这个完全同意

  回复  引用  查看    
#104楼[楼主] 2007-03-08 17:16 玉开      
@lyb
不能一棒子全都打死吧

  回复  引用  查看    
#105楼[楼主] 2007-03-08 17:17 玉开      
@极地银狐.NET
--楼主如果你要修改presentation层的代码,应该如何改呢?
不好意思,不明白你问这句话的含义呀


  回复  引用  查看    
#106楼 2007-03-08 17:23 JesseZhao      
不错,很经典啊
  回复  引用  查看    
#107楼 2007-03-08 17:25 lyb      
@
我是说我们公司做的项目,可能水平不够.
因为我觉得这个问题的根本原因不在架构本身,而在于设计.如果进行良好的OO设计,sp的数量可以减少.

以前也自己寻找别的架构,到最后就觉得.NET里面最好的还是Castle+IBatisnet,我到现在也不会NHibernate,因为我觉得在.Net里面用NHibernate根本没有必要,因为有ADO.Net的存在,没有好的OO设计.
没有好的OO设计 + 数据访问封装ADO.NET + SP=失败的绝配.

面向对象程序人员很多都忘记了面向对象.

  回复  引用  查看    
#108楼 2007-03-08 17:30 Tony.Gong      
我一般这么写:
表示层:
if not Business.Account.Login(userid,password)
abelMessage.Text = "登录失败。"
else
Session["user"] = new User(userName, password);
Redirect("/");
end if

BLL层:
Public function Login(byval userid as string,byval password as string) as boolean
if not Account.Exists(userName)
return false
end if

If Account.Login(userName, password) Then
Account.AddLoginTime(userName)
Return ture
Else
return false
End If
end function

  回复  引用  查看    
#109楼 2007-03-08 17:32 北极狐      
老大,你最后,操作数据库,数据持久化层的代码呢?
  回复  引用  查看    
#110楼[楼主] 2007-03-08 17:33 玉开      
@Tony.Gong
后面的一段好像写错了吧,Da层的

  回复  引用  查看    
#111楼 2007-03-08 17:34 北极狐      
我没有看见呀!是自动生成的吗?
  回复  引用  查看    
#112楼 2007-03-08 17:35 Tony.Gong      
@玉开
恩,写错了,在文本框里写代码真不习惯

  回复  引用  查看    
目前笔者说的,我基本已经避免啦。
我这里想说些题外话,
是我们写程序或是做事情,不要范教条思想的束缚,程序思想也好、设计模式也好,其实都是活的,我们只要在实际中灵活运用,多分析,多动脑,输出好的程序才是关键!

  回复  引用  查看    
#114楼 2007-03-08 17:38 极地银狐.NET      
@玉开
我是说,正如你所说在表示层你认为是业务逻辑前移,你会如何修改使之不前移?

  回复  引用  查看    
#115楼[楼主] 2007-03-08 17:40 玉开      
@贲志强[benzhiqiang]
呵呵,有些原则是一定要遵守的,遵守了原则才可以开发出规范的东西,规范的东西才更容易维护。
比如说:上文中提到的循环引用就是要不得的,如果有了,可能某一天冷不丁就会蹦出一个bug来。

  回复  引用  查看    
#116楼 2007-03-08 17:41 北极狐      
//
public static enStatus Login(AdminUserInfo User)
{
enStatus isReturn = enStatus.Normal;
string strCmd = string.Format(@"dbo.ta_Admin_UserInfo_Login");
using (SqlConnection sqlConn = new SqlConnection(DBHelp.getDBConnetion(enDBConnection.MainDbCononetion_sync)))
{
SqlCommand sqlCmd = new SqlCommand(strCmd, sqlConn);
sqlCmd.CommandType = CommandType.StoredProcedure;
//
sqlCmd.Parameters.Clear();
sqlCmd.Parameters.Add("@aUserName", SqlDbType.NVarChar, 50).Value = User.FUserName;
sqlCmd.Parameters.Add("@aUserPassword", SqlDbType.NVarChar, 50).Value = User.FUserPassword;
sqlCmd.Parameters.Add("@aLoginIPAddress", SqlDbType.NVarChar, 255).Value = User.FLoginIPAddress;
sqlCmd.Parameters.Add("@isReturn", SqlDbType.Int, 4).Value = "0";
sqlCmd.Parameters["@isReturn"].Direction = ParameterDirection.InputOutput;
//
try
{
//
sqlConn.Open();
int intTemp = 0;
sqlCmd.ExecuteNonQuery();
intTemp = Convert.ToInt32(sqlCmd.Parameters["@isReturn"].Value.ToString());
isReturn = (enStatus)(intTemp);
//
}
catch (SqlException sqlExce)
{
ErrorUtility.LogException(sqlExce);
isReturn = enStatus.Normal;
}
catch (Exception e)
{
ErrorUtility.LogException(e);
isReturn = enStatus.Normal;
}
finally
{
//
sqlConn.Close();
}

}//end using
return isReturn;
}
//

  回复  引用  查看    
#117楼 2007-03-08 17:41 北极狐      
这是它的DAL
  回复  引用  查看    
#118楼[楼主] 2007-03-08 17:44 玉开      
@极地银狐.NET
明白你的意思了,我会在业务逻辑层的登录方法中处理文中UI层调用的三个逻辑层方法,大概是这样的:
//rules层登录
public int Login(string userName,string password)
{
if(!IsExists(userName))return -1;
if(DaUser.Login(userName,password)){
DaUser.AddLoginTimes(userName);
return 0;
}
return 1
}

  回复  引用  查看    
发现在很多人写登录依然喜欢用session()来保存用户的状态信息,进入.net时候后,我们应该用System.Web.Security封装的方法来做这个,这样才标准,安全.好处也是鲜而易见的.
  回复  引用  查看    
#120楼 2007-03-08 17:50 wqxh[未注册用户]
@Tony.Gong
你这段代码更加夸张啊,BLL依赖presentation层了

lz题的问题我也常犯,还是觉得规范的好,有利于以后的修改。

  回复  引用    
#121楼[楼主] 2007-03-08 17:53 玉开      
@喜欢吹风的感觉
谢谢你的提示,这个是意外的收获

  回复  引用  查看    
#122楼 2007-03-08 17:55 极地银狐.NET      
@玉开
谢谢,其实我喜欢返回一个BOOL,这样表示执行成功与否,欢迎指教啊. :)

  回复  引用  查看    
#123楼[楼主] 2007-03-08 17:58 玉开      
@极地银狐.NET
呵呵,客气了,

因为需要提示用户是否是用户名写错了,所以才返回整型的,其实也不太好,严格的设计可能要返回枚举。

  回复  引用  查看    
#124楼 2007-03-08 17:58 xnet[未注册用户]
是啊!要看具体情况。。。有的逻辑处理放在数据库更安全!业务处理起来更加的方便!
  回复  引用    
#125楼[楼主] 2007-03-08 18:01 玉开      
@xnet
不是很明白你的意思,什么样的逻辑处理放在数据库更安全呢?

  回复  引用  查看    
#126楼 2007-03-08 18:18 kaka[未注册用户]
个人认为,具体情况应具体分析,软件开发最主要的要领就是“灵活”,逻辑应该放在哪里,是不能一概而论的,关键是要有一个善于度量的大脑,一颗会敢于变通的心,要因时制宜,因地制宜,千篇一律、墨守陈规、以偏概全等都是要不得的。
PS:写完了感觉好像说了等于没说 -_-!

  回复  引用    
#127楼 2007-03-08 18:33 极地银狐.NET      
@玉开
同意返回枚举,一个业务层的枚举.
不过对于业务逻辑我个人比较认同看情况,如果比较频繁地访问数据库,还是在存储过程里完成比较好.毕竟放在业务层频繁来回调用也不太好.近期在自己写一个小程序,欢迎指教啊.

  回复  引用  查看    
#128楼[楼主] 2007-03-08 18:36 玉开      
@极地银狐.NET
客气了,大家互相交流,谈不上指教的。

  回复  引用  查看    
个人提一些意见.在回答了"为什么要分层"这个问题之后,我想这个问题就会有答案了.
分层的目的是:隔离变化点,职责集中,与自动化测试,代码复用.

  回复  引用    
#130楼[楼主] 2007-03-08 18:41 玉开      
@DaiWei[匿名]
对,分层还可以使系统结构清晰,使系统更容易维护。

  回复  引用  查看    
#131楼 2007-03-08 20:23 Tony.Gong      
@wqxh
没有吧?
presentation层调用BLL层的login方法
BLL层的login方法调用了DAL的Exists,Login,AddLoginTime3个方法

  回复  引用  查看    
#132楼 2007-03-08 20:32 Jeffrey Zhao      
这些“问题”呢,的确有一定道理,不过我还没有发现不存在这些问题的应用……
其实很多时候,我们都是基于一个共有的.NET Framework进行开发,因此层与层之间的“依赖性”其实只是表现在依赖想同的.NET Framework组件上,这样的话其实问题不大。

  回复  引用  查看    
#133楼 2007-03-08 20:35 大豆男生      
博主写的很好,但我觉得对性能要求的比较高的功能还是用存储过程,存储过程的性能更好一些。
  回复  引用  查看    
该如何做?
  回复  引用    
#135楼 2007-03-08 22:58 棠棠dotNet      
谢谢lz.我也有犯这样错误.收获多多.
同意 大豆男生 的 "对性能要求的比较高的功能还是用存储过程,存储过程的性能更好一些"

  回复  引用  查看    
#136楼 2007-03-08 23:09 补丁      
凡事有个度
很多东西是功能/性能/架构/开发速度/开发灵活性/修改灵活性/程序员水平/程序小组组成等等因素权衡取舍的过程
文章显然对架构有较高的要求,但是在实际操作中,是不是要按照这个做,是根据具体情况灵活安排的
楼上的很多朋友,你们的问题也不算什么"错误",更多的是在架构方面缺乏认识罢了
但是话说回来,对于中小型/开发目标明确/开发任务紧张等等特点的项目,过于重视架构是不是一件好事,我觉得还有待商榷,特别是,对一些不够成熟的团队来说

  回复  引用  查看    
是的,数据库层和界面层就不应该有逻辑代码。但是在设计时往往对数据库层没有预留足够的数据库调用代码,也才会出现这样的情况。
对于是否使用存储过程,答案是看情况,一个系统的开发,更换数据库的可能性恐怕是非常低的。

  回复  引用  查看    
有针对性的优化,使用存储过程有时是唯一的选择。
  回复  引用  查看    
#139楼 2007-03-08 23:33 Anders.Zhao      
160个存储过程也算大吗?我们公司的一个产品有13W个存储过程,数据库还只是开发阶段就有2GB多,真不知道到了客户那里怎么办,
  回复  引用  查看    
#140楼 2007-03-08 23:50 iCaca      
个人观点,使用存储过程的缺点在于,数量大时难以维护。
复杂的查询用一些存储过程还是很不错的。
我认为这样的讨论很不错

  回复  引用  查看    
#141楼 2007-03-09 00:08 北极狐      
13w是13万个吗,那也真是无话可说了!
  回复  引用  查看    
业务逻辑还有很多的,象上面的登录这种简单而且基本固定的业务逻辑,我和大家一样倾向于封装在存储过程中,这样可以提高了系统的运行效率,而且这种逻辑都在一个存储过程中,以后的维护也方便,如果每一个判断都在业务逻辑层单独处理而每次都去连接数据库,也不见得会减轻数据库的负担,而且肯定会影响到系统运行速度(即使有连接池,连接一次数据库也是很耗费资源和时间的)。

.net开发资源精华收集— http://***

  回复  引用    
#143楼 2007-03-09 08:44 补丁      
@Anders.Zhao
你们公司的dba真累啊...^ ^

  回复  引用  查看    
#144楼[楼主] 2007-03-09 08:52 玉开      
@Anders.Zhao
13w个存储过程的维护要比维护逻辑层麻烦的多吧?

  回复  引用  查看    
#145楼[楼主] 2007-03-09 08:55 玉开      
@iCaca
同意你的观点。

@补丁
希望我们的团队都向成熟的方向发展。

  回复  引用  查看    
#146楼[楼主] 2007-03-09 08:56 玉开      
@Jeffrey Zhao
我不赞同你的观点,虽然都是依赖的framework中的类库,最好也不要形成依赖环。

  回复  引用  查看    
#147楼 2007-03-09 09:57 喝酒的猫      
楼主所说的问题,我认为基本上都可以根据具体的情况,权衡来做一些调整。
没有必要完全的要参照什么标准,但是尽量能遵守就要遵守。

  回复  引用  查看    
#148楼[楼主] 2007-03-09 09:59 玉开      
@喝酒的猫
个人认为除了存储过程包含逻辑这个问题可能要权衡之外,其它的都没必要权衡。

  回复  引用  查看    
还在讨论这样的文章,不可以思议,大都不适合搞程序开发
  回复  引用    
分层思想还是看看老外的吧,中国人有了一点想法,就掰,却不好好学习人家先进的思想,老外程序员看到这些文章,笑死了——以上观点综合自一个老外程序员的观点。
  回复  引用    
#151楼[楼主] 2007-03-09 10:35 玉开      
@不可思议
本文的初衷是发现问题提出问题,大家共勉。
为什么我们不适合搞程序开发?

@不可思议2
我们在软件方面很多东西都在学习老外的,这没有什么。
你没有必要抬出一个老外来,笑死了----没有任何意义,只显得你说话说得很没水平。



  回复  引用  查看    
#152楼 2007-03-09 10:41 jason_lb      
具体问题具体分析,看各自需求孰轻孰重
例如我们项目中有个非常复杂的数理统计,这种情况下,我毫不犹豫的将所有业务逻辑放在SP中实现
试想,如果我非要把这个放到业务层和数据访问层实现,那业务层的压力是极大的,因为几何级数的交互会令你无法接收
当然这个SP还包括相关VIEW,FUNC等等的编写也是让人痛苦的,调试及维护代价也很大
以上孰轻孰重?

  回复  引用  查看    
#153楼 2007-03-09 10:42 iCaca      
@不可思议

那我们应该讨论些什么呢?


@不可思议2

我不认为这有什么可笑的

  回复  引用  查看    
#154楼 2007-03-09 10:58 天才書生      
这里面有些问题很早我在学三层设计开发的时候,就觉得UI层和逻辑层好像都依赖太大了,连很多模仿PETSHOP三层模式的程序也是一个样子,很想请教


但我觉得有些逻辑代码写在存储过程有时候维护起来很方便,要视情况而定,就如@ttyp所说的,我们并不是为分层而分层,要考虑产品和项目的维护和开发周期来定的

我所在的公司有专门的产品客服维护部,如果客户遇到一个问题,可能是转换问题,但你写死在程序里面,难道你让他再去叫开发人员发一个补丁包吗,小题大做,虽然他们不全都会开发程序,但他们SQL都很厉害,如果写在存储过程里面,他们会改,就客户开一个程序读取数据就要10个小时,如果出错了,再加上补丁包的延迟发布,客户不把你杀了就有鬼了

  回复  引用  查看    
#155楼 2007-03-09 11:18 一醉解千愁      
所有的模式,架构都是根据实际情况进行调整,本来就没有固定的模式和标准,所以也就没有了对与错,合适与不合适的争论.

个人意见,了解模式、框架,但并不拘泥于模式、框架.

  回复  引用  查看    
#156楼 2007-03-09 12:51 lyb      
页面逻辑和业务逻辑 分不清, 也是导致这个问题的一个重要原因.
  回复  引用  查看    
#157楼 2007-03-09 13:18 roydu[未注册用户]
中国人为什么很少有创新?就是因为太守规矩了!

如果只是纯粹的去清晰的分层,那分层开发也就失去了意义!

存在即是合理,在这些方面探讨这个是没有意义的.

既然大部分人都这么用,那这样就是合理的.


  回复  引用    
#158楼[楼主] 2007-03-09 13:23 玉开      
@roydu
真理有时候会掌握在少数人的手里。



  回复  引用  查看    
#159楼 2007-03-09 13:39 iCaca      
@roydu
合理么?不合理么?
如果都合理,还需要改革,还需要开人代会?

  回复  引用  查看    
#160楼 2007-03-09 15:41 心飞翔
@ 不可思议

同意你的观点!
学技术不能浮躁,基础要打好!

  回复  引用    
#161楼 2007-03-09 17:09 胖子      
什么叫业务逻辑呢?划分标准又是什么呢?
数据库里运行的代码一定算是数据层么?
……
好混乱啊,搞不懂~~~

  回复  引用  查看    
#162楼 2007-03-09 19:50 伍迷      
请教博主一个小问题,SP里完成事务很容易,在数据访问层里完成事务,利用ADO.NET,也比较容易,但在业务逻辑层,完成事务,每一步操作都是数据访问层的方法,如何进行事务开发?
  回复  引用  查看    
这么厉害




ET电子技术网
http://www.et-dz.com

  回复  引用    
@伍迷
在vs 2005中可以使用TransactionScope
例如:
public void Insert(PetShop.Model.OrderInfo order) {

using (TransactionScope ts = new TransactionScope(TransactionScopeOption.Required)) {

dal.Insert(order);

// Update the inventory to reflect the current inventory after the order submission
Inventory inventory = new Inventory();
inventory.TakeStock(order.LineItems);

// Calling Complete commits the transaction.
// Excluding this call by the end of TransactionScope's scope will rollback the transaction
ts.Complete();
}
}

在以前的dot net版本中可以使用system.enterprise命名空间下的com+事务处理,也很方便的。

  回复  引用    
#165楼 2007-03-09 23:26 Clark Chan      
@亚历山大同志
ms.pet shop 最新版本 不用存储过程 是为了符合 第三方公司的标准.
因为 第三方 拿他和 java的 评测. 标准是都 不用存储过程 方式 比较性能.

  回复  引用  查看    
#166楼 2007-03-10 01:14 丁丁      
犯错也有犯错的好处,估计Oracle和IBM公司要偷着乐了吧?呵呵
  回复  引用  查看    
#167楼 2007-03-10 08:33 Hsjtai      
很谢谢版主的文章!本人对三层(多层)开发很有兴趣,但好象还不能较深入的理解和应用,不知能否提供一些三层(多层)设计方面的文章和实例给我学习呢?谢谢!QQ:1095208 hsjtai@sina.com oldyongs.cnblogs.com
  回复  引用  查看    
@Clark Chan
这个不太好说的,ms为什么不用存储过程,不好推断的,你可以说petshop是为了和java比较性能用的,可是duwamish呢?

  回复  引用    
@丁丁
呵呵
@Hsjtai
本文开始推荐的李天平的文章说明的不错,还有就是《敏捷软件开发:原则、模式与实践》这本书非常棒,如果你理解了书中的原则,就不难理解三层开发了。

  回复  引用    
#170楼 2007-03-10 09:18 Hsjtai      
@yukaizhao
好的,没想到你那么快回复,非常谢谢!!!书我买了不少,你提到的书我有,要补补了!如果有什么好的书/文章涉及到三层(多层)的,请推荐,谢谢!
我现在主要是用vb.net/sql server做c/s方面的开发,c#,b/s方面的也准备全面进攻了。我现在就是想把事情做得更好,把.net理解得更透彻,所以也在较深入的研读.net方面的书籍。

  回复  引用  查看    
@Hsjtai
呵呵,咱们互相学习,经验共享了。

  回复  引用    
#172楼 2007-03-10 11:22 队长      
学习!
楼主的设置的皮肤可真是相当的慢啊!

  回复  引用  查看    
@队长
可能是评论导致页面太长的原因吧,我的另一篇不慢的,用的一样的模版。

  回复  引用    
#174楼 2007-03-12 13:56 howzanh      
很都时候我都是用两层设计的,,有那位好心人,,给我一个标准的三层设计的案例,,谢谢,,
  回复  引用  查看    
#175楼 2007-03-12 14:08 yunhuasheng      
@chill
说的好!

  回复  引用  查看    
#176楼[楼主] 2007-03-12 17:07 玉开      
@howzanh
请参考petshop3。

  回复  引用  查看    
#177楼 2007-03-19 14:01 qq13237810775      
哪正确的写法是什么呢??
  回复  引用  查看    
#178楼 2007-03-25 10:44 wind[未注册用户]
我是个初级写手,我个人很赞同楼主的观点,至少我觉得这方法对我很适合。有的朋友说不要为了分层而分层,我觉得说得在理,但是,既然分层了就应该把它分好,就要有个规则不然业务逻辑在这边写点那边也写点,写的人不爽看的人也不爽,更不利于自己的重用和维护了。
关于业务逻辑都写在存储过程里面,我觉得这是水平比较高的朋友才这么干,好象也乐于这么干,但是,对于我们大部分的中低级别的人来说,存储过程确实有的可怕。
以上纯属个人观点,望各位指教。
欣赏楼主的观点,让我学到了很多,以后多指教。

  回复  引用    
#179楼 2007-04-06 20:51 Clark Zheng      
我的界面层和业务层经常容易混在一块,主要是不怎么重视,因为asp.net表现层上的技术框架改动不大。不过现在看来要好好审视一下了

@arcticfox
微软当然喜欢你用它的SqlServer2005了。。。偶偏就用Oracle,不过存储过程到是用了不少,呵呵

  回复  引用  查看    
#180楼 2007-04-14 09:55 Koy      
vs.net中可以好容易调试存储过程,,呵呵,,,我在写存储过程时常用!
  回复  引用  查看    
其实有好多时候我们不清楚业务就写程序。
  回复  引用    
不是必要的
  回复  引用    
#183楼 2007-06-03 19:23 a[未注册用户]
通常我们都建议客户使用存储过程来访问数据库中的表。 原因如下:

• 存储过程提供了封装查询的一种简洁机制。

• 修改查询可以在不改变数据访问代码的情况下进行。

• DBA 可以很容易地看到正在执行什么 SQL 语句。

• 存储过程一般更安全,对数据库访问的控制也更容易。

• 使用存储过程,可通过在存储过程中发送多个请求,避免与客户端的多次往返行程。

• 存储过程与中间层生成的 SQL 相比,通常能提供最佳性能。

• 存储过程提供了极好的封装 XML 查询和 XML 输入参数的方式。


存储过程的缺点在于,它们往往是专有的,不能跨平台移植。

然而,要想最大程度地利用在数据库软件和硬件上已经花费的投资,开发人员往往对应用程序中使用的 SQL 针对具体数据库引擎进行优化,无论 SQL 是在存储过程中还是在中间层生成的。 这一点有一个很好的例子,就是唯一编号或者标识编号的生成,因为所有数据库执行此操作时都支持自己的特殊机制,所以用来生成唯一编号的 SQL 就往往是特定于所用数据库的。 一般总是有替代方案的,但是它们的执行速度都比不上专有解决方案。


  回复  引用    
#184楼 2007-10-16 19:44 静旅      
呵,加深了点理解
谢谢

  回复  引用  查看    
#185楼 2008-05-29 12:34 水言木      
学习了!
另外请教楼主几个问题:
1. 比如BLL某方法接受一个参数x,在页面逻辑中会从aspx中读取textbox传入,其中可能有非法字符,那么x值的验证要在BLL中还是在aspx.cs中,是在BLL中比较合理么?
2. 曾看文章说DAL要保证原子性,我的理解也就是DAL中只能是简单的CRUD,那比如分页,只有在DAL中考虑分页,效率才能上的去,那分页是否算是界面逻辑?毕竟只有前台UI才有必要考虑分页显示啊.
3. 在分层构架中,下层不能依赖上层,那么,DAL中应该就不能出现Login之类的方法,因为Login看起来是BLL的东西,那么是要在DAL中的UserInfo GetItem(string userName)返回实体,再在BLL中判断password是否相等?如果DAL中有UserInfo GetItem(string userName, string userPwd),那明显会方便,但这么一来感觉DAL就是有考虑了BL。

望楼主帮忙解惑!

  回复  引用  查看    
#186楼 2008-06-02 11:12 清风笑      
正学习....
  回复  引用  查看    
#187楼 2008-06-21 09:00 BruceZhou      
我还分不清逻辑层和界面层
  回复  引用  查看    
#188楼 2008-06-21 14:16 chunfeng      
问LZ一个问题
public DataSet GetTJYYList(string strLXRXM,string strKHMC)
{
StringBuilder strSql = new StringBuilder();
strSql.Append("SELECT KHGL_TJYY.YYBH,KHMC,LXRXM");
strSql.Append(",(SELECT XMMC FROM XTGL_SJZDMX WHERE FLBH='S501-02' AND XMBH=KHXZ) AS KHXZ_Name");
strSql.Append(" FROM KHGL_TJYY");
strSql.Append(" INNER JOIN KHGL_KHXX ON KHGL_TJYY.KHBH=KHGL_KHXX.KHBH");
strSql.Append(" WHERE 1=1");
List <SqlParameter> paramList = new List <SqlParameter>();
if (strLXRXM != string.Empty)
{
strSql.Append(" AND LXRXM=@LXRXM");
paramList.Add(new SqlParameter("@LXRXM", strLXRXM));
}
if (strKHMC != string.Empty)
{
strSql.Append(" AND KHMC=@KHMC");
paramList.Add(new SqlParameter("@KHMC", strKHMC));
}

SqlParameter[] sqlParams = paramList.ToArray();
return DbHelperSQL.Query(strSql.ToString(),sqlParams);
}

去掉strLXRXM,strKHMC的空格,放在数据层,逻辑层,还是表示层好
strLXRXM.Trim(),strKHMC.Trim(),按照分层原则,应该放在哪个层

  回复  引用  查看    
#189楼[楼主] 2008-06-23 12:49 玉开      
@chunfeng
如果你的项目的dll不需要发布给别人用,你确定一个原则,放在指定层就可以了。
如果dll可能会发布给别人使用,那就那个层都需要写。

  回复  引用  查看    
#190楼[楼主] 2008-06-23 12:52 玉开      
@BruceZhou
逻辑层执行业务逻辑,比如说买书方法有这样的逻辑,首先看库库中是否有足够的书,如果没有返回告诉用户信息,如果有继续执行看用户是否有足够的钱买书。。。这是业务逻辑。

ui层用来和用户交互,显示业务逻辑执行的结果。

  回复  引用  查看    
#191楼 2008-07-02 00:53 chunfeng      
希望博主详细写下三层架构中,每层该做些什么,不该做些做些什么,可以另外写一篇文章
  回复  引用  查看    
#192楼 2008-08-04 12:26 陈晨      
"需要逻辑层引用System.Web命名空间,显然是错误的。"
----------------------------------------------------
获取用户名时,难道非要在aspx页面得到用户名再传递到逻辑层吗?
在逻辑层直接通过HttpRuntime类就可以获取了
个人觉得没必要把System.Web非要看成是Web页面表示层的东西
它和System.Text一样都要FCL

  回复  引用  查看    
#193楼[楼主] 2008-08-05 14:45 玉开      
@陈晨
把UI和逻辑层分开是为了层次清晰,各层负责自己要做的事情,便于拆分;如果你再BLL层用HttpRuntime取用户名,那把UI层换成winform界面时,你怎么做?很显然就会有很大的问题。

  回复  引用  查看    
#194楼 2008-08-05 17:11 Myhsg      
个人感觉层次清晰些好,容易有条理性
存储过程我不通,很少用。

  回复  引用  查看    
#195楼 2008-08-07 11:21 hbf      
越讲越糊涂了,其实我感觉只要把各层的功能划清楚了,就不会存在这样的问题
  回复  引用  查看    
#196楼 2008-11-29 11:37 stg609      
混乱中
  回复  引用  查看    
最烦的就是页面里面拼写N多的sql语句 简直是垃圾人搞的东西
数据库的不用说高端开发就是中等的东西也是使用存储过程比较好 他完成外面的程序和数据的接口

现在还有N多人使用什么这个生成器哪个代码生成器的 ,最终项目搞的是乱七八糟。自己也学习不到啥东西 垃圾人还真多

  回复  引用    
三层不三层的没啥关系 首先看需求是啥 需求决定你的开发框架 不要动不动的就提什么三层
数据库存储过程一直是我的最爱
我几乎不允许自己的页面中出现任何一个表 这个也是对数据的保护

  回复  引用    
#199楼 2009-04-26 18:35 私家侦探      
同意 "事务处理应该放在业务逻辑层处理"
这样做的好处是数据访问层的方法粒度都很小,重用度高.
为什么没有人对这个进行讨论呢,看过很多项目还都是写在数据访问层

  回复  引用  查看    
#200楼 2009-05-19 17:25 kydcbt      
按博主的意思能否给个实例学习一下啊。
我的email:kaiyuan100@126.com 谢谢、


  回复  引用  查看    
评论共2页: 上一页 1 2 



发表评论

昵称: [登录] [注册]

主页:

邮箱:(仅博主可见)

评论内容:

  登录  注册

[使用Ctrl+Enter键快速提交评论]

0 668136




相关文章:

相关链接: