手机浏览 RSS 2.0 订阅 膘叔的简单人生 , 腾讯云RDS购买 | 超便宜的Vultr , 注册 | 登陆
浏览模式: 标准 | 列表分类:PHP

RFC: MetaWeblog API

来自xmlrpc网站的资料:http://www.xmlrpc.com/metaWeblogApi
关于这些api还有一些背景资料在这里的:http://www.xmlrpc.com/stories/storyReader$2509,多看看啦。。。

Document status

This document was updated on 8/8/03, to incorporate all the RFCs related to the MetaWeblog API. The earlier version of the document is archived here. It has been reviewed by members of the MetaWeblog API mail list, and feedback has been incorporated.

On 8/24/03, I posted a last call for comments, and received several and incorporated some.

As of 8/26/03, this document is deployable. There may be changes, but they will be clearly documented, and will only clarify the spec, in no way will they change the format or protocol. It is now safe to deploy applications based on this spec.

What is the MetaWeblog API? 

The MetaWeblog API (MWA) is a programming interface that allows external programs to get and set the text and attributes of weblog posts. It builds on the popular XML-RPC communication protocol, with implementations available in many popular programming environments.

Relationship between MetaWeblog API and the Blogger API 

The MetaWeblog API is designed to enhance the Blogger API, which was limited in that it could only get and set the text of weblog posts. By the time MWA was introduced, in spring 2002, many weblog tools had more data stored with each post, and without an API that understood the extra data, content creation and editing tools could not access the data.

At the time of this writing, summer 2003, most popular weblog tools and editors support both the Blogger API and the MetaWeblog API.

Relationship between MetaWeblog API and RSS 2.0

The MetaWeblog API uses an XML-RPC struct to represent a weblog post. Rather than invent a new vocabulary for the metadata of a weblog post, we use the vocabulary for an item in RSS 2.0. So you can refer to a post's title, link and description; or its author, comments, enclosure, guid, etc using the already-familiar names given to those elements in RSS 2.0. Further since RSS 2.0 is extensible, so is the MetaWeblog API. We have designed conventions for representing attributes and namespaces in MWA.

Basic entry-points

There are three basic entry-points in the API:

metaWeblog.newPost (blogid, username, password, struct, publish) returns string

metaWeblog.editPost (postid, username, password, struct, publish) returns true

metaWeblog.getPost (postid, username, password) returns struct

The blogid, username, password and publish params are as in the Blogger API. newPost returns a string representation of the post id, again as defined by the Blogger API. The struct is where the juice is.

The struct 

In newPost and editPost, content is not a string, as it is in the Blogger API, it's a struct. The defined members of struct are the elements of <item> in RSS 2.0, providing a rich variety of item-level metadata, with well-understood applications.

The three basic elements are title, link and description. For blogging tools that don't support titles and links, the description element holds what the Blogger API refers to as "content."

Where an element has attributes, for example, enclosure, pass a struct with sub-elements whose names match the names of the attributes according to the RSS 2.0 spec, url, length and type.

For the source element, pass a struct with sub-elements, url and name.

For categories, pass an array of strings of names of categories that the post belongs to, named categories. On the server side, it's not an error if the category doesn't exist, only record categories for ones that do exist.

In getPost, the returned value is a struct, as with the Blogger API, but it contains extra elements corresponding to the struct passed to newPost and editPost.

The server must ignore all elements that it doesn't understand.

In a call to metaWeblog.newPost or metaWeblog.editPost, if the struct contains a boolean named flNotOnHomePage, then the post does not appear on the home page, and only appears on the specified category pages.

Request and response

Here's an example of a request and a response.

Here's the post that this request is getting info about.

metaWeblog.newMediaObject

metaWeblog.newMediaObject (blogid, username, password, struct) returns struct

The blogid, username and password params are as in the Blogger API.

The struct must contain at least three elements, name, type and bits.

name is a string, it may be used to determine the name of the file that stores the object, or to display it in a list of objects. It determines how the weblog refers to the object. If the name is the same as an existing object stored in the weblog, it may replace the existing object.

type is a string, it indicates the type of the object, it's a standard MIME type, like audio/mpeg or image/jpeg or video/quicktime.

bits is a base64-encoded binary value containing the content of the object.

The struct may contain other elements, which may or may not be stored by the content management system.

If newMediaObject fails, it throws an error. If it succeeds, it returns a struct, which must contain at least one element, url, which is the url through which the object can be accessed. It must be either an FTP or HTTP url.

