Quy tắc ngón tay cái đơn giản:nếu một lớp extends
khác, thì lớp đó là lớp cha đó (chỉ được thay đổi hoặc mở rộng một chút). Bạn có thể chuyển lớp con này thay vì lớp cha. Ví dụ:
class Foo { }
class Bar extends Foo { }
function baz(Foo $foo) { }
baz(new Bar);
Điều này hoạt động, baz()
mong đợi một Foo
mà còn chấp nhận Bar
, bởi vì Bar
là một Foo
.
Bây giờ, là Users
của bạn a Database
? Không. Người dùng của bạn không phải là một cơ sở dữ liệu. Người dùng của bạn sử dụng Một cơ sở dữ liệu. Nếu hoàn toàn, bạn nên sử dụng thành phần :
class User {
protected $database;
public function __construct(Database $database) {
$this->database = $database;
}
}
Một lớp học nên được trách nhiệm của nó là gì . Trách nhiệm của một lớp quản lý người dùng là quản lý dữ liệu người dùng. Một phần của điều đó có thể liên quan đến việc nói chuyện với cơ sở dữ liệu, nhưng điều đó không có nghĩa là lớp quản lý người dùng is Một cơ sở dữ liệu. Nếu User extends Database
, điều đó có nghĩa là nó có thể làm mọi thứ của Database
lớp có thể làm (và hơn thế nữa). Điều đó có nghĩa là bạn có thể sử dụng Users
lớp học ở mọi nơi thay vì cơ sở dữ liệu Database
lớp học, và điều đó không có ý nghĩa gì. Giữ các trách nhiệm riêng biệt.
Bây giờ, vẫn còn đang tranh cãi về việc liệu đó có phải là cấu trúc phù hợp hay không, nhưng nó đã đi đúng hướng. Nhưng bạn có thể thực sự muốn có Users
lớp, đại diện cho một người dùng . Sau đó, bạn có một UserManager
hoặc UserORM
hoặc UserStorage
hoặc bất cứ điều gì liên quan đến việc truy xuất và lưu trữ Users
các đối tượng trong cơ sở dữ liệu. Đến lượt lớp này sử dụng một Database
để làm điều đó. Điều đó giữ cho các trách nhiệm được rõ ràng và tách biệt. Người dùng Database
lớp đại diện cho dữ liệu người dùng, Database
lớp tương tác với cơ sở dữ liệu, UserORM/Manager/whatever
ở giữa là thương lượng giữa hai bên.