PHP에서 싱글톤 패턴 구현하기 > 개발자팁

개발자팁

개발과 관련된 유용한 정보를 공유하세요.
질문은 QA에서 해주시기 바랍니다.

PHP에서 싱글톤 패턴 구현하기 정보

PHP PHP에서 싱글톤 패턴 구현하기

본문

PHP에서 Singleton(싱글톤) 패턴의 구현

  PHP에서 객체가 생성되는 것을 통제하는 것은 정말 어려운 일이다. $변수명 을 적어서 객체를 생성하는 것은 어쩔수 없다고 해도 클래스를 생성하는 일은 분명히 통제되어야 한다. 지금까지 내가 사용해온 방식은 유일한 전역변수를 하나 생성하고 그것을 모든곳에 사용하는 방법이다. 이러한 방법도 유용하다. 그러나 싱글톤 같은 유용한 디자인 패턴에 비해서는 비 효율적인 방법일수 밖에 없다. 여기서 PHP에서 싱글톤을 구현하는 방법에 대해서 설명한다.


싱글톤 패턴이란?

 싱 글톤 패턴이란 프로그램/사이트 전체에서 단 하나의 객체만 생성해서 사용하게 만드는 디자인 패턴이다. 조금만 주의해서 객체를 하나만 생성해서 전체적으로 사용하면 되지 굳이 디자인 패턴까지 사용해야 하냐는 사람도 있겠지만, 사이트가 커지고 파일이 여러군대로 갈라지며 파일 여기저기서 객체를 생성해야 할 때가 되면 내가 어디서 어떤 객체를 생성 하였고 또 어디서 사용하였는지 기억하기란 쉽지 않다. 그래서 항상 하나의 인스턴스만 생성하게 해주는 싱글톤 패턴이 탄생 하게 되었다.
 PHP도 5.0버전대로 진입하면서 static 멤버와 함수를 사용가능하게 되면서 싱글톤 패턴이 사용가능 하게 되었다.

싱글톤 패턴의 장점

 객 체가 하나만 생성된다는 장점도 크지만, 한가지 더 장점이 있다. 객체를 사용하는 그 순간에 생성된다는 것이다. 예전에 사용하던 전역 변수 방식과 비교해 보면 전역변수 방식은 모든 객체를 일시에 생성하고 페이지 로딩이 끝날때 쯤에 모두 소멸한다. 하나의 사이트에 객체를 수십/수백 가지를 사용하게 된다면 그 수십/수백가지의 객체들이 모든 페이지에서 모두 사용되는 것은 아닐 것이다. 사용되는 객체도 있고 사용되지 않는 객체도 있다.
 전역변수 방식을 사용하면서 효과를 보기위해서는 모든 변수를 한곳에 몰아 넣고 일괄 생성하고 수정사항이 발생하면 몰아 넣은 파일에 가서 수정하는 것이 가장 효율적인 방법이다. 이렇게 되면 특정 페이지에서 필요없는 객체를 생성하는 비효율적인 면을 보이게 된다.
 그러나 싱글톤을 잘 구현하게 되면 이러한 제약에서 벗어나게 된다. 최초 getInstance()를 호출하게 되는 순간에 객체가 생성되고 두번째 호출부터는 생성된 인스턴스만 반환하게 된다. 생성자도 한번만 호출되게 되고 소멸자도 한번만 호출 되게 된다. 그리고 언제 어느곳에서 사용해도 문제가 없으며, 여러번 getInstance()를 호출해도 객체는 한번만 생성된다. getInstance()를 호출하지 않은 객체는 생성되지 않는다.


싱글톤 패턴의 구현

 설명은 거창하게 했지만 구현은 아주 간단하다.
  1. class Singleton  
  2. {  
  3.   
  4.     /* 싱글톤 패턴 */  
  5.     private static $singleton;  
  6.     public static function getInstance() {  
  7.         if(!isset(Singleton::$singleton)) Singleton::$singleton= new Singleton('');  
  8.         return Singleton::$singleton;  
  9.     }  
  10.   
  11.     function __construct() {  
  12.         echo "생성";  
  13.     }  
  14.   
  15.     function __destruct() {  
  16.         echo "소멸";  
  17.     }  
  18.   
  19. }  
