<?php 인터페이스 IUser { 함수 getName(); } User 클래스는 IUser를 구현합니다. { 공개 함수 __construct( $id ) { } 공개 함수 getName() { "잭"을 반환합니다. } } 클래스 UserFactory { 공개 정적 함수 만들기($id) { 새로운 사용자 반환( $id ); } } $uo = UserFactory::Create( 1 ); echo( $uo->getName()."n" ); ?> |
그림 1. 팩토리 클래스와 관련 IUser 인터페이스 및 사용자 클래스 |
%phpfactory1.php 잭 % |
<?php 인터페이스 IUser { 함수 getName(); } User 클래스는 IUser를 구현합니다. { 공개 정적 함수 로드($id) { 새로운 사용자 반환( $id ); } 공개 정적 함수 생성( ) { 새로운 사용자 반환( null ); } 공개 함수 __construct( $id ) { } 공개 함수 getName() { "잭"을 반환합니다. } } $uo = 사용자::로드( 1 ); echo( $uo->getName()."n" ); ?> |
그림 2. 팩토리 메소드를 사용하는 IUser 인터페이스 및 사용자 클래스 |
%phpfactory2.php 잭 % |
위에서 언급한 것처럼 때로는 이러한 모드가 소규모 환경에서 과도하게 보일 수 있습니다. 그러나 모든 규모의 프로젝트에 적용할 수 있는 견고한 형태의 코딩을 배우는 것이 가장 좋습니다.
단일 요소 모드
이 유형의 리소스는 하나만 있기 때문에 일부 응용 프로그램 리소스는 배타적입니다. 예를 들어, 데이터베이스 핸들을 통한 데이터베이스 연결은 배타적입니다. 연결을 열거나 닫을 때 오버헤드가 발생하기 때문에 애플리케이션 전체에서 데이터베이스 핸들을 공유하려고 합니다. 단일 페이지를 가져오는 프로세스 중에는 더욱 그렇습니다.
단일 요소 모드는 이 요구 사항을 충족합니다. 애플리케이션에 한 번에 하나의 개체만 포함되어 있으면 이 개체는 싱글톤입니다. 목록 3의 코드는 PHP V5의 데이터베이스 연결 단일 요소를 보여줍니다.
목록 3. Singleton.php
<?php require_once("DB.php"); 클래스 DatabaseConnection { 공개 정적 함수 get() { 정적 $db = null; if ( $db == null ) $db = 새로운 DatabaseConnection(); $db를 반환합니다. } 개인 $_handle = null; 개인 함수 __construct() { $dsn = 'mysql://root:password@localhost/photos'; $this->_handle =& DB::Connect( $dsn, array() ); } 공개 함수 핸들() { $this->_handle을 반환합니다. } } print( "Handle = ".DatabaseConnection::get()->handle()."n" ); print( "Handle = ".DatabaseConnection::get()->handle()."n" ); ?> |
그림 3. 데이터베이스 연결 단일 요소 |
% PHP 싱글톤.php 핸들 = 개체 ID #3 핸들 = 개체 ID #3 % |
관찰자 패턴
관찰자 패턴은 구성 요소 간의 긴밀한 결합을 방지하는 또 다른 방법을 제공합니다. 패턴은 매우 간단합니다. 객체는 다른 객체인 관찰자가 자신을 등록할 수 있도록 허용하는 메서드를 추가하여 객체 자체를 관찰 가능하게 만듭니다. 관찰 가능한 객체가 변경되면 등록된 관찰자에게 메시지를 보냅니다. 이러한 관찰자는 이 정보를 사용하여 관찰 가능한 객체와 독립적인 작업을 수행합니다. 결과적으로 객체는 이유를 이해하지 않고도 서로 대화할 수 있습니다. 간단한 예는 시스템의 사용자 목록입니다. 목록 4의 코드는 사용자 목록을 표시하고 사용자가 추가되면 메시지를 보냅니다. 이 목록은 사용자가 추가되면 메시지를 보내는 로그 관찰자를 통해 관찰할 수 있습니다.
목록 4. Observer.php
<?php 인터페이스 IObserver { 함수 onChanged( $sender, $args ); } 인터페이스 IObservable { 함수 addObserver( $observer ); } UserList 클래스는 IObservable을 구현합니다. { 개인 $_observers = 배열(); 공개 함수 addCustomer( $name ) { foreach( $this->_observers를 $obs로) $obs->onChanged( $this, $name ); } 공개 함수 addObserver( $observer ) { $this->_observers []= $observer; } } UserListLogger 클래스는 IObserver를 구현합니다. { 공개 함수 onChanged( $sender, $args ) { echo( "'$args'가 사용자 목록에 추가되었습니다n" ); } } $ul = 새로운 UserList(); $ul->addObserver( new UserListLogger() ); $ul->addCustomer( "잭" ); ?> |
그림 4. 관찰 가능한 사용자 목록 및 사용자 목록 이벤트 로거 |
% PHP 관찰자.php 사용자 목록에 'Jack'이 추가되었습니다. % |
명령 모드 체인
명령 체인 패턴은 느슨하게 결합된 주제를 기반으로 하며 핸들러 세트를 통해 메시지, 명령, 요청 또는 기타 모든 항목을 보냅니다. 각 핸들러는 요청을 처리할 수 있는지 자체적으로 판단합니다. 가능한 경우 요청이 처리되고 프로세스가 중지됩니다. 다른 핸들러에 영향을 주지 않고 시스템에서 핸들러를 추가하거나 제거할 수 있습니다. 목록 5에서는 이 패턴의 예를 보여줍니다.
목록 5. Chain.php
<?php 인터페이스I명령 { 함수 onCommand( $name, $args ); } 클래스 CommandChain { 개인 $_commands = 배열(); 공용 함수 addCommand( $cmd ) { $this->_commands []= $cmd; } 공용 함수 runCommand( $name, $args ) { foreach( $this->_commands as $cmd ) { if ( $cmd->onCommand( $name, $args ) ) 반품; } } } UserCommand 클래스는 ICommand를 구현합니다. { 공개 함수 onCommand( $name, $args ) { if ( $name != 'addUser' ) return false; echo( "'addUser'를 처리하는 UserCommandn" ); 사실을 반환; } } MailCommand 클래스는 ICommand를 구현합니다. { 공개 함수 onCommand( $name, $args ) { if ( $name != 'mail' ) 반환 false; echo( "'mail'을 처리하는 MailCommandn" ); 사실을 반환; } } $cc = 새로운 CommandChain(); $cc->addCommand( new UserCommand() ); $cc->addCommand( new MailCommand() ); $cc->runCommand( 'addUser', null ); $cc->runCommand( '메일', null ); ?> |
그림 5. 명령 체인 및 관련 명령 |
% PHP 체인.php 'addUser'를 처리하는 UserCommand '메일'을 처리하는 MailCommand % |
전략 패턴
우리가 다루는 마지막 디자인 패턴은 전략 패턴입니다. 이 패턴에서는 알고리즘이 복잡한 클래스에서 추출되므로 쉽게 교체할 수 있습니다. 예를 들어, 검색 엔진에서 페이지 순위를 매기는 방식을 변경하려면 전략 모드를 선택하는 것이 좋습니다. 검색 엔진의 부분, 즉 페이지를 순회하는 부분, 각 페이지의 순위를 매기는 부분, 순위에 따라 결과를 정렬하는 부분에 대해 생각해 보십시오. 복잡한 예에서 이러한 부분은 모두 동일한 클래스에 있습니다. 전략 패턴을 사용하면 정렬 부분을 다른 클래스에 넣어 나머지 검색 엔진 코드에 영향을 주지 않고 페이지 정렬 방식을 변경할 수 있습니다.
더 간단한 예로 Listing 6은 플러그 앤 플레이 정책 세트를 기반으로 사용자 세트를 찾는 방법을 제공하는 사용자 목록 클래스를 보여줍니다.
목록 6. Strategy.php
<?php 인터페이스 전략 { 함수 필터($record); } FindAfterStrategy 클래스는 IStrategy를 구현합니다. { 비공개 $_name; 공개 함수 __construct( $name ) { $this->_name = $이름; } 공용 함수 필터($record) { return strcmp( $this->_name, $record ) <= 0; } } RandomStrategy 클래스는 IStrategy를 구현합니다. { 공용 함수 필터($record) { rand( 0, 1 ) >= 0.5;를 반환합니다. } } 클래스 사용자 목록 { 개인 $_list = 배열(); 공개 함수 __construct( $names ) { if ($names != null ) { foreach( $name을 $name으로) { $this->_list []= $이름; } } } 공개 함수 추가($name) { $this->_list []= $이름; } 공개 함수 찾기($filter) { $recs = 배열(); foreach( $user로 $this->_list) { if ( $filter->filter( $user ) ) $recs []= $사용자; } $recs를 반환합니다. } } $ul = new UserList( array( "앤디", "잭", "로리", "메건" ) ); $f1 = $ul->find( new FindAfterStrategy( "J" ) ); print_r( $f1 ); $f2 = $ul->find( new RandomStrategy() ); print_r( $f2 ); ?> |
그림 6. 사용자 선택에 사용되는 사용자 목록 및 정책 |
%php 전략.php 정렬 ( [0] => 잭 [1] =>로리 [2] =>메건 ) 정렬 ( [0] => 앤디 [1] =>메건 ) % |