一、面向对象的PHP代码设计
1、面向过程的代码
在网站中,文章是最基本的功能,假设我们要显示一篇文章的标题,我们可能会编写下面的代码:
例:1_1
<?php
$sql = '这里仅仅作说明,大家可以回想自己写过的sql语句';
//假设前面已经连接上数据库了
$result = mysql_query($sql);
if (mysql_num_rows($result)>0) {
$record = mysql_fetch_assoc($result);
}
//假设标题放在title字段
$title = $record['title'];
//假设创建时间放在create_time字段
$create_time = $record['create_time'];
?>
如果仅仅从目前的需求来看,这样的代码就足够了,但是如果页面上需要涉及多个文章的信息呢?
比如最新的某篇文章,浏览最多的文章,专家推荐的文章,评分最高的文章等等,他们都有标题和创建时间。
如何解决?也许你会说用数组。对,这是一个解决方案,我们可以用数组存储:
例:1_2
<?php
$sql = '这里仅仅作说明,大家可以回想自己写过的sql语句';
//假设前面已经连接上数据库了
$result = mysql_query($sql);
if (mysql_num_rows($result)>0) {
$record = mysql_fetch_assoc($result);
}
//假设标题放在title字段,创建时间放在create_time字段
$article = array('title'=>$record['title'], 'create_time'=>$record['create_time']);
?>
我们需要的不光是数据,还需要一些功能性的函数,比如某篇文章哪些专家推荐了,那么这可以定义一个函数:
例:1_3
<?php
function article_expertCommend_getExpertsName()
{
return '专家的名字';
}
?>
注意这里的函数名,为何那么长,因为防止别的地方定义了同样的名字,所以把相关的功能的含义全部写上去。
其实我们最直接的功能是'getExpertsName',可是担心别的地方也出现获取专家名字的函数,所以用了很长的函数名。
似乎问题都解决了,但是我们是否能将数据的存储变的更加直观?函数名可以更简洁?
这时候我们可以用面向对象的方式来提供新的解决方案
2、比函数更丰富的封装
函数封装的是功能代码,而用类可以将函数和数据都封装在一起。
例:1_4
<?php
class Article_expertCommend
{
//标题
public $title;
//创建时间
public $create_time;
//获取专家的名字
public function getExpertsName()
{
return '专家的名字';
}
}
不但如此,我们还可以将多个相关函数放入一个类,便于代码管理,这里就不举例子了。
3、保存数据的新方法
我们可以使得一些数据不被修改,无论是失误或者故意,因为类提供了访问控制.
下面就利用private,使得只有类里面的函数才能修改这些对象的成员:
例:1_5
<?php
class Article_expertCommend
{
//标题
private $title;
//创建时间
private $create_time;
//获取文章的信息
public function getArticle()
{
$this->title = '只能这个函数修改标题';
$this->create_time = '只能这个函数修改创建时间';
}
//获取专家的名字
public function getExpertsName()
{
return '专家的名字';
}
}
?>
其实专家推荐的文章也是一种文章,我们可以做更加疯狂的事情,把文章作为一个类,然后把文章对象作为数据保存:
例:1_6
<?php
class Article
{
//标题
private $title;
//创建时间
private $create_time;
}
class Article_expertCommend
{
//整个文章那个对象
private $article;
//构造函数,获取文章的信息
public function __construct()
{
$this->article = new Article();
}
//获取专家的名字
public function getExpertsName()
{
return '专家的名字';
}
}
?>
4、代码重用的新含义
假设文章类有个函数显示网友评论,但是专家推荐的文章只显示专家的评论,而且专家推荐的文章有一些特殊的数据要临时保存,比如推荐的专家数量。
这样文章类的很多代码,希望被专家推荐的文章,但是有些代码要修改,特别是函数,是否像以前一样复制代码?
可以使用类的继承:
例:1_7
<?php
class Article
{
//标题
private $title;
//创建时间
private $create_time;
//获取评论
public function getComment()
{
return '网友的评论';
}
//获取浏览的次数
public function getViewTimes()
{
return '浏览的次数';
}
}
class Article_expertCommend extends Article
{
//获取评论
public function getComment()
{
return '专家的评论';
}
}
?>
这样就用到了数据标题和创建时间,同时用到了获取浏览的次数的函数,但是又修改了获取评论的函数。不用复制代码后修改吧!
5、牵一发不动全身
例1_6已经显示了这点,如果我们需要在文章对象中添加属性,并不影响调用它的专家推荐类。
同样例1_7也显示了,由于类继承取代了代码的复制粘贴,所以评论函数和浏览函数的修改,只需要修改一两个地方,而不是到处修改。
6、更大的舞台
类和对象不仅仅可以用上面的方式来解决很多问题,还可以衍生出各种有趣的解决方案,比如设计模式。
设计模式是比一般的类的设计更抽象的思想,往往涉及到多个类的定义和使用。
这些模式是无数的开发者在使用面向对象的过程中创造的方法,而且每个模式还有一些变种(也叫策略,变形等),以适应问题的变化。
这个系列的接下来的部分就将讨论比较经典和常用的设计模式,它们要针对的问题,如何解决方案,以及进一步的探讨。
说明:文章相关代码在phper杂志下载包中