metaWeblog.getCategories 

metaWeblog.getCategories (blogid, username, password) returns struct

The struct returned contains one struct for each category, containing the following elements: description, htmlUrl and rssUrl.

This entry-point allows editing tools to offer category-routing as a feature.

metaWeblog.getRecentPosts

metaWeblog.getRecentPosts (blogid, username, password, numberOfPosts) returns array of structs

Each struct represents a recent weblog post, containing the same information that a call to metaWeblog.getPost would return.

If numberOfPosts is 1, you get the most recent post. If it's 2 you also get the second most recent post, as the second array element. If numberOfPosts is greater than the number of posts in the weblog you get all the posts in the weblog.

Transmitting elements with attributes 

The members of the struct passed in newPost and editPost come from the elements of items in RSS 2.0. The most commonly used core elements have no attributes, so it's clear how to include them in the struct. However, some elements, such as source, enclosure and category, may have attributes and a value. Here are a simple set of rules for elements that have attributes and a value. Note that these rules do not apply to enclosure and source, which are provided for specifically above.

1. If an element has attributes, then represent the element with a struct, and include the attributes as sub-elements of the struct.

2. If an element has both attributes and a value, make the element a struct, include the attributes as sub-elements, and create a sub-element for the value with the name _value. Note that this means that no element can be passed through the API that has an attribute whose name is _value.

Transmitting elements from namespaces

RSS 2.0 allows for the use of namespaces. If you wish to transmit an element that is part of a namespace include a sub-struct in the struct passed to newPost and editPost whose name is the URL that specifies the namespace. The sub-element(s) of the struct are the value(s) from the namespace that you wish to transmit.

Comments 

The Blogger API provides a parameter called appkey that allows vendors to assign a key to developers so they can track and possibly limit usage of the API for certain tools. The MetaWeblog API doesn't specifically provide a parameter for an appkey. Applications that wish to transmit an appkey should add an element to the struct called appkey and set its value to the appkey that should be associated with the call.

Applications should use the fault-response scheme defined by XML-RPC. For example, trying to create, get, or edit a post without a valid username-password should generate a fault. Client applications should display the error string, as appropriate, to the user, for example, in a dialog, or in a server log.

Thanks

Thanks to Michael Bernstein for help editing this spec in summer 2003.

References

RSS 2.0; Dave Winer; 9/02.

RFC: MetaWeblog API; Dave Winer; 3/02.

Blogger API; Evan Williams; 8/01.

ManilaRPC; Andre Radke, Brent Simmons, Dave Winer; 1999.

XML-RPC; Dave Winer; 1998

Tags: wordpress, xml-rpc, metaweblog

资料:WordPress的四种远程XML-RPC发布协议

没有什么好说的,学习一下这些资料。然后折腾中。
想用word发布博客,这些就必须要看。
原文来自:http://m2009.org/?p=998

WordPress支持四种远程发布协议,他们是 WordPress,Movable Type,MetaWeblog和Blogger 的 XML-RPC发布协议。

 

WordPress发布协议
 
WordPress 发布协议值wordpress自己的文章发布协议,他的接口最为丰富,提供了包括操作评论文章在内的各种各样的支持
 
WordPress发布协议文档:http://codex.wordpress.org/XML-RPC_wp
 
Movable Type发布协议
 
Movable Type,简称MT,是由位于美国加州的Six Apart公司推出的网志(blog)发布系统。它是全球最受欢迎的网志系统之一,包含多用户,评论,引用(TrackBack),主题等功能,并广泛的支持各种第三方插件。
 
Movable Type不仅可以应用于个人的网志系统,而且可以应用于商业、教育等领域。Movable Type于2007年12月12日正式宣布以GPLv2的协议开源。
 
Movable Type发布协议文档:http://www.movabletype.org/documentation/
 
Movable Type 文件集:  http://mtbook.org/
 

MetaWeblog发布协议
 
The MetaWeblog API is an application programming interface created by software developer Dave Winer that enables weblog entries to be written, edited, and deleted using web services.
 
The API is implemented as an XML-RPC web service with three methods whose names describe their function: metaweblog.newPost(), metaweblog.getPost() and metaweblog.editPost(). These methods take arguments that specify the blog author’s username and password along with information related to an individual weblog entry.
 
