2006/11 30
上一篇BLOG以及这一篇都是使用Performancing来发布的,感觉很不错。比FLOCK上的功能要强多了。wordpress上几乎所有的功能都可以使用到,比如Category选取,发布为草稿,也支持编辑以前发布的文章。
功能非常棒。赶快下载使用吧:
Firefox的Performancing插件下载地址
Defined tags for this entry: , ,

Posted by rollenc

Not modified
2006/11 30
来源:http://www.developer.com/lang/php/article.php/10941_3604111_1
Part1:
PHP 5 made significant improvements on the Object Orientated programming model of PHP 4 bringing it more in line with languages such as Visual Basic .NET and Java. The improved object model in PHP 5 makes developing applications using OOP much easier and gives you the programmer, greater flexibility.

In this series of articles I will demonstrate the new features of the PHP 5 object and show you how to create a database abstraction layer similar to PEAR DB. I will also introduce you to a few design patterns that can be applied to common OOP related problems.

In this article, I introduce you to some of the features of the PHP 5 object model. You will see how to create a database abstraction layer similar to the Pear DB abstraction layer. You'll also learn how to adapt this abstraction layer for your own uses.

Introduction


One of PHP's stronger areas is its support for database connectivity. It is able to connect to and talk to just about any database server or interface you can imagine. However, with this comes a few inherent problems; each database system has its own features, functions and in most cases they have their own versions of SQL. Although the functions used to access these databases are similar they do vary subtly meaning that if you were to want to port an application written for MySql to MS SQL server, the refactoring would require manually changing all calls to mysql_query() to mssql_query().

While we are not going to go as far as developing a database independent version of SQL, the new features of PHP 5 will be us build a consistent database API with support for stored procedures (where it is not already present). This will then make switching from one database system to another as painless as changing one line of code.



Interfaces Abstract Classes and the Adapter Pattern


The first features new to PHP 5 to be covered in this article are abstract classes and interfaces. These concepts are nothing more than features added to OOP, which help the programmer follow good coding standards.



Abstract Classes


An abstract class is a class that is only partially implemented by the programmer. It may contain one or more abstract methods. An abstract method is simply a function definition that serves to tell the programmer that the method must be implemented in a child class.



To create an abstract class we use the code shown in Listing 1:


Listing 1: An Abstract PHP class



abstract class Weapon
{
private $SerialNumber;
abstract public function fire();
public function __construct($SerialNumber)
{
$this->SerialNumber = $SerialNumber;
}
public function getSerialNumber()
{
return $this->SerialNumber;
}
}
?>

The abstract class in Listing 1 contains some of the methods required for a weapon. The fire() method however, cannot be implemented because each different weapons use different firing different mechanisms. The method is therefore declared as abstract, meaning it will be implemented in a more specific child class.


Because the class is abstract, an instance of it can never be created (remember, it is only a partial implementation). Instead a child class must be created using inheritance and implement the fire method in itself. Failure to do so will result in a fatal error. Listing 2 shows a child class being created from the Abstract Weapon class.


Listing 2: Extending the Abstract Weapons class



class Gun extends Weapon
{
public function fire()
{
if($this->SafetyOff) {
return $this->CurrentBullet;
}
}
}

class Cannon extends Weapon
{
public function fire()
{
$this->NeedsLoading = true;
return $this->CurrentCanon;
}
?>


An instance of the Cannon and Gun classes can now be created because they now fully implemented subclasses of weapon.


Interfaces


An interface is similar to an abstract class; indeed interfaces occupy the same namespace as classes and abstract classes. For that reason, you cannot define an interface with the same name as a class. An interface is a fully abstract class; none of its methods are implemented and instead of a class sub-classing from it, it is said to implement that interface.


An interface will be used in the database abstraction layer you create. This ensures that every time you create a class for a particular database, the same API is exposed. When using an interface, you can then rely on the methods defined for the interface to be part of the class because, if they are not, PHP will not parse it.


The MySql functions will be used as an example because they are the most commonly used amongst PHP programmers. The most commonly used functions are:


