Submitted by gouki on 2009, April 22, 9:36 AM
HTML重构,以前是一个新鲜的东西,我也没有理解,博客园上有人在介绍,还写了三篇。。。
我这里只简单的复制点东西,还是以链接为重吧。(战略篇全文如下)
《Refactoring HTML: Improving the Design of Existing Web Applications》是一本精彩的HTML重构指南,作者给出了HTML重构的实践路线和方法。本文是《Refactoring HTML》的读书笔记,按照我的理解将全书的分为:战略篇,战术篇,工具篇。
本文是战略篇:全局方略的角度介绍重构的内涵,原因,时机,目标
嗯哼,我们开始:
进行重构就像打一场仗,而战争的发起是要慎重考虑的,《孙子兵法》里面讲“兵者,国之大事,死生之地,存亡之道,不可不察也。”所以动手重构之前首先要回答下面几个问题:
- 什么是重构?
- 为什么进行HTML重构?
- 什么时候进行HTML重构?
- HTML重构的目标是什么?
- 面对质疑:还要重构么?
什么是重构 Refactoring?
本书侧重实战,没有《UML Distilled》那样高屋建瓴的抽象,即使有抽象,抽象层面牵扯的细节过多(这一点在后续的阅读中也可以发现)。这一部分内容我援引了《Refactoring: Improving the Design of Existing Code》对重构的定义:
Refactoring (noun): a change made to the internal structure of software to make it easier to understand and cheaper to modify without changing its observable behavior.
Refactor (verb): to restructure software by applying a series of refactorings without changing its observable behavior.
为什么进行HTML重构?
抽象地讲,HTML重构的可以让代码更能适应变化,应对系统和领域需求为新功能的开发提供更优秀的基础。
具体地讲,HTML重构可以:
- 让代码更具有可读性,更容易理解
- 重构过程中往往有意外的收获:发现隐藏的系统Bug
- 增强页面可用性, 关注点从设计者开发者转移到使用者
- 缩短提高页面的呈现时间(Slow pages -Rendering Times)
- 解决页面浏览器不兼容问题
- 搜索引擎优化Search Engine Optimization
进行HTML重构的时机?
- 每一次进行重新设计之前;新功能将构建在一个更稳固的基础之上
- Refactor When You Need to Fix a Bug
- Refactor As You Do a Code Review
- 一个原则:勿以善小而不为;重构的过程往往是断断续续的,很少有一个连续的时间给我们进行重构。所以我们只要有机会进行重构,就动手去做吧
HTML重构的目标(What Refactor To) ?
- XHTML
理由:XHTML更加严格,浏览器不再解析乱作一团的标签而是格式规范的页内容,这时负担从浏览器转移到页面开发者。内容聚合,搜索引擎优化,样式表都可以更好的应用基础。开发者能够更容易调试和解决问题,因为问题更容易定位了。XHTML不能完全解决浏览器兼容问题,但是它能够消除大部分的浏览器不兼容问题已经居功甚伟。主流HTML编辑器都提供对XHTML的支持。XHTML是未来Web应用提供坚实的基础,如:MathXML MusicXML SVG。
- CSS
理由:将展现层从内容中分离出来。为不同的阅读者提供高可读性。减少代码重复,节省带宽。
REST(Representational State Transfer表述性状态转移)是一种针对网络应用的设计和开发方式,可以降低开发的复杂性,提高系统的可伸缩性。REST提出了一些设计概念和准则:
1.网络上的所有事物都被抽象为资源(resource);
2.每个资源对应一个唯一的资源标识(resource identifier);
3.通过通用的连接器接口(generic connector interface)对资源进行操作;
4.对资源的各种操作不会改变资源标识;
5.所有的操作都是无状态的(stateless)。
REST之所以能够提高系统的可伸缩性,是因为它强制所有操作都是stateless的,这样就没有context的约束,如果要做分布式、做集群,就不需要考虑context的问题了。同时,它令系统可以有效地使用pool。REST对性能的另一个提升来自其对client和server任务的分配:server只负责提供resource以及操作resource的服务,而client要根据resource中的data和representation自己做render。这就减少了服务器的开销。
重构的目标不是金科玉律,你没有必要逐一进行实践。你可以按照XHTML->CSS-->Rest的顺序按部就班步步为营,也可以根据实际情况调整重构目标和计划。但是只要你做了,你就可以从重构过程中得到好处。
面对质疑:还要重构么?
重构的本质决定了它不是生产性的,重构的完成并没有新功能的产生。所以重构往往面临来自各方面的质疑:
面对质疑我们给出这样的答案:
- HTML重构从长远来看为后续开发提供了一个良好的基础,实际上是节省了时间。因为系统更容易添加新功能,更容易维护。重构的过程能让开发者对以前的工作有一个思考,对新人是一个熟悉系统的机会。
- HTML重构本身并不会占用太多的时间,因为我们有很多自动化的工具可用。
- HTML重构不需要一个连续的时间,断断续续的时间未尝不可,对于开发者来说,进行重构就像日行一善。
HTML重构:战略篇
HTML重构:战术篇
HTML重构:工具篇
Tags: html, 重构
PHP | 评论:3
| 阅读:23611
Submitted by gouki on 2009, April 21, 9:16 AM
这个东西,我实在不知道放在哪个分类了。。但因为我是用PHP进行开发的,因此我还是将它归为PHP分类
昨天在Yhustc的博客上看城管操作手册,结果顺便看到了这个免费的webservice列表。
yhustc的博客功能越来越强大了,支持直接的ID的文章,现了也支持这种以英文名为路径的文章了,等再强一点,我也考虑换成yblog,哈哈,不过,要等他写转sablog的程序(实在是2.0到现在都没有出来,等的心急了)
对于sablog,我在另外的应用里,已经将它的模版机制全部转为discuz的,因为自己熟悉DZ的模版,改起来更快了。只是不知道何年才会派上用场。。。。
废话说了这么多,上重点的:
某网站支持
国内手机号码归属地查询WEB服务
2400多个城市5日天气预报 WEB服务
股票行情数据 WEB 服务(支持香港、深圳、上海基金、债券和股票;支持多股票同时查询)
中国电视节目预告(电视节目表)
火车时刻表 WEB 服务
IP地址来源搜索 WEB 服务
等等...
是什么网站呢?Look。。。
http://www.webxml.com.cn/zh_cn/web_services.aspx
其他两种我不懂,但wsdl我还是懂的。啥时候有空看看,oh yeah
Tags: webservice
PHP | 评论:0
| 阅读:27813
Submitted by gouki on 2009, April 13, 12:19 PM
放在PHP栏目是我仔细想过的,虽然文章内容里并未提及到PHP
开发WEB,很多人在一开始就考虑了优化优化再优化,但是,如果按照你这样的优化下去,当你发现瓶劲的时候你怎么办?你已经无法优化了。。
因此,为自己的代码预留一点优化空间,先赶着把代码上线,然后再边运行边优化。一来也保证了上线的时间,二来也可以在运行时注意到哪些地方是需要重点优化的。
以下内容来自守望轩(博客园)的文章:原文http://www.cnblogs.com/xjb/archive/2009/04/13/no-premature-optimization.html
Donald Knuth说“过早优化是万恶之源”(premature optimization is the root of all evil)。这话也许有些夸张,但“过早优化”的危害我觉得不能忽视。同时,我觉得“过早优化”的概念不专属编写程序,生活中的示例也比比皆是。不信,你看看下面这些情形你是否遇到过:
http://www.watch-life.net/life-thinking/no-premature-optimization.html
1、当你开始学一门程序语言的时候(比如c#),你想如果可以精通开发工具(比如Visual Studio)一定如虎添翼,于是一开始你就花很多时间去研究开发工具,而忘记自己学习的重点是语言本身,而非工具。或者,一开始,你花不少的时间去选择哪门程序语言,比较各种语言的优劣,在五花八门的语言前面犹豫不决,这个想学,那个也不想放弃,结果都是学个半路子。
2、当你学习一门外语比如英语的时候,一开始,你花了很多的时间去下载有关英语资料,花了很多的时间去找英语书籍,以为有了这些资料和书籍就可以学好英文,而不是一开始就踏踏实实的从单词、语法开始,结果后来资料下载了一大堆,书籍买了不少,却没有坚持下去。
3、你想搞体育锻炼,比如打羽毛球,于是一开始你花大量时间去买球衣、球鞋、球拍等装备,可没连几天,你发现自己开始三天打鱼了,最后,那些装备都起了灰,也没锻炼几次。
4、你想做时间管理(Getting Things Done),于是你研究各种时间管理的资料,上各种时间管理技巧的网站,比如lifehack、 digg 、gtdlife,下载对最流行的GTD的管理软件,以节省时间的名义浪费时间,很浮躁,不能做到实实在在把每天的计划都落实,拖拖拉拉。
5、你有没有这样的体验,一本书你总是对开头的部分看的最仔细,后面的章节没坚持看下去,下次又重复这种循环。当你计划做一件事的时候,总是规划的 非常完美,几乎考虑每个细节,但却没有认认真真、一步一步执行,或者过早完美计划,反而让你缩手缩脚,犹豫不前,瞻前顾后,顾此失彼,最后虎头蛇尾。
6、比如,如果我有了钱,我就如何如何享受快乐,比如,如果我将来有了很多的时间,我就会花更多的时间陪家人或锻炼…
这样类似的例子还可以举很多。
过早优化对大的问题在于:过早关注不重要的部分,而忽略行动和目标本身。以静态的思维来优化,殊不知,事务发展总是动态的,“优化”是需要长期的实 践积累才可以获得。出发点是好的,但往往好心办坏事,折腾大量的时间,做了很多不该做的,而该做的、重要的反而没做。强化外部条件、工具等外在,而忽略内 在因素和行动本身,或者,过多期望将来,而忽略当下眼前。
活在当下,实实在在做好手头的事,是避免“过早优化”最好的方法之一。
Tags: 优化
PHP | 评论:0
| 阅读:20715
Submitted by gouki on 2009, April 8, 7:31 AM
这是一个比较老的分词程序,原文中的一些链接现在不是地址不正确就是打不开了。由此可以证明它是多老了。
再加上PHP直接进行分词的性能本来就不咋地,因此,建议仅仅用在很小的地方,比如自动添加TAG之类的。
原文如下:http://blog.sina.com.cn/s/blog_5677bc54010000i5.html
用PHP去做中文分词并不是一个太明智的举动, :p
下面是我根据网上找的一个字典档, 简易实现的一个分词程序.
(注: 字典档是gdbm格式, key是词 value是词频, 约4万个常用词)
代码请参见http://www.shi8.com/out/support/art_316.txt
PHP代码
- <?php
-
-
-
-
-
-
- function getmicrotime(){
- list($usec, $sec) = explode(" ",microtime());
- return ((float)$usec + (float)$sec);
- }
- $time_start = getmicrotime();
-
-
-
- class ch_dictionary {
- var $_id;
-
- function ch_dictionary($fname = "") {
- if ($fname != "") {
- $this->load($fname);
- }
- }
-
-
- function load($fname) {
- $this->_id = dba_popen($fname, "r", "gdbm");
- if (!$this->_id) {
- echo "failed to open the dictionary.($fname)<br>\n";
- exit;
- }
- }
-
-
- function find($word) {
- $freq = dba_fetch($word, $this->_id);
- if (is_bool($freq)) $freq = -1;
- return $freq;
- }
- }
-
-
-
- class ch_word_split {
- var $_mb_mark_list;
- var $_word_maxlen;
- var $_dic;
- var $_ignore_mark;
-
- function ch_word_split () {
- $this->_mb_mark_list = array(","," ","。","!","?",":","……","、","“","”","《","》","(",")");
- $this->_word_maxlen = 12;
- $this->_dic = NULL;
- $this->_ignore_mark = true;
- }
-
-
- function set_dic($fname) {
- $this->_dic = new ch_dictionary($fname);
- }
-
- function set_ignore_mark($set) {
- if (is_bool($set)) $this->_ignore_mark = $set;
- }
-
-
- function string_split($str, $func = "") {
- $ret = array();
-
- if ($func == "" || !function_exists($func)) $func = "";
-
- $len = strlen($str);
- $qtr = "";
-
- for ($i = 0; $i < $len; $i++) {
- $char = $str[$i];
-
- if (ord($char) < 0xa1) {
-
- if (!emptyempty($qtr)) {
- $tmp = $this->_sen_split($qtr);
- $qtr = "";
-
- if ($func != "") call_user_func($func, $tmp);
- else $ret = array_merge($ret, $tmp);
- }
-
-
- if ($this->_is_alnum($char)) {
- do {
- if (($i+1) >= $len) break;
- $char2 = substr($str, $i + 1, 1);
- if (!$this->_is_alnum($char2)) break;
-
- $char .= $char2;
- $i++;
- } while (1);
-
- if ($func != "") call_user_func($func, array($char));
- else $ret[] = $char;
- }
- elseif ($char == ' ' || $char == "\t") {
-
- continue;
- }
- elseif (!$this->_ignore_mark) {
- if ($func != "") call_user_func($func, array($char));
- else $ret[] = $char;
- }
- }
- else {
-
- $i++;
- $char .= $str[$i];
-
- if (in_array($char, $this->_mb_mark_list)) {
- if (!emptyempty($qtr)) {
- $tmp = $this->_sen_split($qtr);
- $qtr = "";
-
- if ($func != "") call_user_func($func, $tmp);
- else $ret = array_merge($ret, $tmp);
- }
-
- if (!$this->_ignore_mark) {
- if ($func != "") call_user_func($func, array($char));
- else $ret[] = $char;
- }
- }
- else {
- $qtr .= $char;
- }
- }
- }
-
- if (strlen($qtr) > 0) {
- $tmp = $this->_sen_split($qtr);
-
- if ($func != "") call_user_func($func, $tmp);
- else $ret = array_merge($ret, $tmp);
- }
-
-
- if ($func == "") {
- return $ret;
- }
- else {
- return true;
- }
- }
-
-
- function _sen_split($sen) {
- $len = strlen($sen) / 2;
- $ret = array();
-
- for ($i = $len - 1; $i >= 0; $i--) {
-
-
-
- $w = substr($sen, $i * 2, 2);
-
-
- $wlen = 1;
-
-
- $lf = 0;
- for ($j = 1; $j <= $this->_word_maxlen; $j++) {
- $o = $i - $j;
- if ($o < 0) break;
- $w2 = substr($sen, $o * 2, ($j + 1) * 2);
-
- $tmp_f = $this->_dic->find($w2);
-
- if ($tmp_f > $lf) {
- $lf = $tmp_f;
- $wlen = $j + 1;
- $w = $w2;
- }
- }
-
- $i = $i - $wlen + 1;
- array_push($ret, $w);
- }
-
- $ret = array_reverse($ret);
- return $ret;
- }
-
-
- function _is_alnum($char) {
- $ord = ord($char);
- if ($ord == 45 || $ord == 95 || ($ord >= 48 && $ord <= 57))
- return true;
- if (($ord >= 97 && $ord <= 122) || ($ord >= 65 && $ord <= 90))
- return true;
- return false;
- }
- }
-
-
-
- function call_back($ar) {
- foreach ($ar as $tmp) {
- echo $tmp . " ";
-
- }
- }
-
-
- $wp = new ch_word_split();
- $wp->set_dic("dic.db");
-
- if (!isset($_REQUEST['testdat']) || emptyempty($_REQUEST['testdat'])) {
- $data = file_get_contents("sample.txt");
- }
- else {
- $data = & $_REQUEST['testdat'];
- }
-
-
- echo "<h3>简易分词演示</h3>\n";
- echo "<hr>\n";
- echo "分词结果(" . strlen($data) . " chars): <br>\n<textarea cols=100 rows=10>\n";
-
-
- $wp->set_ignore_mark(false);
-
-
- $wp->string_split($data, "call_back");
-
- $time_end = getmicrotime();
- $time = $time_end - $time_start;
-
- echo "</textarea><br>\n本次分词耗时: $time seconds <br>\n";
- ?>
- <hr>
- <form method=post>
- 您也可以在下面文本框中输入文字,提交后试验分词效果:<br>
- <textarea name=testdat cols=100 rows=10></textarea><br>
- <input type=submit>
- </form>
- <hr>
文章引用自:http://www.im286.net/viewthread.php?tid=1157015
Tags: 分词, gbm
PHP | 评论:0
| 阅读:22199
Submitted by gouki on 2009, April 4, 8:13 AM
首先我们看一下php手册中关于删除cookie的说明
------以下引用php手册内容--------------
bool setcookie ( string name [, string value [, int expire [, string path [, string domain [, bool secure]]]]] )
要删除 cookie 需要确保它的失效期是在过去,才能触发浏览器的删除机制。
下面的例子说明了如何删除刚才设置的 cookie: 例子 2. setcookie() 删除
例子
// 将过期时间设为一小时前
setcookie("TestCookie", "", time() - 3600);
setcookie("TestCookie", "", time() - 3600, "/~rasmus/", ".utoronto.ca", 1);
----------------引用结束--------------------------
删除一个cookie的方法就是把这个cookie的有效期设置为当前时间以前,这
也是几乎所有php程序员都会这么做。
后来一个初接触php的朋友告诉我,他在程序中本想把一个cookie的值设置为
空,结果导致这个cookie直接被删除。我当时的第一反应是不相信,于是测试
了一下
setcookie("testcookie", '');
print_r($_COOKIE);
结果果然是整个$_COOKIE数组都是空的,而非仅仅$_COOKIE['testcookie']为
空.于是用winsock抓包,观察返回的http头,发现http头竟然是
Set-Cookie: testcookie=deleted; expires=Mon, 18-Jun-2007 02:42:33 GMT
这说明setcookie("testcookie", '');的的确确是将testcookie这个cookie直
接删除.而关于这种情况在php手册中完全没有说明.
最后阅读php源码,终于发现真相(这就是开源的好处了,有什么不清楚的内幕
直接查源码)
以下代码可以在php5.20的linux源码包中ext/standard/head.c第99行附近找到.
C++代码
- if (value && value_len == 0) {
-
-
-
-
-
- time_t t = time(NULL) - 31536001;
- dt = php_format_date("D, d-M-Y H:i:s T", sizeof("D, d-M-Y H:i:s T")-1, t, 0 TSRMLS_CC);
- sprintf(cookie, "Set-Cookie: %s=deleted; expires=%s", name, dt);
- efree(dt);
- } else {
- sprintf(cookie, "Set-Cookie: %s=%s", name, value ? encoded_value : "");
- if (expires > 0) {
- strcat(cookie, "; expires=");
- dt = php_format_date("D, d-M-Y H:i:s T", sizeof("D, d-M-Y H:i:s T")-1, expires, 0 TSRMLS_CC);
- strcat(cookie, dt);
- efree(dt);
- }
- }
源码中清清楚楚的显示,if (value && value_len == 0) ,当value_len为0
时
sprintf(cookie, "Set-Cookie: %s=deleted; expires=%s", name, dt);
会发送删除cookie的http头给浏览器.
最后我们可以得出结论,在php中使用
setcookie($cookiename, '');或者 setcookie($cookiename, NULL);
都会删除cookie,当然这些手册中并没有。
Tags: 删除, cookie, 清空
PHP | 评论:1
| 阅读:31190