子非鱼,安知鱼之乐?

我的程序人生,累并快乐着。
posts - 40, comments - 210, trackbacks - 2, articles - 0
  博客园 :: 首页 :: 新随笔 :: 联系 :: 订阅 订阅 :: 管理

2006年9月3日

以后所有的个人日志都在这里更新,不再维护原来的日志系统了,因为那边的环境跟编程无关,导致博客看的人不多,写起来也没劲。
原来的日志里面还有190篇文章,以后挑点舍不得扔的迁移过来,其它的就算了。

posted @ 2006-09-03 13:41 Jason Cui 阅读(60) 评论(0) 编辑

今天重新翻看BOB大叔的《敏捷编程》,想起了仅有的我能够正确理解和应用的两个设计模式之一:工厂模式。(另一个是Command模式)。于是想试试看C#的代码如何实现工厂模式,结果发现确实跟PHP有不小的区别。

通常最容易想到的用途就是建立数据库工厂用于分别生成OleDB和SqlServer的处理类,通常的作法是建立一个工厂类,接收一个字符串,如果是"Sql",就生成一个Sql数据处理类(基类是一个通用数据库类,包含所要使用的数据库处理函数),并且返回;如果是OLEDB,就生成一个OLEDB类并返回,接收方用基类变量收到返回的参数就可以直接使用其中的函数,而不必关心返回的是什么类,处理的是什么数据库。

然而这个过程中,还是用到了switch语句,说明我们的模式应用还是有问题,还没有达到真正的面向对象。当需要增加一个数据库处理类的时候,不但需要添加这个类所需要的代码,还需要修改工厂类,增加一个Case语句。在PHP中就不存在这个问题,因为PHP对变量是非常宽容的。

最终找到了一个真正解决这个问题的方法,就是通过反射机制。C#中的System.Type类包含一个重要的方法:GetType(name,true),这样就可以得到以该名字所命名的类型的信息。然后利用另一个重要的类System.Activator的一个重要的方法:CreateInstance(type),这样我们就可以在不知道传入的类名的情况下生成该类名所对应的实例。

对工厂类经过这样的改造之后,程序调用端只要根据相关的配置文件传入正确的参数就可以得到正确的实例,而且添加新类的时候只要添加一个数据库处理子类,并通知用户就可以了,无需更改其它任何东西。

posted @ 2006-09-03 13:34 Jason Cui 阅读(156) 评论(0) 编辑

.NET语言比起其它面向对象的语言,多了一个东西delegate,(我不确定Java是不是有这个概念,好像没有看到过)。学起来挺难理解的,所以整理一下思路。

总体来说,委派就是一种把函数变成变量的方法,从而可以把函数进行赋值或者叠加。在PHP这一类语言中,语言本身使用了一种简单的特性来支持类似的基本方法,任何一个字符串变量如果后面带上括号就可以当作函数来执行,系统会自动查找与其变量值相同的函数来执行。

在C#中,委派大大加强了这个应用,你可以声明一个委派(普通的函数声明,修饰符加上delegate,只有包括参数的函数声明,没有函数体),然后使用这个委派名称声明具体的变量,这个变量现在就可以添加与委派声明方式相同的函数体了。而且,同一个委派变量可以叠加多个函数,静态函数和实例函数都可以。

当在某个位置以运行函数的方式调用该委派变量的时候,它所绑定的所有的函数会顺序执行。这就是VB.Net和C#中将自己的函数(方法)绑定到一个已有的类的事件(也是函数)并由对方主动调用的实现方式。其实,只不过是对方的类在它的某个方法中间调用了一下它自己的这个委派变量而已。

posted @ 2006-09-03 13:33 Jason Cui 阅读(82) 评论(0) 编辑

近日为了工作需要,开始真正学习C#了,看了一遍教材《C#编程语言详解》,作者Anders Hejlsberg亲自编写,语言并不华丽,却如编译器一般的严谨和逻辑。

看完之后有一些想不太明白的地方,一个个攻破。

