有一些关于这个问题的帖子,但我并没有清楚地理解何时使用面向对象编程,何时在include中使用程序化函数。有人也告诉我,OOP 运行起来很慢,会增加更多的工作量。这对吗?
假设我有一个包含50个函数的大文件。为什么我要用类来调用它们呢?而不是通过 function_name() 来调用它们?我应该转换并创建一个包含所有函数的对象吗?它的优势或具体区别是什么?在 PHP 中采用 OOP 编码有什么好处?模块化?
有一些关于这个问题的帖子,但我并没有清楚地理解何时使用面向对象编程,何时在include中使用程序化函数。有人也告诉我,OOP 运行起来很慢,会增加更多的工作量。这对吗?
假设我有一个包含50个函数的大文件。为什么我要用类来调用它们呢?而不是通过 function_name() 来调用它们?我应该转换并创建一个包含所有函数的对象吗?它的优势或具体区别是什么?在 PHP 中采用 OOP 编码有什么好处?模块化?
面向对象的主要优势来自于继承和多态。如果你使用类,但从未使用这两个概念中的任何一个,那么你可能第一次使用类时不需要它。
我认为 OO 最好的地方之一是允许您摆脱基于类型切换的代码。请考虑:
function drive($the_car){
switch($the_car){
case 'ferrari':
$all_cars->run_ferrari_code();
break;
case 'mazerati':
$all_cars->run_mazerati_code();
break;
case 'bentley':
$all_cars->run_bentley_code();
break;
}
}
使用其面向对象的替代方案:
function drive($the_car){
$the_car->drive();
}
多态性将允许基于运行时信息发生适当类型的"驾驶"。
关于多态的注释:
这里的第二个例子有一些前提条件:即所有汽车类都将扩展一个抽象类或实现一个接口。
两者都允许你强制扩展或实现类来定义特定的函数,例如drive()
。这非常强大,因为它允许您drive()
所有汽车,而无需知道您正在驾驶哪一种;这是因为它们扩展了包含drive()
方法的抽象类或实现了强制定义drive()
方法的接口。
因此,只要确保所有特定的汽车都扩展抽象类car
或实现诸如canBeDriven
之类的接口(两者都必须声明drive()
方法),您就可以在对象上调用drive()
方法,您知道它是一辆汽车(但不知道是什么类型的汽车),而不必担心未定义,因为PHP会向您抛出致命错误,直到您在特定的汽车类中定义这些方法。
function run($car_type) {...}
就可以做得更短了。换句话说,你不需要为不同的汽车编写不同的函数,这完全是虚假的例子。除非你指定驱动程序正在做什么。即使你这样做,我也可以在没有oop的情况下写得更短。 - Petja Zaichikov我会尝试将我的答案作为补充,因为Majd Taby和Coobird的回答非常好。
我多年来一直是一个过程式程序员,并没有反对面向对象编程,但从未真正看到它的重要性...直到我开始在团队中工作并构建更重要和复杂的项目。
在我看来,当您需要为更复杂的应用程序编写简洁、易于维护的代码时,面向对象编程真正发挥作用。请注意,并不是在每种情况下都适用,但有些情况下,过程式编程效果并不太好。
我大多数关于良好面向对象实现的例子都是针对那些有很多相关但又稍有不同的东西的项目。例如有很多表单、很多用户、很多产品的网站等等。
它们都有类似的行为名称,如print()、update()等等...但通过将它们封装为对象并在类中改变方法的实现,我可以使整个站点的运行时代码非常简单干净。此外,这里有一个关键点,尽管具有不同的行为,我仍然可以使用相同的方法调用处理不同的对象在整个应用程序中。这使得第二个开发人员可以处理实际的实现,而我则可以处理更深层次的代码。
我不知道这是否有所帮助,但作为不久前处于您目前状况的人来讲,我非常喜欢面向对象编程。
在编写程序时,使用面向对象编程方法而不是过程式编程方法,这并不完全取决于语言(无论是 PHP 还是其他语言),而是取决于您要解决的问题类型。
例如,如果您有一个程序,只需按顺序执行一堆函数,那么过程式编程就足够了。例如,如果它是一个简单的字符串操作程序,则过程式方法就足够了:
perform_truncation(my_string, 10)
to_upper(my_string)
perform_magic(my_string, hat, rabbit)
然而,如果你要处理许多不同的项(比如文件或其他对象的表示),那么面向对象的方法会更好。
例如,如果你有一堆汽车(Car
),并希望它们能够行驶(drive
),那么在过程式编程中,你可能会做类似以下的事情:
drive_car(first_car)
drive_car(second_car)
与此不同的是,在面向对象编程中,Car
可以自主驾驶:
RedCar myRedCar();
BlueCar myBlueCar();
myRedCar.drive();
myBlueCar.drive();
每辆汽车都属于不同的类别,因此它们的行为可以被定义得不同。此外,它们可能是相同的子类或车
,并且它们可能具有共同的功能。
实际上,采用哪种方法更好取决于问题的类型,有些问题用过程式编程方式解决更好,有些则需要采用面向对象编程方式。
除了过程式或面向对象的问题之外,一个拥有许多函数的源文件也可能成为“代码异味”。这同样适用于包含许多功能的类,这些功能最好在单独的类中作为单独的函数来执行。
这里的问题可能是代码组织,而不是决定选择过程式或面向对象编程。将函数组织成单独的源文件可能是所需的,而不是放弃使用过程式编写程序。
毕竟,有许多采用过程式编程方式编写的程序是编写良好且易于维护的。
如果您将50个函数放入Utilities类中而不是50个静态方法,则会“污染”全局命名空间。
使用具有50个静态方法的类,方法名称仅在类内部有效。
我无法说哪个更好。但是根据我的经验,使用面向对象编程可以更好地管理代码。你知道哪个代码在哪里,哪个文件定义了哪些功能等等。
关于面向对象编程的运行时开销,我曾在某处读到(并且我认为这是正确的),如果你在常规函数中编写了糟糕的代码,并且在面向对象编程中编写了相同的糟糕代码,则函数版本的性能更好。因此,如果你的代码没有编写得很糟糕,那么就没有证据表明面向对象编程会使你的应用程序变慢。同时请记住,这些“慢”和“开销”都是以毫秒为单位衡量的。因此,如果你的应用程序没有为大量用户服务(例如每分钟超过100个用户),你可能感觉不到任何差异。
function drive($the_car){
$the_car();
}
可以轻松地提供其他变量,如下所示:
function operate($the_car,$action){
$the_car($action);
}
function ferrari($action){
switch($action){
case 'drive':
echo 'Driving';
break;
case 'stop':
echo 'Stopped';
break;
default: return;
}
}
operate('ferrari','drive');
在PHP中使用面向对象编程(OOPs)的概念,以确保代码的安全性。所有的查询都是在函数文件中编写而不是代码文件中,因此没有人可以轻易地入侵我们的代码。因此,在PHP中最好使用类来代替直接编写查询。