Chatterley
2011年11月01日
默认分类
在newcp的开发过程中,经过权衡后最终使用基于YII框架开发。在使用了YII框架的MVC结构,程序结构自然而然使用了Controller->Model->View。在Model细分层次结构为Service->Logic->ARModel。在这样的结构下,无论是使用JAVA还是.NET的项目,往往容易被套在事务脚本形式,newcp也不例外。每个功能处理都是使用同一个流程。
最后在编写代码的时候,则会出现如下的代码结构(为了便于阅读代码都已经过调整):
//检查余额
$accountService = new FundsAccountService();
$account = $accountService->checkBalance($orderDetails->customer_id, $orderDetails->amount);
if($account == false) {
//……
}
//产品接口操作
$busiductService = new BusiductService();
$busiduct = $busiductService->getBusiduct($order->busiduct_id);
$productOrder = OrderFactory::createOrderInstance($busiduct->product_code);
$productOrder->service($orderDetails->orderduct_name, $orderDetails->action);
//更新订单状态--已操作
$this->updateStatus($id, BusinessOrder::STATUS_SERVICED);
//扣款操作
$financeTypeService = new FinanceTypeService();
$form = new FundsDetailForm();
$form->customer_id = $orderDetails->customer_id;
$form->amount = $orderDetails->amount;
$form->finance_type_id = $financeTypeService->getTypeByBusiness($orderDetails->busiduct_id, $orderDetails->action);
$form->cheque_number = $orderDetails->id;
$form->effective_date = new CDbExpression('now()');
$form->note = $orderDetails->orderduct_name;
if(false == $accountService->deduct($form)) {
//……
}
//更新订单状态-已支付
$this->updateStatus($id, BusinessOrder::STATUS_PAID);
//更新产品数据信息
$context = $this->getContext($orderDetails);
$productOrder->complete($orderDetails->orderduct_name, $context);
//更新订单状态--已入库
$this->updateStatus($id, BusinessOrder::STATUS_STORED);
//更新订单状态--已完成
$this->updateStatus($id, BusinessOrder::STATUS_FINISHED);
事务脚本优势在于简单,但对于复杂业务则冗余代码,并且复用性可扩展性很低。对于复杂的业务必须使用领域模型来替代。实际表现的代码应该如下:
//检查余额
$account = new Account($orderDetails->customer_id);
if(false == $account->checkBalence($orderDetails->amount)) {
//……
}
//产品接口操作
$busiduct = new Busiduct($order->busiduct_id);
$busiduct->service($order);
//扣款操作
if(false == $account->deduct($orderDetails)) {
//……
}
//更新产品数据信息
$busiduct->complete($order);
这中表现形式很直观,便于阅读,并且少了很多updateStatus操作。其实这些updateStatus操作是封装于service、complete等接口中。
这里只是一个简单的例子,实际设计过程中,领域网往往相对比较复杂。领域模型需要一些面向对象技术,以及对领域逻辑相对比较清晰,并且要利用一些架构模式或设计模式。
领域模式如果设计不好则会导致对象过于臃肿,并且降低程序的响应速度。
注:
事务脚本:将所有逻辑组织成单个过程,在过程中直接调用数据库,或者只通过简单的数据库封装器。
领域模型:创建了一张由互联对象组成的网,其中的每一个对象都代表某个有意义的个体(实际对象)。
Chatterley
2010年09月10日
默认分类
过程狂热
过程狂热曾在上课时被计算机教师批评,因为这种方法没有使用更加抽象的实现方式。而支持PHP面向过程者的观点“它可以工作!”并不能提高其编程水平和档次。毕业后他们可能找到一个工作,写驱动程序,文件系统或其它的偏向底层的编程,他们的注意力集中于速度和代码的精炼。
“过程狂热”极端的例子是抵制对象,抵制抽象化。他们总在想着如何让程序运行起来更快,而不在乎别人是否能读懂他们的代码。他们常常把编程当成竞赛而不是团队活动。除了PHP外,他们最喜爱的编程语言是C和汇编。在PHP世界中他们可能会开发PECL模块,贡献出高效率的代码。
对象狂热
对象狂热者热衷于在任何时候使用PHP面向对象的风格来书写代码。他们没有真正考虑过用这种方式是否会影响程序的执行效率。有时候让人觉得他们更享受抽象的设计概念而不是现实的代码。他们通常很可能是项目管理者或文档书写者。
对象狂热者指出,如果没有抽象的设计方法我们仍然在使用0和1进行编程。他们喜欢用伪码来描述问题。极端的例子是对象狂热者即使知道有时候会牺牲效率仍然使用对象。除了PHP,他们最喜欢的语言是Java和Smalltalk。在PHP世界中,他们可能会开发PEAR模块,贡献文档化非常好,易于维护的代码。
Chatterley
2010年09月09日
默认分类
ESQL/C is an SQL application programming interface (API) that enables you to embed Structured Query Language (SQL) statements directly into a C program. The ESQL/C preprocessor, which the esql command calls, converts each SQL statement and all Informix-specific code to C.
To access a database server through an ESQL/C application
1. Write embedded SQL statements and calls to ESQL/C library functions into your C code to create an ESQL/C program.
2. Convert the ESQL/C program to a C executable file with the esql command.
Compiling an ESQL/C Program: You type the esql command to compile your ESQL/C program. The esql command passes your ESQL/C source file to the ESQL/C preprocessor and to the C compiler. It passes along options that are specific to both the ESQL/C preprocessor and the C compiler to preprocess, compile, and link your ESQL/Cprogram.
The esql command follows these steps to carry out the conversion:
* In Stage 1, the ESQL/C preprocessor performs the following steps:
o Incorporates header files into the source file when it processes all include directives ($include and EXEC SQL include statements)
o Creates or removes compile-time definitions when it processes all define ($define and EXEC SQL define) and undef ($undef and EXEC SQL undef) directives
o In Stage 2, the ESQL/C preprocessor processes any conditional compilation directives (ifdef, ifndef, else, elif, endif) and translates embedded SQL statements to ESQL/C function calls and special data structures.
Stages 1 and 2 mirror the preprocessor and compiler stages of the C compiler. Successful completion of the preprocessing step yields a C source file (.c extension).
Default Compilation Order
ESQL/C source program -> ESQL/C preprocessor -> C source program with SQL statements and ESQL/C calls -> C language preprocessor and compiler -> Executable program
Chatterley
2010年07月06日
架构
Lighttpd和Nginx都属于轻量级的Web服务器,它们的出现自然会抢占一些属于Apache的市场份额。不过 Lighttpd、Nginx和Apache并不是相互排斥,相互对立的。Lighttpd和Nginx的长处在于处理静态页面,它们的处理速度可以达到 Apache的2~3倍,极端情况下能达到10倍。因此通常情况下,Apache用来作为后台服务器,处理PHP、CGI等,生成动态内容;Nginx用来作为前端服务器,从而充分利用它占用资源少的优势来处理静态页面的大量请求,而Lighttpd则通常用于图片服务器。
Chatterley
2010年05月31日
默认分类
对于使用mysql-connector-net来连接mysql的asp.net应用程序,如果抛出System.Collections.Generic.KeyNotFoundException异常,则在连接字符串中不使用Charset设置.
.net使用unicode对于utf8或gbk,取出的内容是正常的.
Chatterley
2010年05月27日
默认分类
function get_unsigned_value($var)
{
list(,$var_unsigned)=unpack("L",pack("L",$var));
return floatval(sprintf("%u",$var_unsigned));
}
//example, echo 4294967295
$val = -1;
echo get_unsigned_value($val);
Chatterley
2010年05月19日
软件人生
When building transactionally protected applications, there are some special issues that must be considered. The most important one is that if any thread of control exits for any reason while holding Berkeley DB resources, recovery must be performed to do the following:
* Recover the Berkeley DB resources.
* Release any locks or mutexes that may have been held to avoid starvation as the remaining threads of control convoy behind the failed thread's locks.
* Clean up any partially completed operations that may have left a database in an inconsistent or corrupted state.
Complicating this problem is the fact that the Berkeley DB library itself cannot determine whether recovery is required; the application itself must make that decision. A further complication is that recovery must be single-threaded; that is, one thread of control or process must perform recovery before any other thread of control or processes attempts to create or join the Berkeley DB environment.
There are two approaches to handling this problem:
The hard way:
An application can track its own state carefully enough that it knows when recovery needs to be performed. Specifically, the rule to use is that recovery must be performed before using a Berkeley DB environment any time the threads of control previously using the Berkeley DB environment did not shut the environment down cleanly before exiting the environment for any reason (including application or system failure).
Requirements for shutting down the environment cleanly differ, depending on the type of environment created. If the environment is public and persistent (that is, the DB_PRIVATE flag was not specified to the DB_ENV->open function), recovery must be performed if any transaction was not committed or aborted, or DB_ENV->close function was not called for any open DB_ENV handle.
If the environment is private and temporary (that is, the DB_PRIVATE flag was specified to the DB_ENV->open function), recovery must be performed if any transaction was not committed or aborted, or DB_ENV->close function was not called for any open DB_ENV handle. In addition, at least one transaction checkpoint must be performed after all existing transactions have been committed or aborted.
The easy way:
It greatly simplifies matters that recovery may be performed regardless of whether recovery strictly needs to be performed; that is, it is not an error to run recovery on a database for which no recovery is necessary. Because of this fact, it is almost invariably simpler to ignore the previous rules about shutting an application down cleanly, and simply run recovery each time a thread of control accessing a database environment fails for any reason, as well as before accessing any database environment after system reboot.
There are two common ways to build transactionally protected Berkeley DB applications. The most common way is as a single, usually multithreaded, process. This architecture is simplest because it requires no monitoring of other threads of control. When the application starts, it opens and potentially creates the environment, runs recovery (whether it was needed or not), and then opens its databases. From then on, the application can create new threads of control as it chooses. All threads of control share the open Berkeley DB DB_ENV and DB handles. In this model, databases are rarely opened or closed when more than a single thread of control is running; that is, they are opened when only a single thread is running, and closed after all threads but one have exited. The last thread of control to exit closes the databases and the environment.
An alternative way to build Berkeley DB applications is as a set of cooperating processes, which may or may not be multithreaded. This architecture is more complicated.
First, this architecture requires that the order in which threads of control are created and subsequently access the Berkeley DB environment be controlled because recovery must be single-threaded. The first thread of control to access the environment must run recovery, and no other thread should attempt to access the environment until recovery is complete. (Note that this ordering requirement does not apply to environment creation without recovery. If multiple threads attempt to create a Berkeley DB environment, only one will perform the creation and the others will join the already existing environment.)
Second, this architecture requires that threads of control be monitored. If any thread of control that owns Berkeley DB resources exits without first cleanly discarding those resources, recovery is usually necessary. Before running recovery, all threads using the Berkeley DB environment must relinquish all of their Berkeley DB resources (it does not matter if they do so gracefully or because they are forced to exit). Then, recovery can be run and the threads of control continued or restarted.
We have found that the safest way to structure groups of cooperating processes is to first create a single process (often a shell script) that opens/creates the Berkeley DB environment and runs recovery, and that then creates the processes or threads that will actually perform work. The initial thread has no further responsibilities other than to monitor the threads of control it has created, to ensure that none of them unexpectedly exits. If one exits, the initial process then forces all of the threads of control using the Berkeley DB environment to exit, runs recovery, and restarts the working threads of control.
If it is not practical to have a single parent for the processes sharing a Berkeley DB environment, each process sharing the environment should log their connection to and exit from the environment in a way that allows a monitoring process to detect if a thread of control might have acquired Berkeley DB resources and never released them. In this model, an initial "watcher" process opens/creates the Berkeley DB environment and runs recovery, and then creates a sentinel file. Any other process wanting to use the Berkeley DB environment checks for the sentinel file; if the sentinel file exists, the other process registers its process ID with the watcher and joins the database environment. When the other process finishes with the environment, it unregisters its process ID with the water. The watcher periodically checks to ensure that no process has failed while using the environment. If a process does fail while using the environment, the watcher removes the sentinel file, kills all processes currently using the environment, runs recovery, and re-creates the sentinel file.
Obviously, it is important that the monitoring process in either case be as simple and well-tested as possible because there is no recourse if it fails.
Chatterley
2010年01月13日
默认分类
如果谷歌走了,对IT界绝对是地震,绝对不亚于汶川地震的效果。中国的IT界发展将变慢,经济发展将变慢。
如果我也可以去国外,我也想出去看看了,因为我们是井底之蛙……
不知道清腐败的时候是不是和现在一样……
Chatterley
2009年12月28日
未分类
下载地址:main.cpp
修改扩展名为cpp。
前提:修改main.cpp里面的main方法
char image[30] = "image1.jpg"; //你要添加水印图片
char waterImage[30] = "wm1.png";//你的水印图
在linux下执行
>g++ -o main main.cpp -lgd -ljpeg
>./main
C
Chatterley
2009年12月25日
默认分类
致群主,媒体的力量:
1,群主才下飞机,记者问:你对三陪小姐有何看法?群主很吃惊:北京也有三陪小姐?记者第二天登报《群主飞抵北京,开口便问有无三陪》
2,记者问群主:你对三陪问题有何看法?群主:不感兴趣!记者第二天登报《群主夜间娱乐要求高,本地三陪小姐遭冷遇》
3,记者问群主,你对三陪小姐没有看法?群主很生气:什么三陪四陪五陪的?不知道!记者第二天登报《三陪已难满足群主,四陪五陪方能过瘾》
4,记者后来再问群主,群主不发言。记者第二天登报《面对三陪问题,群主无言以对》
5,群主大怒,对记者说,这么乱写,我去法院告你!记者第二天登报《群主一怒为三陪》
6,群主气急之下,将记者告到法庭。媒体争相报道《法庭将审理群主三陪小姐案》,群主看后撞墙而死。
7,群主撞墙而死后,媒体补充报道《为了三陪而殉情:群主这一生》
无意从网上看到此文,深表感概~这个社会已经不那么真实了。这个社会,要知道如果通过表面看本质。一切表面都并非如此。
Chatterley
2009年12月19日
默认分类
台湾发生6.4级地震。
6.4级 2009/12/19 21:02:17左右 北纬23.763 东经121.689 深度44.6km TAIWAN
厦门普遍有震感。
地震
Chatterley
2009年12月07日
软件人生
所谓64bit的应该程序,所有的栈数据还是保持原本的32bit的形式,例如int,long等。只有指针或对象等堆数据扩展为64bit的形式。这样对于同样的程序只要注意堆数据的处理,使其容易根据平台(32bit 或 64bit)达到更好的移植。
备注:64bit应用程序具有更好的性能,因为32bit只限4G内存,而64bit可以达到8T内存。可以把很多的东西丢到内存处理,大大提高程序的处理速度。对于64bit的程序,硬盘的存取速度已经不那么重要了(不再是瓶颈)。
Chatterley
2009年11月25日
编程
一篇详细讲述autoconf和automake的好文章。
原文地址:http://www.ibm.com/developerworks/cn/linux/l-makefile/