第一个问题就是,没有别的语言那些明显的标记符,比如VB里面的Function, Dim之类的。在C#里不管是变量还是属性,或者函数,都使用相同的声明过程:public int SomeThing,如果后面加上小括号,那么就是一个函数。否则,如果带有大括号,那么就是属性,再否则,就是变量了。

而没有这些修饰符之后,带来了另一个问题,如果完成类的多态性。这个概念是类里面最重要也最难理解的一个概念,找来找去,书上似乎没有明确的提到这个语法。不过发现了几个重要的词,virtual, override, new。前两个在看C++的时候已经见过了,这个new又是什么呢?根据书上的说法和VS的提示,好像跟override有些想像。但是肯定是有区别的,于是写段代码研究一下。

使用经典的Human类作为基类,实现一个函数Walk,两个子类Man和Woman,继承这个类,分别实现这个函数Walk,不带任何其它的开关符。Main函数里使用

Human h1=new Man();
h1.Walk();
Human h2
=new Woman();
h2.Walk();

来查看结果。如果基类里面的函数没有virtual修饰符,而且子类里面的函数也不带修饰符,那么编译器会报错,提示加上new。OK,加上去,结果两个函数显示的都是执行了基类的Walk。这个似乎不太符合多态的定义。

于是在基类的函数上加上virtual,给两个子类分别用override和new定义函数,再执行一遍。第一个过程调用了Man的Walk,这个是正确的多态过程。第二个过程调用的还是Human的Walk。

由此可以看出,new是给子类新增加了一个函数,可以说除了函数名字相同以外,它跟基类里面的这个同名函数没有任何关系。当使用子类的类型来调用的时候,它会运行子类中的函数,而如果类型是基类的话,被隐藏的基类函数就会站到前台来。只有使用virtual定义基类中的函数,并使用override标记子类中的函数,才可以达到想要的多态类。

posted @ 2006-09-03 13:32 Jason Cui 阅读(693) 评论(1) 编辑

早上醒来,看到墙上挂着的照片突然想到一个问题。相框本身有个挂钩,但是我并没有把它直接挂到墙上的钉子上去,因为时间长了一定会生锈,会损坏这个挂钩的外观。于是我又在这个挂勾上加了一根短线,把这根线挂到墙上钉子上去。时间长了可以把这根线换一根,从而保证了相框的外观。我相信大部分人都会这样做的。

还有,新买来的PDA,因为要直接在屏幕上手写,时间长了屏幕就花掉了。屏幕一旦磨花,就再也没有办法还原了,除非换个屏幕。于是所有用PDA的人都是再买一张屏幕保护膜,把膜贴在屏幕上,再往膜上写字。时间长了,膜被磨花,只要撕掉重新买张膜就可以了。这样就最大限度的保证了PDA的完整性。

这种解决方案叫什么呢?在程序上来讲,这就是代理模式。在不破坏第三方库的情况下对其行为进行包装,也可以在不影响第三方库的情况下替换成另一个代理,而不影响使用者的行为。

事实上,所谓的23个设计模式,所面向的要解决的问题的方面只有不到一半,通常都有两个或者三个模式所要解决的问题是相同的,只是解决问题的手段和方向不同而已。所以总结起来,只需要10个大的模式就可以了。而这其中,又有两三个模式是真正融于生活的,就是那种你天天在用,只是不知道自己在用的模式,就像相框上的挂绳和PDA屏幕上的保护膜一样。

posted @ 2006-09-03 13:25 Jason Cui 阅读(93) 评论(0) 编辑

摘要: 研究了很多成熟的系统,大部分都是使用用户控件ascx文件的形式来做模板。但是我总觉得这样对于美工来说过于复杂了。在当前的一个项目中,我们的美工对于asp.net基本上一窍不通的,所以如果还以这种方式来做的话,只能是他做出HTML模板,然后我把模板拆成一块块的ascx。而且,这些ascx没有办法预览,设计期看起来非常的不直观。