The impetus for the creation of the API in 2002 was perceived limitations of the Blogger API, which serves the same purpose. Another weblog publishing API, the Atom Publishing Protocol became an IETF Internet standard (RFC 5023) in October 2007.
 
Many blog software applications and content mangement systems support the MetaWeblog API, as do numerous desktop clients.
 
MetaWeblog文档:http://www.xmlrpc.com/metaWeblogApi
 
Blogger发布协议
 
The Blogger Data API allows client applications to view and update Blogger content in the form of Google Data API feeds.
 
文档(墙外):http://www.blogger.com/developers/api/1_docs/
 
google:http://code.google.com/intl/zh-CN/apis/blogger/
 
比较详细的api文档
 
API参考文档:http://www.sixapart.com/developers/xmlrpc/

Tags: wordpress, xml-rpc, metaweblog

转:网站优化 更小的静态资源

这是来自perfgeeks.com的一篇文章,介绍了一些常见的工具,还有一个脚本。
在用YII框架的时候,我用的是hightman写的一个cssmin的插件,可以直接把css和js进行合并到一个文件。对于图片,我都是把这个艰巨的任务交给前端,由他们完成,至于他们用什么样的png或者gif之类的优化软不不是我关心的了。OK,先上文章
来源网址是是:http://www.perfgeeks.com/?p=660
内容如下:

更小的静态资源(js、css、png、gif),意味着更少的网络传送时间。构建的时候,可以把这些静态资源进行压缩优化(不像gzip/deflate压缩),使之更小化。有很多相应的开源工具帮助你完成这项工作。

javascript

  • Google Closure Compiler
  • UglifyJS
  • YUI Compressor
  • ShrinkSafe
  • 其它,比如JSMIN

Node.js、jQuery1.5开始使用UglifyJS,UglifyJS压缩比YUI Compressor更小、比Google Closure Compiler更安全。尽管如此,但UglifyJS需要部署NodeJS环境,所以我们还是选择使用Google Closure Compiler

style(css)

  • CSSTidy
  • YUI Compressor
  • Yslow/Google Page Speed

CSSTidy和YUI Compressor都很棒,我们还是选择老牌的YUI Compressor,因为我们更熟悉它,它也能够满足我们的需求。

png8/gif图片

  • Optipng
  • AdvanceCOMP(advpng、advdef)
  • ImageMagic(mogrify、identify、convert)
  • Pngcrush
  • Pngout
  • gifsicle
  • jpegtran

任何大一点的网站页面都会使用到不少图片,压缩优化图片很有必要。选择什么样的图片格式,决定了怎么去压缩图片。一般而言,只要是非动画图片,我们 推荐png8,即便是颜色很少的小图片(尽管这样的图片gif有更高压缩性,但应该使用css sprites)。Pngout没有开放源码,仅能在Window NT平台使用,所以我们并不考滤使它。Pngcrush虽然很好用,但是optipng、advpng以及advdef结合使用能把图片压缩得更小,所以 我们选择optipng、advpng以及advdef压缩优化PNG图片。 Optipng压缩优化图片、而advdef则优化压缩算法。

构建脚本

发布产品的时候,我们希望构建前端资源,包括压缩优化、合并等等。构建应该尽量满足:
1.整个过程是自动的,不需要人工介入
2.所有的操作都是安全的
3.免费的命令行工具

我们这里应用bash写了一个简版的部署脚本,能够简单地应付中小型网站静态资源发布。

