作者gpmm (银色)
看板PHP
标题[心得] 浅聊物件导向在 PHP 中的观念和应用 # 1
时间Sat Jul 30 18:27:58 2011
将文章从原本那篇中抽取出来,是因为这系列浅聊,
是写给所有想尝试将物件导向概念应用在自己程式里的板友,
这些文章当中所提及的程式码只是单纯一个入门阶,重点还是观念,
有兴趣的板友可以在自己的程式或专案里来思考或应用这些观念
如果文章里有任何观念上的谬误或需要补充的地方,
也请板友们不吝指教。感谢。
--
在小弟的经验里,很多 phper 对於物件一直感到很疑惑,
物件类别的宣告并不难理解,但应用上却很难想像。
其实物件比较合适的应用方式会涉及物件导向本身的特性,
但这部份可以晚点说明(太理论性了),我们尽量用简单的例子来谈。
情况:
如果手上有一个案子,其中某个部份是有关资料的显示处理,
资料是可能会由一个结构简单的 DB Table 中取得,
※ id / name
但是最後要输出的可能形式包括:
下拉式选单(select)、列表、单选按钮(radio)三种
在一般性的思考上,我们很可能会建立三个 function:
function output_select ($data)
function output_list ($data)
function output_radio ($data)
三个 function 各自代表了某种输出的实做,
而允许输入的参数是 mysql_fetch_* 所取出的资料集合,
但如果今天突然增加一个限制条件,
name 当中 sexy 为字首的部份显示时必须要滤掉,
并且再增加一个控制条件,
表示当 id 小於 100 的是系统管理者,要在 name 前面加上 admin
那在这个思考点上的延伸很可能是增加第四、五个 function:
function data_remove_sexy ($data)
function data_check_add_admin ($data)
而我们使用上会是:
$data = mysql_fetch_* ($sql);
$data = data_remove_sexy ($data);
$data = data_check_add_admin ($data);
output_select ($data);
注意到哪边很有趣了吗?
yap,这五个 function 实际上在处理的都是同一笔资料 $data,
我们可以思考如何尝试用更结构化的方式来达成这件事。
类别设计的本身具有一个最强大的特性让它成为可以承担物件导向的一切核心,
那就是「物件内部自我资料处理的能力」,
如果仅仅将类别当作一种储存方式来使用那是极为浪费的行为(并不是说不行),
因为这会将物件贬低到跟 array 或 hash table 一样的价值层次里,
也就是储存复数资料的能力。
如果真的 class 在宣告後只是从外部喂给它变数,
那 class 和 hash table 也就只有语法撰写上的差异而已了。
回到类别,如果我们试着把上面这个例子类别化,可以粗略得到以下的程式:
class dataHandler {
var $_data = Array ();
function __construct ($data) {
$this->_data = $data;
$this->data_remove_sexy ();
$this->data_check_add_admin ();
}
function data_remove_sexy () {}
function data_check_add_admin () {}
function output_select () {}
function output_list () {}
function output_radio () {}
}
仔细看过我们可以发现,几乎所有的函式(方法)都不需要额外的参数,
因为它们都已经成为这个类别(物件)的一部分,可以直接使用物件内部的资料。
这个类别在使用上大致可以像以下:
$data = mysql_fetch_* ($sql);
$dh = new dataHandler ($data);
$dh->output_select ();
当然你可能会说,我也可以在每个 output_* 里加上那两个函式来节省重复的部份,
这样使用起来和类别也就差不多了啊?
但是仔细想想,当我们需要扩充更多的前提条件或更多的输出方法时,
function 和 class 哪个处理起来会更容易(包括容易实做与理解)?
除此之外,当你朋友遇到一个相同的需求时,
你可以直接把这个 class 交给他,然後告诉他:
「只需要 new 出物件,并且把 $data 喂进去,中间的它都会帮你处理好。」
这就是物件导向三大特性中 - 封装的一部分含意。
有没有一种很熟悉的感觉?
其实当我们在使用别人已经做好的扩充类别时,也都会享受到封装特性的优点,
也就是类别实际上达成了黑箱化的作业,隐匿去了使用者不需知道的细节,
而我们只要专注在类别本身的操作和使用上即可。
--
夭寿…写东西真的超慢,三大特性只约略提了一个,
看之後有没有空继续 follow 吧…囧
其实真正要体验到 oo 的精髓,一定要试着去理解设计模式,
如果有足够的时间小弟再慢慢聊吧…
--
※ 发信站: 批踢踢实业坊(ptt.cc)
◆ From: 114.45.241.224
※ 编辑: gpmm 来自: 114.45.241.224 (07/30 18:30)
1F:推 kusoayan:好文! 07/30 18:52
2F:推 roga:好文 07/30 22:53
3F:推 LaPass:推这篇.... 我一开始就是学c#那种非常物件化的语法,结果去 07/30 23:41
4F:→ LaPass:学PHP就觉得很卡.... 07/30 23:41
5F:推 bobju:有c的基础,在切入php会比较快. 07/31 10:11
6F:推 m24:yep... 08/02 10:44
7F:推 chc2:对由c转向php的在下而言,这篇文章是不可多得的好物! 08/04 21:43
8F:→ qmo668:推! 10/02 01:47