延遲載入是一種將物件的初始化延遲到實際需要時才進行的設計模式。不是在應用程式啟動時載入所有對象,而是按需載入對象,這可以顯著提高效能和記憶體使用率。
讓我們從一個簡單的例子開始來理解核心概念:
class User { private ?Profile $profile = null; private int $id; public function __construct(int $id) { $this->id = $id; // Notice that Profile is not loaded here echo "User {$id} constructed without loading profile\n"; } public function getProfile(): Profile { // Load profile only when requested if ($this->profile === null) { echo "Loading profile for user {$this->id}\n"; $this->profile = new Profile($this->id); } return $this->profile; } } class Profile { private int $userId; private array $data; public function __construct(int $userId) { $this->userId = $userId; // Simulate database load $this->data = $this->loadProfileData($userId); } private function loadProfileData(int $userId): array { // Simulate expensive database operation sleep(1); // Represents database query time return ['name' => 'John Doe', 'email' => 'john@example.com']; } }
代理模式提供了一種更複雜的延遲載入方法:
interface UserInterface { public function getName(): string; public function getEmail(): string; } class RealUser implements UserInterface { private string $name; private string $email; private array $expensiveData; public function __construct(string $name, string $email) { $this->name = $name; $this->email = $email; $this->loadExpensiveData(); // Simulate heavy operation echo "Heavy data loaded for {$name}\n"; } private function loadExpensiveData(): void { sleep(1); // Simulate expensive operation $this->expensiveData = ['some' => 'data']; } public function getName(): string { return $this->name; } public function getEmail(): string { return $this->email; } } class LazyUserProxy implements UserInterface { private ?RealUser $realUser = null; private string $name; private string $email; public function __construct(string $name, string $email) { // Store only the minimal data needed $this->name = $name; $this->email = $email; echo "Proxy created for {$name} (lightweight)\n"; } private function initializeRealUser(): void { if ($this->realUser === null) { echo "Initializing real user object...\n"; $this->realUser = new RealUser($this->name, $this->email); } } public function getName(): string { // For simple properties, we can return directly without loading the real user return $this->name; } public function getEmail(): string { // For simple properties, we can return directly without loading the real user return $this->email; } }
循環引用提出了特殊的挑戰。這是一個全面的解決方案:
class User { private ?Profile $profile = null; private int $id; public function __construct(int $id) { $this->id = $id; // Notice that Profile is not loaded here echo "User {$id} constructed without loading profile\n"; } public function getProfile(): Profile { // Load profile only when requested if ($this->profile === null) { echo "Loading profile for user {$this->id}\n"; $this->profile = new Profile($this->id); } return $this->profile; } } class Profile { private int $userId; private array $data; public function __construct(int $userId) { $this->userId = $userId; // Simulate database load $this->data = $this->loadProfileData($userId); } private function loadProfileData(int $userId): array { // Simulate expensive database operation sleep(1); // Represents database query time return ['name' => 'John Doe', 'email' => 'john@example.com']; } }
interface UserInterface { public function getName(): string; public function getEmail(): string; } class RealUser implements UserInterface { private string $name; private string $email; private array $expensiveData; public function __construct(string $name, string $email) { $this->name = $name; $this->email = $email; $this->loadExpensiveData(); // Simulate heavy operation echo "Heavy data loaded for {$name}\n"; } private function loadExpensiveData(): void { sleep(1); // Simulate expensive operation $this->expensiveData = ['some' => 'data']; } public function getName(): string { return $this->name; } public function getEmail(): string { return $this->email; } } class LazyUserProxy implements UserInterface { private ?RealUser $realUser = null; private string $name; private string $email; public function __construct(string $name, string $email) { // Store only the minimal data needed $this->name = $name; $this->email = $email; echo "Proxy created for {$name} (lightweight)\n"; } private function initializeRealUser(): void { if ($this->realUser === null) { echo "Initializing real user object...\n"; $this->realUser = new RealUser($this->name, $this->email); } } public function getName(): string { // For simple properties, we can return directly without loading the real user return $this->name; } public function getEmail(): string { // For simple properties, we can return directly without loading the real user return $this->email; } }
以上是延遲載入和循環引用的詳細內容。更多資訊請關注PHP中文網其他相關文章!