>  기사  >  백엔드 개발  >  PHP의 싱글턴 패턴에 대해 이야기해 봅시다.

PHP의 싱글턴 패턴에 대해 이야기해 봅시다.

青灯夜游
青灯夜游앞으로
2021-07-26 19:05:244126검색

이전 기사 "PHP의 템플릿 메소드 패턴 심층 분석"에서 PHP의 템플릿 메소드 패턴을 소개했습니다. 이 기사에서는 PHP 디자인 패턴의 싱글톤 패턴을 이해하는 데 도움이 될 것입니다.

PHP의 싱글턴 패턴에 대해 이야기해 봅시다.

싱글턴 패턴은 일반적으로 사용되고 자주 묻는 인터뷰 디자인 패턴 중 확실히 1위를 차지합니다. 한편으로는 매우 간단하며 몇 단어로 설명할 수 있습니다. 반면에 구현이 하나의 형식일 뿐만 아니라 Java와 같은 비동기 언어의 다중 스레드 잠금 문제도 고려해야 할 정도로 복잡합니다. 그러니 인터뷰할 때 면접관이 싱글톤 모델에 대해 질문할 때 긴장을 풀 것이라고 생각하지 마세요. 이 모델은 실제로 깊을 수도 있고 얕을 수도 있고, 개발자의 수준을 극도로 반영할 수도 있습니다. 일정 기간 동안 작업을 하다 보면 필연적으로 이 모델을 접하게 되기 때문입니다.

Gof 클래스 다이어그램 및 설명

GoF 정의: 클래스에 인스턴스가 하나만 있는지 확인하고 이에 액세스할 수 있는 전역 액세스 포인트를 제공합니다.

GoF 클래스 다이어그램

PHP의 싱글턴 패턴에 대해 이야기해 봅시다.

코드 구현

class Singleton
{
    private static $uniqueInstance;
    private $singletonData = '单例类内部数据';

    private function __construct()
    {
        // 构造方法私有化,外部不能直接实例化这个类
    }

    public static function GetInstance()
    {
        if (self::$uniqueInstance == null) {
            self::$uniqueInstance = new Singleton();
        }
        return self::$uniqueInstance;
    }

    public function SingletonOperation(){
        $this->singletonData = '修改单例类内部数据';
    }

    public function GetSigletonData()
    {
        return $this->singletonData;
    }

}

예, 핵심은 싱글톤 클래스일 뿐 다른 것이 아닙니다. 인스턴스화 후에 정적 변수가 자체적으로 저장되도록 합니다. 이 개체가 필요한 경우 GetInstance() 메서드를 호출하여 전역적으로 고유한 개체를 얻습니다. 클라이언트 측에서

$singletonA = Singleton::GetInstance();
echo $singletonA->GetSigletonData(), PHP_EOL;

$singletonB = Singleton::GetInstance();

if ($singletonA === $singletonB) {
    echo '相同的对象', PHP_EOL;
}
$singletonA->SingletonOperation(); // 这里修改的是A
echo $singletonB->GetSigletonData(), PHP_EOL;

를 호출하면 PHP의 싱글턴 패턴에 대해 이야기해 봅시다.singletonB가 정확히 동일한 개체라는 것을 알 수 있습니다.

  • 예, 코드에서 볼 수 있듯이 싱글톤의 가장 큰 용도는 개체를 전역적으로 고유하게 만드는 것입니다.
  • 그렇다면 글로벌화하면 어떤 이점이 있나요? 일부 클래스를 생성하는 데는 비용이 많이 들고 매번 새 개체를 사용할 필요가 없으며 변경해야 하는 속성이나 상태가 없고 일부 공용 서비스만 제공하는 하나의 개체로 재사용할 수 있습니다. 예를 들어 데이터베이스 작업 클래스, 네트워크 요청 클래스, 로그 작업 클래스, 구성 관리 서비스 등이 있습니다.
  • 면접관이 한 번 질문한 적이 있는데, PHP에서는 싱글톤이 유일한 것인가요? 하나의 프로세스, 즉 1fpm 미만인 경우에는 물론 고유합니다. nginx가 동시에 가져오는 여러 fpm 중 이것이 확실히 유일한 것은 아닙니다. 프로세스당 하나의 프로세스!
  • 싱글턴 패턴의 장점: 고유 인스턴스에 대한 액세스 제어, 작업 및 표현의 개선이 가능하며 클래스 작업보다 더 유연한 수를 허용합니다.
  • Laravel은 IoC 컨테이너 부분에서 싱글톤 패턴을 사용합니다. Laravel 시리즈의 향후 기사에서 컨테이너 부분에 대해 설명하겠습니다. IlluminateContainerContainer 클래스에서 싱글톤 메소드를 찾을 수 있습니다. 바인딩 메소드에서 getClosure 메소드를 호출합니다. 계속 추적하면 결국에는 클래스를 인스턴스화하기 위해 컨테이너의 make 또는 build 메소드를 호출하게 되며, make 또는 build 메소드에 관계없이 싱글톤 판단, 즉 클래스 여부를 판단하게 됩니다. 인스턴스화되었거나 이미 컨테이너에 존재합니다. if (!$reflector->isInstantiable()) 빌드에서.