  • mysql_connect()
  • mysql_error()
  • mysql_errno()
  • mysql_query()
  • mysql_fetch_array()
  • mysql_fetch_row()
  • mysql_fetch_assoc()
  • mysql_fetch_object()
  • mysql_num_rows()
  • mysql_close()

If all the database class APIs you create can expose the same methods with the same return types then you can be sure that changing from one database to another, such as from MySql to Postgre SQL, will be painless. As such, the interface in listing 3 can be determined for your API.

Listing 3: An Abstracted Database Interface



interface DB
{
public function connect();
public function error();
public function errno();
public static function escape_string($string);
public function query($query);
public function fetch_array($result);
public function fetch_row($result);
public function fetch_assoc($result);
public function fetch_object($result);
public function num_rows($result);
public function close();
}

Any class implementing the interface must define each method that is declared in the interface, and each method must have at least the parameters identified in their interface definitions. It may have more parameters as long as they are optional, but it cannot have less.

Part2

Look at a class in Listing 4 that implements the database interface. You should recall that I mentioned the adapter pattern earlier. This is an example of the adapter pattern, which is used by programmers in order to adapt one API. The API you are adapting from could be another object-based API or as being done here, an adaptation from a modular API. If you want to read more about the adapter pattern, you can find a more detailed explanation and examples here.

Notice how the escape_string() method is included as a static method. This method does not require an active connection to a database and should not require and instance of any object which implements the DB interface. In my opinion, this is the single most important method of any database implementation; a poorly implemented escape string method could make your applications vulnerable SQL injection.


Listing 4: Implementing the database interface



class MySqlDB implements DB
{
private $link;

public function connect($server='', $username='', $password='', $new_link=true, $client_flags=0)
{
$this->link = mysql_connect($server, $username, $password, $new_link, $client_flags);
}

public function errno()
{
return mysql_errno($this->link);
}

public function error()
{
return mysql_error($this->link);
}

public static function escape_string($string)
{
return mysql_real_escape_string($string);
}

public function query($query)
{
return mysql_query($query, $this->link);
}

public function fetch_array($result, $array_type = MYSQL_BOTH)
{
return mysql_fetch_array($result, $array_type);
}

public function fetch_row($result)
{
return mysql_fetch_row($result);
}

public function fetch_assoc($result)
{
return mysql_fetch_assoc($result);
}

public function fetch_object($result)
{
return mysql_fetch_object($result);
}

public function num_rows($result)
{
return mysql_num_rows($result);
}

public function close()
{
return mysql_close($this->link);
}
}
?>


You'll notice that there are many more mysql functions than methods that are adapted in the interface in listing 3. However, this small subset of functions is sufficient to meet the needs of most applications requiring trivial data storage and retrieval. The additional functions can be implemented and I have done this in the attached example file, you may also choose to add additional functionality to the class and the interface.


Listing 5: Creating a database class



$db = new MySqlDb;
$db->connect('host', 'username', 'password');
$db->query('use users'); // we could also use $db->select_db here but it is not consistent with the interface

$result = $db->query("SELECT username FROM users");

while($row = $db->fetch_assoc($reuslt))
{
echo($row['username']);
}

As shown in listing 5, you can now create a class for each database you want and as long as it implements the DB interface, switching from one to another is as easy as changing one line of code:



$db = new MsSqlDb;

Conclusion


In this first article, you've seen how to create an abstraction layer to access a database. Using this, you saw how creating an interface helps you to isolate your application so that you can easily switch from one database to anther without rewriting your own applications.


Downloads


About the Author


Adam Delves is a university student and web programmer from the UK who is studying computing. He has been a PHP programmer for over 3 years and now runs two small websites and writes articles for PHP builder.com.

rollenc总结


将本文标题相对应,MySqlDb实现了DB接口(interface),也对mysql_*函数进行了适配(Adapter)(我就很喜欢进行这种适配,php中有很多带‘_’字符的函数(这也被PHP反对者们发现,并抨击PHP的一大有力证据),与我喜欢的骆驼编程风格很不协调,所以,为了隐藏它们,我常常进行适配)。
抽象类只在weapon上出现到了,为了增加代码的灵活性,建议使用接口,而不是继承。(完)
Defined tags for this entry: , ,

Posted by rollenc

Last modified on 2007-01-13 10:56
2006/11 28
终于把DB这一个模块整理出来了,简单的分析一下几个类之间的关系以及其中的设计模式:
类图如下:

sugar DB类图


顺序图如下:
DB 顺序图

从类的模式及其构建一个DBManager的流程来看,这使用了单例模式,而其中是创建哪一个类,则使用桥梁模式来封装。但是在代码中我还看到了一些地方直接使用了DBManager::getInstance()方法来建造(获取)数据库实例,虽然使用上调用DBManagerFactory::getInstance()和DBManager::getInstance()这两个静态函数并无差别,DBManagerFactory::getInstance只是简单的委托给DBManager::getInstance,但是在顺序图流程上就不好解释了。这打乱了整个设计模式的结构。
当然,如果单单说是从速度上解释的话可以理解,使用DBManager::getInstantce可以减少一次函数调用。但这样混乱了整个设计模式,我觉得这代价是不是大了。
希望有高人指点一二,说说其中我忽略和分析错误了的道理。
Defined tags for this entry: , ,

Posted by rollenc

Not modified
2006/11 28
由于sugarOS考虑了PHP4的兼容性,虽然代码架构中在设计模式上表现不错,但由于缺少很多的面向对象关键字,比如(public,private abstract)等,也缺少一些面向对象的功能,如(interface)等。这在很大程度上影响了代码的可阅读性以及限制了一些设计模式的使用。
比如如下代码段:
[PHP]
class DBManager
{
var $helper;
var $tableName;
var $database = null;
var $dieOnError = false;
var $encode = true;
var $query_time = 0;
var $lastmysqlrow = -1;
var $last_error = '';
var $lastResult = array ();
function DBManager()
{

global $sugar_config;

$my_db_helper = 'MysqlHelper';
if ($sugar_config['dbconfig']['db_type'] == "oci8")
{

}
if ($sugar_config['dbconfig']['db_type'] == "mssql")
{
$my_db_helper = 'MssqlHelper';
}
static $helper;
if (empty ($helper))
{
$helper = new $my_db_helper ();
}
$this->helper = $helper;
}

function & getInstance($instanceName = '')
{
global $sugar_config;
static $count;
static $old_count;
global $dbinstances;

$instanceName = 'db';
$config = $sugar_config['dbconfig'];

if (!isset ($dbinstances))
{
$dbinstances = array ();
}

if (!isset ($dbinstances[$instanceName]))
{

$my_db_manager = 'MysqlManager';
if ($config['db_type'] == "oci8")
{

}
else
if ($config['db_type'] == "mssql")
{
$my_db_manager = 'MssqlManager';
}
if (!empty ($config['db_manager']))
{
$my_db_manager = $config['db_manager'];
}

DBManagerFactory :: load_db_manager_class($my_db_manager);
$dbinstances[$instanceName] = new $my_db_manager ();
$dbinstances[$instanceName]->connect($config, true);
$dbinstances[$instanceName]->count_id = $count;
$dbinstances[$instanceName]->references = 0;
$dbinstances[$instanceName]->helper->db = $dbinstances[$instanceName];

}
else
{
$old_count++;
$dbinstances[$instanceName]->references = $old_count;

}

return $dbinstances[$instanceName];
}
//MORE
}
[/PHP]
DBmanager是一个抽象类,也是一个单例类,故DBmanager类声明应该是abstract class, 构造函数好像不该出现或者是private,getInstance函数也该是static等等,这样,对于设计模式的理解更方便些。
我准备对其重构了,不是为了使用或者速度,仅仅是把代码改一改,使它更象一个面向对象的系统。
当然,一开始改,PHP4支持肯定就挂掉了。
Defined tags for this entry: , , , ,

Posted by rollenc

Not modified
2006/11 26
最近几天一直在研究SugarOS,主要在学习其中设计模式和编程风格等。
其中使用了以下的工具和组件等:

