我是一个PHPer,并没有编写面向对象的代码.
OO优于过程代码有什么优势,我在哪里可以学习如何将这些想法应用到PHP?
它不会自动帮助您.你可以编写比结构程序更糟糕的"OO"程序,反之亦然.OOP是一个允许您创建更强大的抽象的工具.
与每个强大的工具一样,您必须正确使用它.
与每个强大的工具一样,学习如何正确使用它需要时间.
与每个强大的工具一样,你会犯错误.
与每个强大的工具一样,您必须练习很多.
与每个强大的工具一样,您应该阅读很多关于它的内容,并阅读其他人的想法.向他人学习.
但是,正如每个强大的工具一样,有些人滥用它.学会不学习他们的不良做法.这很难.
对象有助于将代码隔离在不同的部分之间,因此如果您需要对一个部分进行更改,您可以确信它不会影响其他部分:松散耦合.
然后,当你已经完成了一段时间后,你会发现你为一个应用程序创建的对象在其他应用程序中也很有用,并且你也开始获得更好的代码重用.因此,新应用程序已完成部分工作,并且正在使用经过时间考验的代码:软件构建速度更快,错误更少.
人们会从各个角度告诉你关于OOP的各种事情.但是如果你想形成自己的观点,而不是拿别人的观点,那么我建议阅读Bertrand Meyer的"面向对象的软件构建".
从本质上讲,他采用非OOP编程技术,并分析其基本缺陷.然后,他得出了一种解决这些缺陷的替代技术.换句话说,他从第一原则中得出OOP.这是一项了不起的工作,非常有说服力.
阅读它,您将了解为什么,何时以及以何种方式可以通过推理进行备份.
对象有助于封装复杂性.对于大多数PHP编程来说,为任何相当复杂的应用程序编写好的,干净的代码是不可能的.编写OO PHP可以帮助您将代码放入自己的框中,将其与其他所有代码隔离开来.这有几个好处.
只要你的对象有明确定义的输入和输出,对象完成它所做的事情的方式根本不重要 - 存储/检索数据可以从平面文件到XML到memcache到MySQL到Oracle,你只有不得不关注一个单一的对象.
只要您的对象具有明确定义的输入和输出,您就可以将其完全替换为具有相同输入/输出的另一个对象.在运行时决定是否需要MySQL,Postgres,memcached或HTTP POST/GET请求到印度尼西亚的粗略服务器.
OO使单元测试更容易.如果你可以定义一个特定对象应该做什么(即它应该给你一个给定输入的结果)那么你可以轻松地编写代码来测试针对该代码的数千个值并检查结果,你会立即知道是否有什么东西休息.
您隐藏在对象中的代码越多,在使用该功能时就必须看到的代码越少.我在PHP中编写了一个轮询应用程序,它处理了轮询的所有方面 - 数据库交互,轮询生成,投票,排名,排序和显示 - 我只需要在我的网站上使用一行代码(Poll::Display()
)来实现整个应用可以做 - 这使我的主页更容易维护.
记住一件事 - 与Python或Ruby等语言相比,PHP中的OO(甚至PHP5)不是很好的OO.Python中的所有对象模型是让OO编程真正为我点击的原因 - 作为一名前PHP程序员(以及经过双重认证的Zend工程师),如果你想了解什么是OO,我强烈推荐探索Python的OO就是这样.它至少可以帮助您编写更好的PHP代码.
是的,如果你真的得到它.
它可以帮助您直观地了解较大系统的各个部分如何相互交互.它在设计层面非常有用.
如果您只是编写几行代码,那么您将获得的唯一好处是,使用分解为精心设计的对象而不仅仅是函数的库通常会更容易一些.
要充分利用它,您还需要遵循合理的OO设计实践.始终使用许多小类封装所有数据,从不使用大型"全能"类.让课程为你工作,而不是要求它提供数据和在课堂外做工作等.
它可能暂时不会对你有所帮助,如果你总是在做小型网站(我不能肯定地说,我真的不做php),但可能永远都不会帮助你,但随着时间的推移,在大型项目上它可以是非常宝贵的.
没人提到的一件事是OO代码有助于编写可读代码:
sherry.changePhoneNumber(); phoneCompany.assignNewPhoneNumberTo(sherry); sherry.receive(new PhoneNumber().withAreaCode("555").withNumber("194-2677"));
我从这种美学中得到了一种奇怪的满足感.
对我来说,一个巨大的胜利就是继承,或者制作一个几乎与另一个完全相同但却有一些差异的物体.这是我办公室的一个真实案例:
我们需要代码来处理客户发送给我们的TIFF文件,将它们转换为标准格式,将有关该文件的一些信息插入数据库,然后发送结果电子邮件.我在一组类中编写了这个(在Python中,但想法是一样的)."fetcher"类从POP3邮箱收到电子邮件,并将其发送到"容器"类,该类知道如何从电子邮件中读取附件.该类将每个图像传递给执行必要处理的"文件对象"类.
好吧,有一天我们有一个想要发送PDF文件的客户.我将"TIFF文件对象"类子类化并重写了"normalize"函数,将PDF作为输入,但保留了其他所有代码.它第一次工作,我很高兴.
对我们的邮件服务器的更改意味着我需要通过IMAP获取电子邮件.再次,我将"POP3 fetcher"子类化,以便它可以说IMAP.问题解决了.
另一位客户希望向我们发送CD,因此我将"email container"类子类化为"filesystem directory"类.瞧 - 完成了.
在每种情况下,新代码与旧代码的95%相似.例如,"TIFF文件对象"类有大约15种方法."PDF文件对象"类只定义了一个:将特定格式的文件转换为标准的方法.它从其父类获得的所有其他内容.
现在,你绝对可以在程序上做同样的事情,比如通过写:
if fileobjecttype == 'TIFF': data =elif fileobjecttype == 'PDF': data = elif fileobjecttype == 'PNG': data =
最大的区别在于我相信你可以让OOP看起来更干净,更有条理.我的PDF类看起来像:
class PDFReader(GenericImageReader): def normalize(self): data = <45 lines to read a PDF>
就是这样.你可以一眼就看出它只有一件事与它继承的类不同.它还会迫使您 - 或者至少强烈鼓励您 - 在应用程序的各个层之间建立干净的界面.在我的示例中,PDFReader不知道并且不关心其图像是来自POP3邮箱还是CD-ROM.POP3提取器完全不了解附件,因为它的工作只是收发电子邮件并传递它们.在实践中,这使我们能够以绝对最少的编码或重新设计来做一些相当惊人的事情.
OOP并不神奇,但它是保持代码组织的一种非常棒的方式.即使你不到处使用它,它仍然是你真正应该发展的技能.