XML/HTML代码
  1. #!/bin/sh  
  2. #filename:build.sh  
  3. IN_FILE="/var/www.imgwell.com/themes/ocean/misc"  
  4. OUT_FILE="/var/www.imgwell.com/misc"  
  5. EXCLUDE_FILES="jquery.min.js LAB.min.js"  
  6. GOOGLE_COMPILER="/opt/build/bin/compiler.jar"  
  7. YUI_COMPRESSOR="/opt/build/bin/yuicompressor-2.4.6.jar"  
  8. OPTIPNG="/usr/local/bin/optipng -quiet -o3 "  
  9. ADVPNG="/usr/local/bin/advpng -q -z -4 "  
  10. ADVDEF="/usr/local/bin/advdef -q -z -4 "  
  11.    
  12.    
  13. function mt_ver_code() {  
  14.     local MATRIX="23456789ABCDEFGHJKLMNPQRSTUVWXYZabcdefghijkmnpqrstuvwxyz"  
  15.     local LENGTH=12  
  16.     while [ "${n:=1}" -le "$LENGTH" ]; do  
  17.         local PASS="$PASS${MATRIX:$(($RANDOM%${#MATRIX})):1}"  
  18.         let n+=1  
  19.     done  
  20.     echo -n ${PASS}  
  21. }  
  22.    
  23. function mt_file_ext() {  
  24.     local FILE=`basename -- "$1"`  
  25.     echo -n "${FILE##*.}"  
  26. }  
  27.    
  28. function mt_file_size() {  
  29.     if [ -f "$1" ]; then  
  30.         echo -n `ls -l -- "$1" |awk '{print $5}'`  
  31.     else  
  32.         echo -n 0  
  33.     fi  
  34. }  
  35.    
  36. function mt_has_exclude() {  
  37.     if [ -z "$EXCLUDE_FILES" ]; then  
  38.         echo -n 0  
  39.         return 0  
  40.     fi  
  41.     echo "$EXCLUDE_FILES" |grep -q -w -- "${1}"  
  42.     if [ $? -eq 0 ]; then  
  43.         echo -n "1"  
  44.     else  
  45.         echo -n "0"  
  46.     fi  
  47. }  
  48.    
  49. function mt_google_compile() {  
  50.     java -jar "$GOOGLE_COMPILER" --js $1 --js_output_file $2  
  51. }  
  52.    
  53. function mt_yui_compressor() {  
  54.     java -jar "$YUI_COMPRESSOR" $1 -o $2 --charset utf-8  
  55. }  
  56.    
  57. function mt_png_opti() {  
  58.     [ -f "`echo ${OPTIPNG} |awk '{print $1}'`" ] && ${OPTIPNG} "${1}"  
  59.     [ -f "`echo ${ADVPNG} |awk '{print $1}'`" ] && ${ADVPNG} "${1}"  
  60.     [ -f "`echo ${ADVDEF} |awk '{print $1}'`" ] && ${ADVDEF} "${1}"  
  61. }  
  62.    
  63. function __main__() {  
  64.     [ -d "$IN_FILE" ] || exit 1  
  65.     local VER_CODE=`mt_ver_code`  
  66.     local FILE_STATUS="!"  
  67.     mkdir -p "${OUT_FILE}/${VER_CODE}"  
  68.    
  69.     for f in `ls -1 "$IN_FILE"`; do  
  70.         if [ -d "${IN_FILE}/${f}" ] ; then  
  71.             continue  
  72.         fi  
  73.    
  74.         local HAS_EXCLUDE=`mt_has_exclude "${f}"`  
  75.         local FILE_SRC_SIZE=`mt_file_size "${IN_FILE}/${f}"`  
  76.    
  77.         if [ "`mt_file_ext "${f}"`" = "js" -a "$HAS_EXCLUDE" = "0" ]; then  
  78.             mt_google_compile "${IN_FILE}/${f}" "${OUT_FILE}/${VER_CODE}/${f}"  
  79.             FILE_STATUS="G"  
  80.         elif [ "`mt_file_ext "${f}"`" = "css" -a "$HAS_EXCLUDE" = "0"  ]; then  
  81.             mt_yui_compressor "${IN_FILE}/${f}" "${OUT_FILE}/${VER_CODE}/${f}"  
  82.             FILE_STATUS="Y"  
  83.         elif [ "`mt_file_ext "${f}"`" = "png" -a "$HAS_EXCLUDE" = "0" ]; then  
  84.             cp "${IN_FILE}/${f}" "${OUT_FILE}/${VER_CODE}"  
  85.             [ -f "${OUT_FILE}/${VER_CODE}/${f}" ] && {  
  86.                 mt_png_opti "${OUT_FILE}/${VER_CODE}/${f}"  
  87.                 FILE_STATUS='O'  
  88.             }  
  89.         else  
  90.             cp "${IN_FILE}/${f}" "${OUT_FILE}/${VER_CODE}"  
  91.             if [ $? -eq 0 ]; then  
  92.                 FILE_STATUS="-"  
  93.             else  
  94.                 FILE_STATUS="D"  
  95.             fi  
  96.         fi  
  97.    
  98.         local FILE_DST_SIZE=`mt_file_size "${OUT_FILE}/${VER_CODE}/${f}"`  
  99.         echo "${FILE_STATUS} ${HAS_EXCLUDE} ${f} ${FILE_SRC_SIZE}/${FILE_DST_SIZE}"  
  100.     done  
  101.     echo "===========/" $VER_CODE "\=========="  
  102. }  
  103.    
  104. __main__  