想来想去还是觉得PHP的模板技术是最合适的,于是决定放弃一些asp.net的技术,整合一下PHP的模板方式。使用简单的HTML里面加标记,然后用纯正的C#语言读取html模板文件,用计算出来的字符串替换这些固定的标记,然后用response.write写到客户端。虽然原始一些,但是却可以很好的解决前面那些问题,我不需要再重复一次美工的工作了。不过还有个缺点,就是需要循环的部分就要单独拿出来做一个单独的文件,可能会导致文件数量比较多。不过相对来说,这不是大问题,大不了拆分模板目录。阅读全文

posted @ 2006-09-03 13:23 Jason Cui 阅读(723) 评论(1) 编辑

asp.net用到现在,有几个实在无法忍受的问题:

1.每次更新程序,都会启动一大堆Csc.exe进程来编译新的文件,所有的DLL我都编译过了,为什么要重新编译一次呢?而且在编译完成之前,每一个新的连接都会启动一个新的进程进行编译,这些进程之间又会互相抢占资源,造成堵塞,因此,每次更新程序,都要几分钟的时间才能启动起来。不知道当初设计的时候为什么不让它们等待一个进程编译完成以后大家一起使用?这样只需要十几秒就可以了。而编译完成之后,由于同时编译,可能还会带来另一个问题,就是会提示dll文件找不到,又需要重新完整编译一遍再上传,并清空dll缓存才可以。

据说asp.net 2.0里面已经有完整发布模式编译了,可以在本地进行完整编译,上传以后就可以直接用。有机会尝试一下。

今天发现另一个新问题,编译完成以后内存占用会上升一倍,而且不会降下来。内存的持续升高会带来网站Down掉,或者反应缓慢。又要重启IIS服务才能解决问题。而重启以后,又面临另一次编译......

2.在本地写程序的时候,通过SVN更新了别人上传的文件,如果Web项目有文件变动,比如新增加了aspx文件,或者删除了aspx文件,导致Web项目的project文件发生变化,会提示项目文件变动,是否重新载入。看上去这是个很贴心的功能,但是实际上当你选择了是,重新载入以后,是无法通过编译的,发生的都是奇怪的问题,比如某某函数找不到,通常这是因为这个函数是在另一个被引用的项目的定义的,过去看看,函数明明是在的。

编译的输出信息里面有一句话,被引用的那个Dll无法复制到bin目录,因为文件正在被使用等等。不得不把整个项目关掉重新打开。而联系IIS的这个过程又慢的要死。

据说VS2005把Web应用程序也当作普通的Dll项目来编写和编译了,不再需要IIS的支持了,也不知道是不是真的。

目前项目时间太紧,否则就花上一个星期把项目升级到2.0去了。不知道随着项目越来越大,会不会造成升级的难度的增加。再等个半年,大概3.0就出来了,或许可以直接升级到3.0上面去。

posted @ 2006-09-03 13:16 Jason Cui 阅读(141) 评论(0) 编辑

今天在做在线用户的时候突然发现一个问题,在所有的页面调用之前加入一个写入用户当前位置的过程,结果这个过程始终只写Default.aspx,无论点击的是哪个页面。跟踪了一通没有发现问题所在,结果被误导了。在首页上点击任何一个页面,最后首页都会被调用一次。而如果直接刷新首页,在生成的时候会连续调用两次Page_Load,这也就意味着整个网页要生成两次,也就是说完全的多了一次运算。不看不知道,一看吓一跳,所有的首页都有这个问题。而且还有一个莫名奇妙的问题,打开其它页面的时候,首页也会被调用一次。转来转去搞了一个下午,试了几个论坛上找到的解释也都不对。

晚上回家接着搞,把所有的Redirect查了一篇,没有找到任何问题。把页面模板里面的东西删的差不多了,也没发现问题所在。都是因为一开始没有发现是Default.aspx的差别,而对比页面是About.aspx。后来终于在微软的论坛上看到一句提示,如果HTML里面存在<img src="">,就会调用一次当前目录里面的Default文件。美工一直使用这种图像点位符来做高度分隔符,查了一下,果然在框架里找到了,去掉这一项一看,果然好了。真背。

posted @ 2006-09-03 13:15 Jason Cui 阅读(277) 评论(1) 编辑