设为首页收藏本站

LUPA开源社区

 找回密码
 注册
文章 帖子 博客
LUPA开源社区 首页 业界资讯 技术文摘 查看内容

PHP开发:从程序化到面向对象

2013-7-9 12:00| 发布者: 红黑魂| 查看: 3148| 评论: 0|来自: 51CTO

摘要: 教程详情• 难度: 中级• 预计完成时间: 60分钟这份教程的诞生源自一年多之前Robert C.Martin在演讲中带给我的启发。当时他的演讲主题在于讨论创造“终极编程语言”的可能性。在过程中,他提出了这样几个问题:为什 ...

因此我们需要保证只有Presenter感知到这一情况,即将以上两个方法变换为下列内容:

  1. function getEventsForCalendar($calendarId) {  
  2.    global $client;  
  3.    return getEventList($client$calendarId)['items'];  
  4. }  
  1. function printCalendarContents() {  
  2.    $this->putCalendarTitle();  
  3.    $eventsForCalendar = $this->businessLogic->getEventsForCalendar(htmlspecialchars($_GET['showThisCalendar']));  
  4.    foreach ($eventsForCalendar as $event) {  
  5.       $this->putEventListElement($event);  
  6.    }  
  7. }  

现在我们需要实现特定事件的输出功能。对于本文中的范例,我们假设自己无法直接检索任何事件,即必须亲自进行事件查找。Logic类这时候就要派上用场了,我们可以在其中操作事件列表并搜索特定ID:

  1. function getEventById($eventId$calendarId) {  
  2.    foreach ($this->getEventsForCalendar($calendarIdas $event)  
  3.       if ($event['id'] == $eventId)  
  4.          return $event;  
  5. }  

然后Presenter的对应调用会完成输出工作:

  1. function printEventDetails() {  
  2.    $this->putEvent(  
  3.       $this->businessLogic->getEventById(  
  4.          $_GET['showThisEvent'],  
  5.          $_GET['calendarId']  
  6.       )  
  7.    );  
  8. }  

就是这样,我们已经成功完成了依赖倒置。

控制流仍然由Logic指向Presenter,所有输出内容也完全由Logic进行定义。这样如果我们打算接入其它日程表服务,则只需创建另一个Logic类并将其注入Presenter即可,Presenter本身不会感知到任何差异。再有,源代码依赖关系也被成功倒置。Presenter是惟一创建且直接依赖于Logic的类。这种依赖关系对于保证Presenter可随意变更数据显示方式而又不影响Logic内容而言至关重要。此外,这种依赖关系允许我们利用CLI Presenter或者其它任何向用户显示信息的方法来替代HTML Presenter。

摆脱全局变量

现在惟一漏网的潜在设计缺陷就只剩下$client全局变量了。应用程序中的所有代码都会对其进行访问,但与之形成鲜明对比的是,真正有必要访问$client的只有Logic类一个。最直观的解决办法肯定是使其变更为专用类变量,但这样一来我们就需要将$client经由Router传递至Presenter处,从而使presenter能够利用$client变更创建出Logic对象——这对于解决问题显然无甚作用。我们的设计初衷是在独立环境下建立类,并准确为其分配依赖关系。

对于任何大型类结构,我们都倾向于使用Factories;但在本文的小小范例中,index.php文件已经足以容纳逻辑创建了。作为应用程序的入口点,这个类似于高层体系结构中“main”的文件仍然处于业务逻辑的范畴之外。

因此我们将index.php中的代码变更为以下内容,同时保留所有内容以及session_start()指令:

  1. $client = createClient();  
  2. if(!authenticate($client)) return;  
  3.    
  4. $logic = new Logic($client);  
  5. $presenter = new Presenter($logic);  
  6. (new Router($presenter))->doUserAction();  

结语

现在工作彻底完成了。当然,我们的设计肯定还有很多改进的空间。我们可以为Logic类中的方法编写一些测试流程,也许Logic类本身也可以换个更有代表性的名称,例如GoogleCalendarGateway。我们还可以创建Event与Calendar类,从而更好地控制相关数据及行为,同时将Presenter的依赖关系根据数据类型拆分为数组。另一项改进与扩展方针则是创建多态性行为类,用于取代直接通过$_GET调用函数。总而言之,对于这一范例的改进可谓无穷无尽,有兴趣的朋友可以尝试将自己的想法转化为现实。我在附件的GoogleCalObjectOrientedFinal文件夹中保存有代码的最终版本,大家能够以此为起点进行探索。

如果大家的好奇心比较强,也可以试着将这款小应用与其它日程表服务对接,看看如何在不同平台上以不同方式实现信息输出。对于使用NetBeans的朋友,每个源代码文件夹中都包含有NetBeans项目,大家只要直接打开即可。在最终版本中,PHPUnit也已经准备就绪。不过我在其它项目中将其移除了——因为还没有经过测试。

感谢您的阅读。

附件下载地址:https://github.com/tutsplus/From-Procedural-to-Object-Oriented-PHP

原文链接:http://net.tutsplus.com/tutorials/php/from-procedural-to-object-oriented-php/


酷毙
1

雷人

鲜花

鸡蛋

漂亮

刚表态过的朋友 (1 人)

  • 快毕业了,没工作经验,
    找份工作好难啊?
    赶紧去人才芯片公司磨练吧!!

最新评论

关于LUPA|人才芯片工程|人才招聘|LUPA认证|LUPA教育|LUPA开源社区 ( 浙B2-20090187 浙公网安备 33010602006705号   

返回顶部