执行结果如下

[root@www-avatar misc]# ./build.sh
O 0 6N9FQPpTHCy.png 820/258
Y 0 base.css 40171/35530
O 0 FSEB6oLTK3I.png 10362/10362
- 0 GsNJNwuI-UM.gif 522/522
O 0 heart.png 921/807
O 0 IJYgcESal33.png 5771/5771
O 0 _IKHHfAgFQe.png 2635/2302
G 0 jquery.elastic.js 4988/1665
- 1 jquery.min.js 85260/85260
G 0 jquery.ui.dialog.js 10074/5274
G 0 jquery.ui.pview.js 4565/2878
- 1 LAB.min.js 5537/5537
O 0 lFahQXTaTNO.png 90/90
G 0 mutfa.js 36958/21777
O 0 nCItFQafRu8.png 452/288
O 0 p13yZ069LVL.png 792/219
- 0 plupload.flash.swf 18537/18537
G 0 plupload.full.js 48277/46682
Y 0 position.css 7737/7440
O 0 star.png 3292/283
G 0 stars.js 6333/2622
Y 0 ui_plugin.css 12794/12079
G 0 up.js 6230/3991
- 0 uVR6w3wRHEJ.gif 54/54
O 0 WSQ2wnhSG-F.png 245/229
- 0 _ZWZupdaAgS.gif 827/827
===========/ LruQcmx4Zi84 \==========

总结

1.UglifyJS压缩比YUI Compressor更小,比Google Closure Compiler更安全。不想冒险,还是应该选择UglifyJS。若想最小化,可以选择Google Closure Compiler
2.YUI Compressor压缩css文件。但CSSTidy也很不错
3.optipng -o3 *.png |advpng -z -4 *.png |advdef -z -4 *.png 将最大化压缩优化png图片
4.网页尽量使用png格式图片,并且压缩优化它,使之最优

-------------------------------

纠结,原文中的代码是有配色的,但是COPY过来就没有配色了,而自带的配色没有bash的配色。所以。。。将就点看了,或者看原文吧:http://www.perfgeeks.com/?p=660

Tags: perfgeeks, hightman, cssmin

郁闷,又在纠结swfupload的302问题了

这是一个非常让人郁闷的问题。问题也知道根源在哪里,但TMD就是纠结。
因为是SWF,你懂的,有些包抓不到的。但不搞又不行,准备用smartsniff来抓数据看了。

其实就是一个session的问题,但还没有彻底搞定,真烦人。
yii框架中应用swfupload还是有点纠结的(其实以前都没有问题,不知道什么时候,突然间就开始有这个BUG了。。。)

仔细排查了一下,其实,大家都知道,session原本就是用来处理登录这种玩意的。果然排查后发现,新开的上传进程之所以是302,就是因为跳转到登录页面去了。晶啊。每次都是这个原因,我靠

来自coolshell:重构代码的7个阶段

代码重构是所有人的噩梦。怎么样重构一系列代码,是一件非常重要的事情。
在没转这篇文章之前,我的重构都是先从部分非关键代码开始重构,而且把这一部分慢慢的独立成一个模块,在采用新的架构的时候,这一块也可以被嵌入的新的架构中。
当然在其中也会遇到一系列的问题,但这样来说会轻松一点。
OK,让我们来看原文吧。
原文是来自:http://coolshell.cn/articles/5201.html

你曾去想重构一个很老的模块,但是你只看了一眼你就恶心极了。文档,奇怪的函数和类的命名,等等,整个模块就像一个带着脚镣的衣衫褴褛的人,虽然能 走,但是其已经让人感到很不舒服。面对这种情况,真正的程序员会是不会认输的,他们会接受挑战认真分析,那怕重写也在所不惜。最终那个模块会被他们重构, 就像以前和大家介绍过的那些令人销魂的编程方式中的屠宰式编程一样。下面是重构代码的几个阶段,文章来自:The 7 stages of refactoring,下面的翻译只是意译。

第一阶段 - 绝望

在你开始去查看你想要重构的模块的,你会觉得好像很简单,这里需要改一个类,那里需要改两到三个函数,重写几个 函数,看上去没什么大不了的,一两天就搞定了。于是你着手开始重构,然后当你调整重构了一些代码,比如改了一些命名,修理了一些逻辑,渐渐地,你会发现这 个怪物原来体型这么大,你会看到与代码不符甚至含糊不清的注释,完全摸不着头脑的数据结构,还有一些看似不需要方法被调了几次,你还会发现无法搞清一个函 数调用链上的逻辑。你感到这个事可能一周都搞不定,你开始绝望了。