class Singleton { /* 싱글톤 패턴 */ private static $singleton; public static function getInstance() { if(!isset(Singleton::$singleton)) Singleton::$singleton= new Singleton(''); return Singleton::$singleton; } function __construct() { echo "생성"; } function __destruct() { echo "소멸"; } }
 static 메소드와 static 멤버변수를 이용해서 구현한다. static 멤버를 호출하는 방법은 클래스명::메소드(변수) 이렇게 호출한다. static 이란 말의 의미는 객체를 생성하지 않아도 호출 가능하다는 것이다.
 static 멤버변수를 하나 선언하고 선언된 멤버변수를 getInstance()에서 new를 이용해 할당한다. 이때 isset
함수를 이용해 할당되었으면 할당된 것을 반환하고 할당되지 않은 것이라면 new연산자를 이용해 객체를 생성한다.
  1. $single3 = Singleton::getInstance();  
  2. echo $single3->view(15);  
  3.   
  4. $single = Singleton::getInstance();  
  5. echo $single->view(15);  
  6.   
  7. $single2 = Singleton::getInstance();  
  8. echo $single2->view(15);  
  9.   
  10. $single4 = Singleton::getInstance();  
  11. echo $single4->view(15);  
$single3 = Singleton::getInstance(); echo $single3->view(15); $single = Singleton::getInstance(); echo $single->view(15); $single2 = Singleton::getInstance(); echo $single2->view(15); $single4 = Singleton::getInstance(); echo $single4->view(15);
 클래스를 선언하고 위와 같이 사용하게 된다. Singleton::getInstance();는 언제 어디서나 사용가능하다. 위와 같이 사용하게 되어도 아래와 같은 결과가 나오게 된다.
생성
소멸
 객체는 하나만 생성 되었기 때문에 위와 같이 생성자와 소멸자가 한번만 호출 되게 된다.


싱글톤 사용을 위한 좀더 나은 방법

 싱 글톤 패턴 사용을 위해서 좀더 나은 방법을 사용해 보자. PHP5.0버전에 추가된 __autoload()함수를 오버라이드 해 보자. 이 함수는 클래스의 메소드가 아니라 독립적인 함수이다. 클래스의 선언없이 외부에서 사용가능하다. 이 메소드를 사용하면 선언되지 않은 클래스를 사용할때 자동으로 호출되며, 내부 구현에 따라 클래스가 정의된 파일을 인크루드 하게 된다. 
  1. function __autoload($name) {  
  2.     global $g4;  
  3.     include_once "$g4[path]/class/{$name}.class.php";   // 절대경로는 지원하지않는다. 상대경로만 적도록..  
  4. }  
function __autoload($name) { global $g4; include_once "$g4[path]/class/{$name}.class.php"; // 절대경로는 지원하지않는다. 상대경로만 적도록.. }
 위 예제는 그누보드에서 모든 클래스 파일들을 /class 폴더에 위치 시키고 __autoload()를 위와 같이 선언하게되면 언제 어디서든 인크루드 없이 클래스를 사용가능하다. static 메서드를 호출할 때에도 마찬가지로 자동으로 인크루드 해 준다. $name은 호출하려한 클래스 명이다.


그누보드에서 사용하기

 그누보드에서 /extend 폴더를 활용한다. /extend 폴더에 php파일을 넣어두면 모두 인크루드 된다. 간단하게 /extend/index.php 파일에 위 소스코드를 삽입한다. 그리고 /class 폴더 아래에 자신이 생성하고자 하는 클래스 파일을 파일명을 맞추어서 넣어준다. 위의예에서는 클래스명.class.php 이러한 형식으로 파일을 넣어준다.
 이제 그누보드 어디서든 클래스명::getInstance() 하게되면 인스턴스를 반환 받게되고 클래스 정의 파일은 자동으로 인크루드 된다.


테스트 환경

 PHP 5.2.5
[이 게시물은 관리자님에 의해 2011-10-31 17:12:10 PHP & HTML에서 이동 됨]
추천
1

댓글 2개

음... 한마디로..
사람이란 동물이 실수를 항상 할수 있기 때문에
생성했던 객체 또 생성 할 수있으니까...

실수없이.. 객체는 하나만 생성하자...
이런 취지의 디자인 패턴 입니다.

제가 설명을 잘 못해서..... ㅠㅠ;;

모르시는 부분을 알려주시면 설명 해 드릴게요 ^^
전체 5,352
개발자팁 내용 검색

회원로그인

(주)에스아이알소프트 / 대표:홍석명 / (06211) 서울특별시 강남구 역삼동 707-34 한신인터밸리24 서관 1402호 / E-Mail: admin@sir.kr
사업자등록번호: 217-81-36347 / 통신판매업신고번호:2014-서울강남-02098호 / 개인정보보호책임자:김민섭(minsup@sir.kr)
© SIRSOFT