회사는 점점 커지고 있지만 OA 시스템에는 모든 회사 명단의 사본(싱글톤 클래스)이 하나만 저장되어 있습니다. 제가 두려운 점은 각 부서마다 고유한 명단이 있으면 혼란이 발생할 것이라는 점입니다. 예를 들어 업데이트가 시기적절하지 않으면 다른 부서에서 새로 입사하거나 퇴사한 직원이 누락될 수 있습니다. 다른 부서는 필요할 때 전체 명단을 보거나 전체 명단을 기반으로 자신의 부서 섹션을 만들고 수정할 수 있습니다. 하지만 OA 시스템에서 실제로 수정하는 것은 일반 명단의 내용입니다. 모두가 유지하는 것은 실제로 OA 시스템 서버에 저장된 유일한 실제 명단입니다

전체 코드 : https://github.com/zhangyue0503/ designpatterns-php/blob/master/21.singleton/source/singleton.php

Example

위에서 말한 이후로 저는 데이터베이스 작업 클래스와 네트워크 요청 클래스를 모두 좋아하므로 싱글톤 모드를 사용하겠습니다. HTTP 요청 클래스의 싱글톤 모드 개발을 구현합니다. 오래 전 Android 작업을 할 때는 지금처럼 프레임워크가 많지 않았는데, Http 요청이 모두 자체적으로 캡슐화되어 있었고 대부분의 온라인 튜토리얼이 싱글톤 모드를 채택했던 것으로 기억합니다.

캐시 클래스 다이어그램

PHP의 싱글턴 패턴에 대해 이야기해 봅시다.

전체 소스 코드: https://github.com/zhangyue0503/designpatterns-php/blob/master/21.singleton/source/singleton-http.php

<?php 

class HttpService{
    private static $instance;

    public function GetInstance(){
        if(self::$instance == NULL){
            self::$instance = new HttpService();
        }
        return self::$instance;
    }

    public function Post(){
        echo &#39;发送Post请求&#39;, PHP_EOL;
    }

    public function Get(){
        echo &#39;发送Get请求&#39;, PHP_EOL;
    }
}

$httpA = new HttpService();
$httpA->Post();
$httpA->Get();

$httpB = new HttpService();
$httpB->Post();
$httpB->Get();

var_dump($httpA == $httpB);

지침

  • 여전히 매우 간단한가요? 여기서는 이러한 형태의 싱글톤에 대해 더 이상 이야기하지 않겠습니다. 여러 가지 다른 형태의 싱글톤에 대해 이야기하겠습니다.
  • Java와 같은 정적 언어에서 정적 변수는 직접적으로 새로운 객체가 될 수 있습니다. 선언 PHP의 싱글턴 패턴에 대해 이야기해 봅시다.

    instance = new HttpService();. 이렇게 하면 GetInstance() 메서드를 생략할 수 있지만 이 정적 변수는 사용 여부에 관계없이 직접 인스턴스화되어 메모리를 차지하게 됩니다. 이런 종류의 싱글톤을 Hungry Chinese 싱글톤 패턴이라고 합니다.

  • 우리의 코드와 예제는 분명히 Hungry Man 스타일이 아닙니다. 이 형식을 Lazy Man 스타일이라고 합니다. 이를 얻으려면 GetInstance()를 적극적으로 사용해야 하며 그런 다음 객체를 생성하겠습니다.
  • Java 멀티스레딩이나 PHP에서 swoole을 사용하는 등 멀티스레드 응용 프로그램에서는 반복 생성 문제가 발생하며 여러 번 생성된 객체는 동일한 객체가 아닙니다. 이때 전역 객체가 하나만 존재하는지 확인하기 위해 일반적으로 이중 감지를 사용합니다. 특정 코드를 직접 찾을 수 있습니다. Hungry Han 스타일에는 문제가 없습니다. Hungry Han 스타일 자체는 이미 정적 속성에 값을 할당했으며 다시 변경되지 않습니다.
  • 또 다른 방법은 정적 내부 클래스를 만드는 것입니다. 이는 거의 볼 수 없으며 자원 활용률이 높습니다. 정적 변수가 클래스 내 변수가 아닌 메서드 내 변수가 되도록 메서드 내부에 정적 변수를 넣습니다. 이를 통해 싱글톤 개체가 자신의 정적 메서드와 속성을 호출할 수 있습니다.

원본 주소: https://juejin.cn/post/6844903990585458702

저자: Hardcore Project Manager

추천 학습: "PHP 비디오 튜토리얼"

위 내용은 PHP의 싱글턴 패턴에 대해 이야기해 봅시다.의 상세 내용입니다. 자세한 내용은 PHP 중국어 웹사이트의 기타 관련 기사를 참조하세요!

성명:
이 기사는 juejin.cn에서 복제됩니다. 침해가 있는 경우 admin@php.cn으로 문의하시기 바랍니다. 삭제