第二阶段 – 找最简单的做

你承认你要重构的这个模块就是一个可怕的怪物,不是一两下就可以搞定的,于是你开始着干一些简单的事,比如重新命名一下几个函数,移除一些代码的阻碍,产生几个常量来消除magic number,等等,你知道这样做至少不会让代码变得更糟糕。

第三阶段 – 再次绝望

但是接下来的事会让你再次撞墙。你会发现那些代码的瑕疵是些不痛不痒的事,改正这些事完全于事无补,你应该要做 的事就是重写所有的东西。但是你却没有时间这么干,而这些代码剪不乱理还乱,耦合得太多,让你再一次绝望。所以,你只能部分重写那些不会花太多时间的部 分,这样至少可以让这些老的代码能被更多的重用。虽然不完美,但是至少可以试试。

第四阶段 – 开始乐观

在你试着部分重构这个模块几天之后,随着重构了几个单元后,虽然你发现改善代码的进度太慢了,但此时,你已知道代码应该要被改成什么样,你在痛苦之 后也锁定了那些那修改的类。是的,虽然你的时间预算已经超支,虽然要干的事比较多,但你还是充满希望,觉得那是值得的。你胸中的那团火又被点燃了。

第五阶段  - 快速了结

在这个时候,你发现你已花了太多的时间,而情况越来越复杂,你感到你所面对的情况越来越让你越到不安,你明白你自己已经陷入了困境。你原本以为只需 要一次简单的重构,然而现在你要面对的是重写所有的东西。你开始意识到原因是因为你是一个完美主义者,你想让代码变得完美。于是你开始在怠慢你文档,并想 找到一个捷径来重写老的代码,你开始采用一些简单而粗暴,快速而有点肮脏的方法。虽然不是很完美,但你就是这样去做了。然后,你开始运行测试做UT,发现 UT报告上全是红色,几乎全都失败了,你恐慌了,于是快速地fix代码,然后让UT 能工作。此时,你拍拍自己胸口,说到,没问题 ,于是就把代码提交了。

第六阶段 – 修改大量的Bug

你的重写并不完美,虽然其过了测试,但是那些UT测试对于你的新的代码有点不太合适,虽然他们都没有报错,但是他们测试得范围太小了,没有覆盖到所 有的情况和边界。所以,在这以后,你还需要几周或是更长的时间不得不来修正越来越多的bug,这使得你的设计和代码在每一次quick-fix后就变得越 来越难看。此时,代码已经不像你所期望的那样完美了,但你依然觉得他还是比一开始要好一些。这个阶段可能历经几个月。

第七阶段  - 觉悟

经过了6个月,你重写的模块又出了一个比较严重的bug。这让你重构的那个模块变得更难堪。你发现出的这个问题是和当初的设计不一致,你还发现被你 重构掉的那段老的代码并不是当初看上去的那么坏,那段老的代码确实考虑到了一些你未曾考虑到的事情。这个时候,你团队里有人站出来说这个模块应该被重构或 是重写,而你却不动声色地一言不发,并希望那个站出来的人能在几个月后能觉悟起来。

——————

不知道这是不是你的经历,我经历过很多次这样的事。对于很多维护性质的项目,我犯过的错误让我成了一个实实在在的保守派,我几乎不敢动,那怕看到代 码很不合口味。当然,那些从来没有写过代码的敏捷咨询师一定会说用TDD或是UT可以让你的重构更有效也更容易,因为这样会让他们显得更我价值,但我想告 诉你,这种脱离实际的说法很不负责任,这就好比说—— 我在杀猪的时候遇到了一些麻烦,因为我对猪的生理结构不清楚,或是这本来就是一头畸形的猪,导致我杀的猪很难看,而伟大的敏捷咨询师却告诉我,要用一把更快更漂亮的刀。软件开发永远不是那么简单的事,杀猪也一样。

-----------------------
不过我想,更多的时候,安排你重构一份代码的时候,你可能想到的就是我情愿重写一份也不愿意重构,对着数据库结构和一些业务逻辑,然后就开始重写了。只是这样的写法,后面遇到的问题会非常非常多。你呢?也是这样的吗?

Tags: 重构