±¾ÎĵÄ×÷ÕßJohan PerssonÊÇPHPÖÐÖøÃûµÄJpGraphͼ±íÀà¿âµÄ¿ª·¢Õß. ±¾ÎÄÊÇ×÷Õß¶ÔÓÚÔÚPHP4ÖнøÐÐÃæÏò¶ÔÏ󿪷¢Ê±ÐèҪעÒâµÄ¼¸¸öСÎÊÌâµÄ×ܽá.
·Òë: Binzy Wu [Mail: Binzy at JustDN dot COM], ˮƽÓÐÏÞ, »¶Ó̽ÌÖ. 2004-2-4
¼ò½é
±¾ÎĵĶÔÏóÊÇÄÇÐ©ÔøÊ¹Óøü¼Ó³ÉÊìµÄOO [1] ÓïÑÔ, ÈçEiffel, Java, C# [2] or C++(), ½øÐпª·¢µÄÅóÓÑ(ÈçÎÒ×Ô¼º). ÔÚʹÓÃPHP4½øÐÐÍêÈ«µÄOO¿ª·¢Ê±ÓÐ×ÅÐí¶àµÄÓïÒå[3] (semantic)
ÉϵÄÏÝÚå[4].
Ï£±¾ÎÄÄÚÈÝ¿ÉÖúÈ˱ÜÎÒÔø·¸Ö®´í.
ÒýÓÃ VS ¿½±´ÓïÒå
Õâ»ù±¾ÉÏÊÇ´íÎóµÄÖ÷ÒªÀ´Ô´(ÖÁÉÙ¶ÔÓÚÎÒÀ´Ëµ).¼´Ê¹ÔÚPHPµÄÎĵµÖÐÄã¿ÉÒÔ¶Áµ½PHP4½ÏÖ®ÒýÓøü¶àʹÓÿ½±´ÓïÒå(ÈçÆäËûÎÒËùÖªµÄÃæÏò¶ÔÏóÓïÑÔ), µ«ÕâÈÔ½«Ê¹Äã×îºóÔÚһЩϸС֮´¦À§ÈÅ.
½ÓÏÂÀ´µÄÁ½²¿·ÖÓÃÓÚ²ûÊö¶þ¸öСµÄÀý×Ó, ÔÚÕâ¶þ¸öÀý×ÓÖп½±´ÓïÒåÒ²Ðí»áÁîÄ㾪ÑÈ.
Ҫʱ¿ÌÀμÇÖØÒªµÄÊÇÒ»¸öÀàµÄ±äÁ¿²»ÊÇÒ»¸öÖ¸ÏòÀàµÄÖ¸Õë¶øÊÇʵ¼ÊµÄÀà×Ô¼º±¾Éí[5]. ´ó¶àÊýÎÊÌâÒý·¢×Ô¶ÔÓÚ¸³Öµ²Ù×÷·û(=)µÄÎó½â, ¼´ÒÔΪÊǸøÒ»¸ö¶ÔÏóÒ»¸ö±ðÃû, ¶øÊµ¼ÊÉÏÈ´ÊÇÒ»¸öеĿ½±´. ÀýÈç¼ÙÉè$myObjÊÇij¸öÀàµÄʵÀý, ²¢ÇÒËüÓÐÒ»¸öSet()·½·¨. ÄÇôÏÂÃæµÄ´úÂëÒ²Ðí²»»áÏñÒ»¸öC++(»òÕßJava)³ÌÐòÔ±ËùÆÚÍûµÄÄÇÑù¹¤×÷.
function SomeFunction($aObj) { $aObj->Set(10); }
¡
SomeFunction ($myObj);
¡
ÄÇôÏÖÔÚ, ºÜÈÝÒ×±ã»áÈÏΪ¸Ãº¯ÊýËùµ÷ÓõÄSet()·½·¨»á×÷ÓÃÓÚ$myObj. µ«ÕâÊÇ´íµÄ!
Æäʵ·¢ÉúµÄÊÇ$myObj±»¿½±´ÎªÒ»¸öеÄ, ÓëÔ¶ÔÏóÒ»ÑùµÄ¿½±´----²ÎÊý$aObj. È»ºóµ±Set()·½·¨±»µ÷ÓÃʱ, Ëü½ö½ö×÷ÓÃÓÚ±¾µØ¿½±´¶ø·ÇÔ²ÎÊý----$myObj.
ÔÚ°üº¬Ö±½Ó»ò¼ä½Ó(ÈçÉÏ)¸³Öµ²Ù×÷µÄµØ·½¾Í»á·¢Éú¸÷ÖÖ¸÷ÑùµÄÉÏÊöÎÊÌâ.
ΪÁ˺¯ÊýÄÜÏñÄãËùÆÚÍûµÄÄÇÑùÐж¯(Ò²ÐíÊÇ), ÄÇôÄã²»µÃ²»Í¨¹ýÐ޸ķ½·¨ÉêÃ÷À´¸æËßPHPʹÓÃÒýÓÃÀ´´«µÝ¶ÔÏó, Èç:
Function SomeFunction(&$aObj)
Èç¹ûÄãÔÙÒ»´Î³¢ÊÔÉÏÃæµÄ´úÂë, ÄÇôÄã»á·¢ÏÖSet()·½·¨½«×÷ÓÃÓÚÔÀ´µÄ²ÎÊýÉÏ, ÒòΪÏÖÔÚÎÒÃÇÔÚ×÷ÓÃÖд´½¨ÁËÒ»¸ö$myObjµÄ±ðÃû----$aObj.
µ«ÊÇÄã²»µÃ²»Ð¡ÐÄ, ÒòΪ¼´Ê¹ÊÇ£¦²Ù×÷·ûÒ²²»ÊÇÔÚÈκÎʱºò¶¼ÄܾÈÄã, ÈçÏÂÃæµÄ¾ÙÀý.
´ÓÒ»¸öÒýÓÃÀ´»ñµÃÒýÓÃ
¼ÙÉèÓÐÈçÏ´úÂë:
$myObject = new SomeClass();$myRefToObject = &$myObject;
Èç¹ûÎÒÃÇÏÖÔÚÏëÒªÒ»¸öÒýÓõĿ½±´(ÒòijЩÀíÓÉ), ÄÇôÎÒÃÇÒª×öÊ²Ã´ÄØ? Äã¿ÉÄÜ»áÓÉÓÚ$myRefToObjectÒѾÊÇÒýÓöøÊÔͼÄÇôд:
$myCopyRefToObject = $myRefToObject;
Õýȷô? ²»! PHP»á´´½¨$myRefToObjectËùÒýÓöÔÏóµÄп½±´. Èç¹ûÄãÏ뿽±´Ò»¸ö¶ÔÏóµÄÒýÓÃ, Äã²»µÃ²»Õâôд:
$myCopyRefToObject = &$myRefToObject;
ÔÚÓëǰËùÊöÀý×ÓÏ൱µÄC++µÄÀý×ÓÖÐ, ±ã»á´´½¨Ò»¸öÒýÓõÄÒýÓÃ. ÓëÆäÔÚPHPÖв»Í¬. ÕâÊÇÒ»¸ö¾Ñé·á¸»µÄC++³ÌÐòÔ±³£»á×÷µÄÖ±¾õ¼ÙÉèÏà·´µÄ, ¶øÕâ»áÊÇÄãµÄPHP³ÌÐòÖÐСBUGµÄÀ´Ô´.
ÇëСÐÄÓÉ´ËËù²úÉúµÄ¼ä½Ó(´«µÝ²ÎÊý)»òÖ±½ÓµÄÎÊÌâ.
ÎÒ¸öÈËËù´ï³ÉµÄ½áÂÛ, ¼´×îºÃµÄ±ÜÃâÕâЩÓïÒåÏÝÚåµÄ·½·¨ÊÇ×ÜÊÇÓÃÒýÓÃÀ´´«µÝ¶ÔÏó»òÕß¶ÔÏó¸³Öµ. Õâ²»½ö½ö¸Ä½øÁËÔËÐÐËÙ¶È(¸üÉÙµÄÊý¾Ý¿½±´), ¶øÇÒ¿ÉÒÔ¶ÔÏñÎÒÕâÑùµÄÀϹ·¶øÑÔʹÓïÒå¸ü¼Ó¿ÉÔ¤²â.
ÔÚ¹¹Ô캯ÊýÖжÔ$thisʹÓÃÒýÓÃ
ÔÚÒ»¸ö¶ÔÏóµÄ¹¹Ô캯ÊýÀï³õʼ»¯×÷ΪÆäËû¶ÔÏó·¢ÏÖÕß(Observer[6])µÄ¶ÔÏóÊÇÒ»¸ö³£¼ûµÄģʽ. ÏÂÃæ¼¸ÐдúÂë±ãÊÇÒ»¸öʾÀý:
class Bettery
{
function Bettery() {¡};
function AddObserver($method, &$obj)
{
$this->obs[] = array($obj, &$method)
}
function Notify(){¡}
}
class Display
{
function Display(&$batt)
{
$batt->AddObserver("BatteryNotify",$this);
}
function BatteryNotify() {¡}
}
µ«ÊÇ, Õâ²¢²»»áÕý³£¹¤×÷, Èç¹ûÄãÊÇÕâôʵÀý»¯¶ÔÏóµÄ:
$myBattery = new Battery();$myDisplay = new Display($myBattery);
Õâô×öµÄ´íÎóÔÚÓÚnewʱÔÚ¹¹Ô캯ÊýÖÐʹÓÃ$this²¢²»»á·µ»ØÍ¬Ò»¸ö¶ÔÏó. ·´¶ø»á·µ»Ø×î½ü´´½¨¶ÔÏóµÄÒ»¸ö¿½±´. ¼´ÔÚµ÷ÓÃAddObserver()ʱËù´«Ë͵ĶÔÏóÓÚÔ¶ÔÏó²»ÊÇͬһ¸ö. È»ºóµ±BatteryÀà³¢ÊÔ֪ͨËùÓÐËüµÄ¹Û²ìÕß(Observer)(ͨ¹ýµ÷ÓÃËûÃǵÄNotify·½·¨)ʱ, Ëü²¢²»»áµ÷ÓÃÎÒÃÇËù´´½¨µÄDisplayÀà¶øÊÇ$thisËù´ú±íµÄÀà(¼´ÎÒÃÇËù´´½¨µÄDisplayÀàµÄ¿½±´). Òò´ËÈç¹ûNotify()·½·¨¸üÐÂÁËһЩʵÀý±äÁ¿, ²¢²»ÏñÎÒÃÇËùÉèÏëÔDisplayÀà»á±»¸üÐÂ, ÒòΪ¸üÐÂµÄÆäʵÊǸö¿½±´. ΪÁËÈÃËü¹¤×÷, Äã±ØÐëʹ¹¹Ô캯Êý·µ»ØÍ¬Ò»¸ö¶ÔÏó, ÕýÈçÓë×î³õ$thisËùÏóÕ÷µÄÄÇÑù. ¿ÉÒÔͨ¹ýÌí¼Ó&·ûºÅÓÚDisplayµÄ¹¹Ôì, Èç$myDisplay = & new Display($myBattery);
Ò»¸öÖ±½ÓµÄ½á¹ûÊÇÈκÎDisplayÀàµÄClient±ØÐëÁ˽âDisplayµÄʵÏÖϸ½Ú. ÊÂʵÉÏ, Õâ»á²úÉúÒ»¸ö¿ÉÄÜÒýÆðÕùÂÛµÄÎÊÌâ: ËùÓжÔÏóµÄ¹¹½¨±ØÐëʹÓöîÍâµÄ&·ûºÅ. ¾ÍÎÒËù˵µÄ»ù±¾ÉÏÊǰ²È«µÄ, µ«ºöÂÔËü¿ÉÄÜ»áÔÚijЩʱºòµÃµ½²»ÏëÒªµÄÈçÉÏÊöʾÀý°ãµÄ×÷ÓÃ.
ÔÚJpGraphÖÐʹÓÃÁËÁíÒ»ÖÖ·½·¨À´½â¾ö. ¼´ÐèҪʹÓÃͨ¹ýÌí¼ÓÒ»¸öÄܰ²È«µÄʹÓÃ&$thisÒýÓõġ±Init()¡±·½·¨µÄËùν¶þ½×¶Î¹¹ÔìÀ´¡±new¡±Ò»¸ö¶ÔÏó(½ö½öÊÇÒòΪÔÚ¹¹Ô캯ÊýÖеÄ$thisÒýÓ÷µ»Ø¶ÔÏóµÄÒ»¸ö¿½±´¶ø²»ÈçËùÆÚÍûµÄÄÇÑùÖ´ÐÐ). Òò´ËÉÏÃæµÄÀý×Ó»áÈçÏÂʵÏÖ:
$myBattery = new Battery();
$myDisplay = new Display();
$myDisplay->Init($myBattery);
ÈçJPGraph.PHPÖеġ±LinearScale¡±Àà.
ʹÓÃforeach
ÁíÍâÒ»¸öÏàËÆ´úÂëÈ´²»Í¬½á¹ûµÄÎÊÌâÊÇ¡±foreach¡±½á¹¹µÄÎÊÌâ. Ñо¿Ò»ÏÂÏÂÃæµÄ¶þ¸öÑ»·½á¹¹µÄ²»Í¬°æ±¾.
// Version 1
foreach( $this->plots as $p )
{
$p->Update();
}
¡
// Version 2
for( $i=0; $iplots); ++$i )
{
$this->plots[$i]->Update();
}
ÏÖÔÚÊÇÒ»¸ö¼ÛÖµ10ÃÀÔªµÄÎÊÌâ[7]: version1==version2ô?
ÁîÈ˾ªÑȵĴð°¸ÊÇ:No! ÕâÊÇϸСȴÊǹؼüµÄ²»Í¬. ÔÚVersion 1ÖÐ, Update()·½·¨½«×÷ÓÃÓÚ¡±plots[]¡±Êý×éÖжÔÏóµÄ¸±±¾. Òò´ËÊý×éÖÐÔÀ´µÄ¶ÔÏó²¢²»»á±»¸üÐÂ.
ÔÚVersion 2ÖÐUpdate()·½·¨½«ÈçÔ¤ÆÚµÄ×÷ÓÃÓÚ¡±plots[]¡±Êý×éÖеĶÔÏó.
ÕýÈçµÚÒ»²¿·ÖËù³ÂÊöµÄ, ÕâÊÇPHP½«¶ÔÏóʵÀý×÷Ϊ¶ÔÏó±¾ÉíÀ´´¦Àí¶ø·Ç×÷Ϊ¶ÔÏóÒýÓõĽá¹û.
Òë×¢:
[1]. OO: Object-Oriented, ÃæÏò¶ÔÏó.
[2]. ÔÎIJ¢ÎÞC#, È«ÒòBinzyµÄ¸öÈ˰®ºÃ.
[3]. SemanticÔÚ±¾ÎÄÖб»ÒëΪ¡±ÓïÒ塱, ÈçÓÐÈκν¨ÒéÇëºÍBinzyÁªÏµ.
[4]. C++ÖÐÓÐÒ»±¾ÖøÃûµÄ¡±C++ Gotchas¡±.
[5]. ÕâÀïµÄÀàÓ¦¸ÃÊÇÖ¸Instance, ¼´ÊµÀý.
[6]. ¿É²Î¼û¡±[GoF95]¡±, ¼´¡±Design Patterns¡±.
[7]. ÓиöͦÓÐȤµÄ¹ØÓÚ½»Ò×µÄС¹ÊÊÂ:
ÓÐÈËÓÃ60ÃÀÔªÂòÁËһƥÂí, ÓÖÒÔ70ÃÀÔªµÄ¼ÛÇ®ÂôÁ˳öÈ¥;È»ºó, ËûÓÖÓÃ80ÃÀÔª°ÑËüÂò»ØÀ´, ×îºóÒÔ90ÃÀÔªµÄ¼ÛÇ®Âô³ö.ÔÚÕâ×®ÂíµÄ½»Ò×ÖÐ, Ëû? (A)ÅâÁË10ÃÀÔª; (B)ÊÕ֧ƽºâ; ©×¬ÁË10ÃÀÔª;(D)׬ÁË20ÃÀÔª; (E)׬ÁË30ÃÀÔª.
ÕâÊÇÃÀ¹úÃÜÖ´°²´óѧÐÄÀíѧ¼Ò÷¶ûºÍ²®¿ËÒª´óѧÉúÃǼÆËãµÄÒ»¸ö¼òµ¥µÄËãÊõÌâ.½á¹ûÖ»Óв»µ½40%µÄ´óѧÉúÄܹ»×÷³öÕýÈ·´ð°¸, ¶àÊýÈËÈÏΪֻ׬ÁË10ÃÀÔª.Æäʵ, ÎÊÌâµÄÌõ¼þÊ®·ÖÃ÷È·, ÕâÊÇÁ½´Î½»Ò×, ÿ´Î¶¼×¬10ÃÀÔª, ¶øºÜ¶àÈËÈ´´íÎóµØÈÏΪµ±ËûÓÃ80ÃÀÔªÂò»ØÀ´Ê±¼º¾¿÷ËðÁË10ÃÀÔª. ÓÐȤµÄÊÇ, ͬһÎÊÌâ, ÒÔÁíÒ»ÖÖ·½Ê½Ìá³öÀ´:ÓÐÒ»¸öÈËÓÃ60ÃÀÔªÂòÁËһƥ°×Âí, ÓÖÒÔ70ÔªµÄÖµÂô³öÈ¥;È»ºó, ÓÃ80ÃÀÔªÂòÁËһƥºÚÂí, ÓÖÒÔ90ÃÀÔªµÄÖµÂô³öÈ¥.ÔÚÕâ×®ÂòÂôÂíµÄ½»Ò×ÖÐ, Ëû____(°ÑͬÑùµÄÎå¸öÑ¡ÔñÂÞÁгöÀ´).Õâʱ, ÁíÒ»×é´óѧÉúÔڻشðÉÏÊöÎÊÌâʱ, ½á¹û´ó¼Ò¶¼´ð¶ÔÁË.

