OO 的要点是将属于一起的东西打包在一起。请参阅这个存储和输出客户数据的简单示例:
$customers = array(
array('id' => 1, 'firstname' => 'John', 'lastname' => 'Doe', 'address' => 'Foobar Lane', …),
array('id' => 2, 'firstname' => 'Jane', 'lastname' => 'Dough', 'address' => 'Foobar Road', …)
);
function output_customer_name($customer) {
return $customer['firstname'] . ' ' . $customer['lastname'];
}
function output_customer_address($customer) {
return $customer['address'] . ', ' . $customer['state'] . ', ' . $customer['country'];
}
foreach ($customers as $customer) {
echo output_customer_name($customer);
echo output_customer_address($customer);
}
您需要为要输出的关于客户的每种类型的数据声明不同的函数(这只是一个简单的示例,输出可能要复杂得多)。想象一下,您不仅有客户,还有产品。现在您还拥有output_product_name 和output_product_description 函数。不过,您的数据结构($customer 数组)定义不明确。您可以随时更改它,如果您忘记更新它们,这将破坏您的所有输出功能。您也可能不小心将$product 输入到output_customer_name 函数中,这会破坏一切。
输入 OOP:
class Customer {
protected $firstname;
protected $lastname;
protected $address;
…
public function __construct($firstname, $lastname, $address, …) {
$this->firstname = $firstname;
$this->lastname = $lastname;
$this->address = $address;
…
}
public function name() {
return $this->firstname . ' ' . $this->lastname;
}
public function address() {
return $this->address . ', ' . $this->state . ', ' . $this->country;
}
}
$customers[] = new Customer('John', 'Doe', 'Foobar Lane', …);
$customers[] = new Customer('Jane', 'Dough', 'Foobar Road', …);
foreach ($customers as $customer) {
echo $customer->name();
echo $customer->address();
}
您的数据结构和应该对它们起作用的函数被捆绑到一个对象中。您不可能将$product 提供给应该输出客户的函数。您的函数名称也短了很多,并且您的命名空间没有杂乱无章的函数。在将数据分配到数据结构('John' 到 $firstname)时,您不会冒着拼写数组键的风险。与客户打交道的复杂性已全部打包到对象中。与程序方式相比,数据结构、函数和处理两者都同样复杂且容易出错。在 OOP 中,您的对象很复杂,但处理对象的代码非常简单,几乎不会出错。
这只是一个非常简单的例子。您的项目越复杂,您从结构合理的对象中获得的好处就越多,而不是结构松散的函数和变量。复杂性并没有均匀地分布在整个代码库中,而是捆绑在对象中。由于对象“外部”的代码已被简化,这些对象本身可以成为更复杂代码的一部分,而您的整个代码库的复杂性不会随着您的每个新实体(产品、客户)而呈指数级增长介绍。这一切都是为了让您更难自欺欺人,并使您的代码更具可读性和更好的结构。封装、抽象等是将相关事物捆绑在一起的自然副作用。它们使您能够编写更简单的代码,而这反过来又使您能够编写更复杂的代码而不会爆炸。
用过程代码编写复杂的应用程序是完全可能的。但实际上,情况发生了变化。即使您是天才并且可以事先规划应用程序的整个结构,需求也会发生变化。随着时间的推移,您需要扩展、更改和维护您的代码库。与使用单个变量和函数的 Rube Goldberg 机器相比,使用适当结构化、抽象、封装和类型检查的代码要容易得多。