  • Eclipse & PHPEclipse
    我对比了一下DreamWeaver(DW),Zend Studio(ZS),Eclipse & PHPEclipse(E&PE)三种开发工具,厌倦DW的全站搜索功能,各个文件间的关联很松散。ZS强在逐步调试,但好像我并不需要,从大局把握整个系统才是最重要的。另外就是ZS的速度让我的256机子疯掉了。E&PE是最佳的选择,整个系统完整的融合在一起,不需要ctrl+F就可以在相关联的函数,类中跳转。

  • Simple Test
    试着以测试的方式去思考。不过我更希望是测试驱动开发。这样更有趣些。唯一的遗憾是Simple Test for eclipse的插件没有安装好,各个文件间的包含关系处理不正常,看了一下readme文件,有这么一句:

    Future Features
    These are features that should eventually make it into this plugin
    * Allow different "include" file on each runner (override the "master" include)
    * Handle fatal errors better


    所以,只能等待下一个版本出来了。现在先在WEBPAGE里面用Simple Test吧。

  • 重构
    我没有准备去重构这个系统,几天的代码阅读,也没有问到“代码臭味”,但是我会在代码中去理解,重构的目标:设计模式。

  • 设计模式
    这是我一眼看中这个系统并把它作为我的学习对象的原因。先在再看DB部分,对整个的构建模式有了很大的体会。不过,完全理解这个系统的代码对现在的我来说还是有困难的,在复杂的工厂模式中还是会迷路,找不到系统运行的流向。






Defined tags for this entry: , , , ,

Posted by rollenc

Not modified
2006/11 23
SugarCRM,简介如下:
SugarCRM 是在SourceForge.net上最成功的开放源程序系统,其开放源程序的版本是目前为止最有名,也是最成功的免费的 CRM。
SugarCRM 具有很强的可操作性、灵活的适用性、完善的功能、独特的个性化设计和专业的技术安全保障,是辅助企业实现客户关系管理的理想之选。
最主要的是,SugarCRM不仅仅是一种业务操作软件,更是先进的销售管理解决方案,专业的销售培训使你的销售效果倍增,确实提高您的业务水平。它在企业管理人员、销售人员和客户之间建立了一个立体的管理系统,帮助企业对内和对外实现以“客户为中心”的全方位管理。
SugarCRM 正是这样一款优秀的客户关系管理软件!她在总结研究成功企业管理经理基础上,结合现代前沿营销理念,针对小企业的实际需求,实现了对客户和销售的全方位管理。
官方网站:http://www.sugarcrm.com/crm/
下载链接:官方下载地址
SugarCRM OS 4.5D 中文语言包:官方下载地址
注意:SugarCRM版本1.5D的,而语言包是4.5F的。我不知道有什么大的区别,我成功安装了,但是会引起什么样的BUG暂时无法得知。E文好又要求稳定的请行不要急于安装中文包。静等F版的放出。

我简单的看了一下SugarCRM的代码,敢肯定,这一系统将成为影响我的最深的一个PHP系统之一。
准备学习中。。。
Defined tags for this entry:

Posted by rollenc

Not modified
2006/11 21
从最近的一些运转情况来看,团队人员之间的协作遇到大麻烦了。
具体事宜属于商业机密,写在私人文档中。不外泄。
Defined tags for this entry: ,

Posted by rollenc

Not modified
2006/11 20
以前建了几个QQ群,疏于打理宣传,终于一个个倒闭关门了,现在剩下好几个空的群,里面就两人,一个是自己,另一个也是自己,小号。
最近的群是高中的同学群,由于另一个同样的群的崛起,竞争不过,倒了了之。免得寂寞。
Defined tags for this entry:

Posted by rollenc

Not modified
2006/11 20
几经周折,Ubuntu 6.10终于安装上了。说是升级,但是写为修复更合适。一下是一些操作,我没有再次去验证这些操作里面哪些是有用的,如果有哪位朋友想我一样倒霉的可以反过来拣几个步骤试一下。
起因:想使用firefox2.0
1、修改了源,deb http://ubuntu.cn99.com/ubuntu/ dapper main restricted universe multiverse为edgy,更新找到firefox2.0,升级。
结果:firefox升级成功,但是不能打开https协议链接。
不爽。接下来继续:
2、升级gtk和gnome相关的一些东西。
结果:gnome挂了,起动不了。还好有KDE。
3、用了几天KDE,继续不爽,想恢复,但是自动更新回老版本是不行的。选择强制版本安装,但是没有选择全,相反强制安装导致系统卸载掉很多的依赖元件包。
结果:系统全部崩掉。只有终端界面。
4、准备重新使用光盘安装,但恨不下心,毕竟还有些数据在磁盘上,虽然可以从WINDOWS系统提取出来,但不爽。重装也还补是我的最后选择。破罐子破摔。把源全部改成edgy,更新。
结果:不成。继续停留在终端,起动不了图形界面。
5、继续摔:删掉个人文件夹里的一些配置文件,主要是GNOME的,下载安装ubuntu-desktop,完整的安装一遍。反正网速快,250K的速度。15分钟之后,重启。
结果:搞定,进入UBUNTU。
6、遗留问题:很多软件包被卸载掉,以及遗留老版本。系统也提示需要版本升级,升之,安装上以前被卸掉的软件包。
结果:完全正常,以前在UBUNTU 6.06下面的fctix和firefox2不能使用的情况也没有了(完全个人软件安装冲突)。
Defined tags for this entry: ,

Posted by rollenc

Last modified on 2007-01-29 07:51
2006/11 20
很久没写过读后感了,估计上一次还是小学时代看电影时。也就因为这个,特讨厌学校放电影。
这不是读后感,因为我现在还在慢慢的读。有点惊讶,有点昏头,也有点。。。什么感觉都有,想骂人的感觉都有。
我很佩服阎宏了,再一本程序员阅读的书里面可以写这么多的哲学,古文,和一些其他的知识。第一章就看的我昏,从形而上学──我一直没弄明白第一次说这个词的人是不是中国人──开始论,涉及
1、道家观点:无名大地之始,有名万物之母──老子云
2、量子物理中波和粒子我一个理科本科差生看不懂的东西云云
3、马王堆出土道德经贴图
4、成玄英(601~690)之《庄子疏》:气聚而有其形,气散而归于无形也。
5、建筑风水学:气乘风则散,界水则止;
等等云云。。
后面不少西游记例子,唐僧和徒弟的一对多的关系,徒弟是抽象类,悟空,八戒是徒弟的继承;孙大圣的身外身法术。还有鲁智深为什么是和尚的道理。
昏昏头。我已经对阎宏佩服的五体投地了,简直想把往上留传的那段赞扬楼主发帖的回帖记下来,背给阎宏大哥听。
说回来,这本书也是我看到的最浅显易懂的涉及模式的书了。哲学古文相关的东西不解,但程序部分还是很容易理解的。
谢谢阎宏老师了,在教我程序的同时,也让我补回了一点小学初中高中大学里面一直没学习好的中国古代文化和哲学。

附记:
哲学:比这句话“你是人,会制作和使用劳动工具的人”的回答更没用的知识。 (摘自:rollenc无知词典)
Defined tags for this entry: , ,

Posted by rollenc

Not modified
2006/11 18
网站的改版终于告一段落。从程序角度来讲,说是重构更为合适。
针对这次重构,不管结果是什么,从一个项目的角度来讲,这次重构是失败的。时间长,效果也并非优美。主要从自己,以及项目与中自己工作相关度较多的内容进行一下总结:
1、个人请假。因为外婆病故,回家了一个星期,项目开发的文档等都没有写过。此期间也几乎没有成员可以接受我手中的JS编程工作。这使得整个项目延时了一周。
2、公司成员离开。本来团队成员人手缺少,一个人员的离开,给项目增加了更大的负担。以往的文档,编程规范,以及公用代码库都没有建立和统一。因此,在重构的同时,我们需要去阅读,修改,实现一部分的陌生代码。有部分功能我们考虑了完全的重写。
3、新技术痴迷。在这次重构上,我完整的引用了JS的JSON结构,这种实现固然给程序运行速度,兼容性和扩展性带来了实质性的转变,但是,学习的成本也给项目的前期进展带来了很大的损失。
4、新技术暴露的缺陷。JSON代码的运行时错误有时不能被调试工具捕获,因此,增加了其测试时间。
5、对实现目标的不赞同。在部分实现效果上,不同意其实现结果,而且,经过长时间的商讨也未能被说服。但是,只能在“设计师”和“用户”的要求指引下,强制接纳这一意见,但在具体编码实施阶段有厌烦和抵制情绪,并为自己希望的模式作了可扩展和移植接口。造成过度开发,不必要的时间浪费。
6、缺少激励。项目已经稳定运行一段时间了,但是,在投资等方面还没有是指性的进展,致使自己对产品产生怀疑心态,自己是否能够长期靠这个项目生存。毕竟,JS不是我所期待的职业语言,PHP才是。长期工作于JS,可能导致职业进程的白白延迟。因此,业余投入了很多精力学习“设计模式”等关于系统架构的相关知识。这些在短期内是不能很成熟的应用到当前项目开发中来的。

从这次项目的开发来讲,我必须道歉和反省。情绪影响是最迫切需要纠正的,以及留一手的过度开发,代码管理,新技术的狂热等,也需要在项目中留意。
Defined tags for this entry:

Posted by rollenc

Not modified
2006/11 16
忙着学习,把生活的记录给荒废了。
Blog有很长一段时间没有好好的更新了,写的文章大多不痛不痒的。没什么意思。相反的,每天在Wiki上要泡较长一段时间,当然,也包括Wikipedia.org。不断的注入到新的只是以充实自己,乐此不疲。自己也坚定了自己的职业发展目标,Wiki上对系统架构师的描述太狠了点,看着有点象自己的终身目标了。不过80后有80后自身的好处,对自己的崇拜,可以完全的造就自己的自信和成长。
学习着,快乐着。请被遗忘的人和事给予我谅解。
我首先原谅了自己,忘我,不惧,不怕。
Defined tags for this entry: ,

Posted by rollenc

Last modified on 2007-04-24 04:03
2006/11 12
这一节基本学习完毕,标记一下。
详细信息请查阅本站WIKI。
抽象工厂模式
Defined tags for this entry: , ,

Posted by rollenc

Not modified
2006/11 12
现在已经对哪种语言最好这个问题产生疲惫了,没有意义的问题,任何回答也感觉没有意义。只有执著的偏执者才固守一种语言技术。
最近学习设计模式,几本书混着看,几种语言也一起往脑子里输。C,C++,JAVA,PASAL,SMALLTALK,PHP。类C的语言还好懂,加之以前简单的学过一些C++,C#的入门知识,关键字可以看懂。看示例代码,比看英文要快的多。几乎没有语言障碍。非类C的语言也在上下文中可以体会到它的大概意思。
自己使用的一般是PHP,所以,有时也试图将这一些语言“翻译”成PHP,然后使用之。
我想起了儿时的一个寓言:一个学箭之人,箭术很高超,后来跟一个老头学射,从有箭之射,到无箭之射,再到无弓之射。最终的结果,他已经不知道,弓为何事,箭又为何物。
编程语言?概念模糊了。就像日常说话,自然。
Defined tags for this entry:

Posted by rollenc

Not modified
2006/11 10
这个星期咖啡的消耗比较快,今天中午眯了半个小时,没睡着。起来冲杯咖啡下肚。90分钟后,脑子顶不住了,思维长时间处于停止状态。同事一句话过来,我需要3秒钟的反应时间。而且,5秒钟之后立刻忘掉我听到了一句什么话。
精神状态已经撑不住了。咖啡只是一种让我在一小时后可以完全睡着的饮料。
明天还要熬过一天,周六睡觉。
只希望,不要让我再作恶梦,不要让我在半夜惊醒。
Defined tags for this entry: ,

Posted by rollenc

Not modified

(Page 1 of 2, totaling 20 entries)