C/C++
Chatterley
2009年11月24日
信息检索
信息检索是一项基于文档内容的技术,然而计算机自动理解语义在目前还很难实现,这使得一个相对比较严密和完整的信息检索理论框架无法建立,无法直接针对语义去建模和操作,而只能是通过非语义的计算力求尽量地体现文档的语义。在这种情况下,人的先验知识和经验的指导,对信息检索系统便是极为重要的。而事实上,目前为止许多出于人直观性的经验,都是信息检索中提升性能的重要因素。最典型和直观的有诸如文档词频、逆文档数、文档长度、文档词数等因素。
基于语言模型的信息检索技术,相比于许多传统的检索技术来说,具有自身的理论优势。但是它通过对文档字符层面上的概率建模很难获得一个好的文档语义表达模型(特别是对于小文档而言)。于是,人们将一些传统模型中的经验化方法融入到语言模型的框架下来,例如基于词典的查询扩展、相关反馈、先验平滑等技术,其目的都是为了更好的表达文档的语义。因此,在信息检索中,更“准确”的模型建立并不是靠严格的数学方法在字符层面上估计概率,而是在先验知识和经验的指导下,更好的表达文档的内容,建立一个能尽量表达文档语义的模型。如果说语言模型在其他任务中通常是一个局部的表层概率模型,那它在信息检索中则是一个全局表达文档语义的概率模型。全局性和语义表达性应是信息检索中语言建模须把握的两大要素。
摘自:信息检索中基于MLS的语言模型准确性分析
统计学