我一直在构建我的应用程序架构,主要使用功能范例,特别是我从头开始构建的部件/模块。现在,我也在尝试OOD。在基于PHP,MySQL,IdiORM的应用程序中,用于跟踪音乐曲目信息;我的下一步是构建搜索功能,在哪里我计划创建一个类,如果它是正确的方法。我熟悉一般的理论OOP概念,如继承,多态等等。
在我的典型工作流程中,就像过去几年一样,我会在include目录中创建一个名为search.inc.php的文件,实现如下函数:
function search_by_artist($artist_name){
...
}
function search_by_track($track_name){
...
}
然后将其编码为服务,该服务根据数据库中的获取结果返回JSON,并使用表单中的POSTed值创建WHERE
子句。
我的问题是,在这种情况下,将这些实现移动到名为Search的类是否有意义。如果是这样,这个类的实例在逻辑上代表什么? 很遗憾提出一个天真的问题,但由于我的大部分背景都是使用JavaScript中的功能性PHP和原型继承,所以我不太熟悉正统的OOD如何适用于此。此外,建议将add.inc.php或通常所有CRUD服务文件转换为类吗?
一般来说,在什么样的场景中应该首选基于功能的服务架构,何时使用OOD更好?
答案 0 :(得分:3)
OOP在应用程序中可以改进的一件大事就是将不同部分分离。使用函数(请注意,我不是说功能代码),您的搜索功能可能如下所示:
function search_by_artist($artist_name) {
global $db;
$db->query(...)
...
}
该函数被硬编码以依赖特定的数据库连接。
使用OOP,你可以解耦:
class Search {
protected $db;
public function __construct(Database $db) {
$this->db = $db;
}
public function byArtist($name) {
$this->db->query(...);
...
}
}
拥有一个对象构造函数是一个强大的东西。在运行类中的任何其他方法之前,构造函数必须运行,从而允许您强加某些前提条件。除非在对象构造时获得有效的Database
实例,否则任何类方法都无法运行。这意味着没有类方法需要关心数据库连接,他们可以简单地假设$this->db
有一个可用。它究竟是如何实现的,构造函数的工作与调用它的代码一起使用。您已在代码库中创建了一个seam,您可以灵活地传递不同的数据库实例,同时创建数据库实例可用的保证。
在实际的功能代码中,该函数应如下所示:
function search_by_artist(Database $db, $name) {
...
}
一个函数应该纯粹依赖于它的输入和返回定义的输出,它不应该依赖于隐式环境变量或产生副作用。与OOP的区别在于您不必将$db
实例单独传递给每个函数,您可以使用依赖项将对象实例化一次,然后将其作为一个封装包传递。