1. 가장 적합한 디자인 패턴을 선택하세요
완벽한 것은 없으며 누구도 디자인 패턴이 모든 경우에 적용되는 엄격한 솔루션이라고 말한 적이 없습니다. 따라서 이러한 모드를 변경하여 현재 작업에 더 적합하게 만들 수 있습니다. 일부 디자인 패턴의 경우 해당 패턴이 속한 프로그램에 고유한 반면, 다른 디자인 패턴의 경우 패턴 자체를 변경할 수 있습니다. 모드가 협력하고 함께 일하는 것이 일반적입니다. 이는 전체 애플리케이션의 (적어도 일부) 기초를 형성합니다.
2. 싱글톤 모드
-
-
// Database 클래스는 전역 DB 연결을 나타냅니다.
- class Database{
- // 정적 변수 단일 인스턴스 유지
- private static $_instance = null;
-
- // 싱글톤을 보장하기 위해 생성자를 비공개로 만듭니다.
- private function __construct()
- {
- echo 'constructor';
- }
// 싱글톤 인스턴스를 가져오는 메서드
- public static function getInstance()
- {
- if (!(self::$_instance instanceof 데이터베이스)) {
- self::$_instance = new Database();
- }
-
- return self::$_instance;
- }
- }
$database = Database::getInstance();
- var_dump($database);
-
코드 복사
문제: 싱글톤 모드를 사용하여 두 개의 인스턴스를 생성할 수 없습니다. 특성을 사용하여 서로 다른 유형의 두 인스턴스를 생성하는 문제를 해결할 수 있지만 두 개의 동일한 인스턴스를 생성하는 문제는 여전히 해결되지 않습니다(레지스트리 모드로 해결 가능).
다른 클래스 코드의 두 인스턴스를 만듭니다.
-
- 특성 싱글턴 {
- private static $_instance = null;
-
- public static function getInstance() {
- $class = __CLASS__;
-
- if(!(self::$_instance 인스턴스of $class)) {
- self::$_instance = new $class;
- }
-
- return self:: $_instance;
- }
-
- }
- 클래스 DB {
- }
-
- 클래스 DBWriteConnection 확장 DB {
- 싱글톤 사용;
-
- 프라이빗 함수 __construct () {
- echo 'DBWriteConnection
';
- }
- }
-
- class DBReadConnection 확장 DB {
- 싱글톤 사용;
-
- 개인 함수 __construct () {
- echo 'DBReadConnection
';
- }
- }
-
- $dbWriteConnection = DBWriteConnection::getInstance();
- var_dump($dbWriteConnection);
코드 복사
3. 레지스트리 모드
레지스트리 패턴은 코드가 필요할 때 개체의 동일한 인스턴스를 검색하고 필요할 때 다른 인스턴스를 생성할 수 있도록 하는 단순한 단일 전역 클래스입니다(해당 전역 인스턴스는 요청 시 다시 액세스됩니다).
등록 클래스:
-
-
class Registry {
- /**
- * @var array 모든 객체를 저장하는 저장소
- */
- static private $_store = array() ;
-
- /**
- * 레지스트리에 개체 추가
- *
- * 이름을 지정하지 않으면 클래스 이름이 사용됩니다.
- *
- * @param mix $object 저장할 개체
- * @param string $name 객체를 검색하는 데 사용되는 이름
- * @return void
- * @throws Exception
- */
- static public function add($object, $name = null)
- {
- // 이름이 지정되지 않은 경우 클래스 이름을 사용하고 싱글톤을 시뮬레이션합니다.
- $name = (!is_null($name)) ?$name:get_class($object);
- if (isset(self::$_store[$name])) {
- throw new Exception( "개체가 이미 레지스트리에 존재합니다.");
- }
-
- self::$_store[$name]= $object;
- }
-
- /**
- * 레지스트리에서 객체 가져오기
- *
- * @param string $name 객체 이름, {@see self::set()}
- * @return Mixed
- * @throws 예외
- */
- 정적 공용 함수 get($name)
- {
- if (!self::contains($name)) {
- throw new Exception("개체가 레지스트리에 존재하지 않습니다.");
- }
return self::$_store[$name];
- }
-
- /**
- * 레지스트리에 개체가 있는지 확인
- *
- * @param string $name 개체 이름, {@see self::set()}
- * @return bool
- */
- 정적 공개 함수에는 다음이 포함됩니다. ($name)
- {
- if (!isset(self::$_store[$name])) {
- return false;
- }
-
- return true;
- }
-
- /**
- * 레지스트리에서 개체 제거
- *
- * @param string $name 개체 이름, {@see self::set()}
- * @returns void
- */
- 정적 공용 함수 제거($name)
- {
- if (self::contains($name)) {
- unset( self::$_store[$name]);
- }
- }
- }
-
-
코드 복사
클래스 외부에서는 Registry 클래스를 사용합니다.
-
-
require 'Registry.php';
class DBReadConnection {}
- class DBWriteConnection {}
$read = new DBReadConnection;
- Registry::add($read);
$write = new DBWriteConnection;
- Registry::add($write);
// 코드 어디에서나 인스턴스를 가져오려면:
- $read = Registry::get( 'DBReadConnection');
- $write = 레지스트리::get('DBWriteConnection');
var_dump($read);
- var_dump($write);
-
-
코드 복사
클래스 내부에 레지스트리 테이블 클래스를 사용하며, 사용자는 레지스트리와 상호 작용하지 않습니다.
샘플 코드:
-
-
require 'Registry.php';
추상 클래스 DBConnection {
- static public function getInstance($name = null)
- {
- // __CLASS__의 후기 정적 바인딩 버전을 가져옵니다.
- $class = get_called_class();
- // 이름 전달 허용 여러 인스턴스를 얻으려면
- // 이름을 전달하지 않으면 싱글톤으로 작동합니다.
- $name = (!is_null($name)) ? $name:$class;
- if (!Registry ::contains($name)) {
- $instance = new $class();
- Registry::add($instance, $name);
- }
- return Registry::get($ name);
- }
- }
class DBWriteConnection은 DBConnection을 확장합니다. {
- public function __construct()
- {
- echo 'DBWriteConnection
- }
- }
class DBReadConnection은 DBConnection을 확장합니다. {
- 공개 함수 __construct()
- {
- echo 'DBReadConnection
- }
- }
$dbWriteConnection = DBWriteConnection::getInstance('abc');
- var_dump($dbWriteConnection);
- $dbReadConnection = DBReadConnection::getInstance();
- var_dump($dbReadConnection);
-
코드 복사
4.공장 모드
공장 패턴은 이름을 딴 철강 및 콘크리트 산업과 마찬가지로 객체를 제조합니다. 일반적으로 동일한 추상 클래스나 인터페이스의 구체적인 구현을 초기화하기 위해 팩토리 패턴을 사용합니다.
일반적으로 공장 모드는 거의 사용되지 않지만 여전히 다양한 드라이버 기반 설치 변형을 초기화하는 데 가장 적합합니다. 예를 들어 다양한 구성, 세션 또는 캐싱 스토리지 엔진이 있습니다. 팩토리 패턴의 가장 큰 가치는 여러 개체 설정을 하나의 간단한 메서드 호출로 캡슐화할 수 있다는 것입니다.
-
- /**
- * 로그 팩토리
- *
- * 파일, mysql 또는 sqlite 로거 설정 및 반환
- */
- class Log_Factory {
- /**
- * 로그 객체 가져오기
- *
- * @param string $type 로깅 백엔드 유형, 파일, mysql 또는 sqlite
- * @param array $options 로그 클래스 옵션
- */
- 공용 함수 getLog( $type = 'file', array $options)
- {
- // 유형을 소문자로 정규화
- $type = strtolower($type);
-
- // 클래스 이름 파악
- $class = "Log_" .ucfirst($type);
- require_once str_replace('_', DIRECTORY_SEPARATOR, $class) '.php';
-
- // 인스턴스화합니다. 클래스를 선택하고 적절한 옵션을 설정
- $log = new $class($options);
- 스위치($type) {
- 케이스 'file':
- $log->setPath($options[ 'location']);
- break;
- case 'mysql':
- $log->setUser($options['username']);
- $log->setPassword($options ['password']);
- $log->setDBName($options['location']);
- break;
- case 'sqlite':
- $log->setDBPath($ options['location']);
- break;
- }
-
- return $log;
- }
- }
코드 복사
5. 반복 모드
반복 패턴을 사용하면 공용 속성뿐만 아니라 모든 개체의 내부에 저장된 데이터에 foreach의 성능을 추가할 수 있습니다. 기본 foreach 동작을 재정의하고 루프에 비즈니스 논리를 삽입할 수 있습니다.
(1) Iterator 인터페이스 사용
-
-
class BasicIterator는 Iterator를 구현합니다. {
- private $key = 0;
- private $data = array(
- "hello",
- "world",
- );
공개 함수 __construct() {
- $this->key = 0;
- }
공개 함수 rewind() {
- $this->key = 0;
- }
() {
- return $this->data[$this->key];
- }
공개 함수 키() {
- return $this ->key;
- }
공개 함수 next() {
- $this->key ;
- return true;
- } p>
public function valid() {
- return isset($this->data[$this->key]);
- }
- }
$iterator = new BasicIterator();
- $iterator->rewind();
do {
- $key = $iterator- >key();
- $value = $iterator->current();
- echo $key .': ' .$value . PHP_EOL;
- } while ($iterator->next( ) && $iterator->valid());
- $iterator = new BasicIterator();
- foreach ($iterator as $key => $value ) {
- echo $key .': ' .$value . PHP_EOL;
- }
-
코드 복사
(2) RecursiveIteratorIterator를 사용하여 배열을 순회합니다.
-
-
$array = array(
- "Hello", // 레벨 1
- array(
- " World" // 레벨 2
- ),
- array(
- "How", // 레벨 2
- array(
- "are", // 레벨 3
- "you" / / 레벨 3
- )
- ),
- "doing?" // 레벨 1
- );
$recursiveIterator = new RecursiveArrayIterator($array);
$recursiveIteratorIterator = new RecursiveIteratorIterator($recursiveIterator);
foreach($recursiveIteratorIterator as $key => $value) {
- echo "깊이: " . $recursiveIteratorIterator->getDepth() . PHP_EOL;
- echo "키: " . $key . PHP_EOL;
- echo "값: " .$value .
-
-
코드 복사 (3)사용FilterIterator迭代器实现过滤
-
-
class EvenFilterIterator 확장 FilterIterator { - /**
- * 짝수 값만 허용
- *
- * @return bool
- */
- public function accept()
- {
- // 실제 반복자를 가져옵니다
- $iterator = $this->getInnerIterator();
-
- // 현재 키를 가져옵니다
- $ key = $iterator->key();
-
- // 짝수 키 확인
- if ($key % 2 == 0) {
- return true;
- }
-
- false 반환;
- }
- }
$array = array(
- 0 => "안녕하세요",
- 1 => " Everybody Is",
- 2 => "나는",
- 3 => "Amazing",
- 4 => "The",
- 5 => "Who",
- 6 => "Doctor",
- 7 => "Lives"
- );
// 배열에서 반복자 만들기
- $ iterator = new ArrayIterator($array);
// FilterIterator 만들기
- $filterIterator = new EvenFilterIterator($iterator);
foreach ($filterIterator as $key => $value) {
- echo $key .': '. $ 값 . PHP_EOL;
- }
- ?>
-
复代码
(4)RegexIterator迭代器
-
-
- // RecursiveDirectoryIterator 만들기
- $directoryIterator = new RecursiveDirectoryIterator("./" );
// 재귀적으로 반복하기 위한 RecursiveIteratorIterator 생성
- $recursiveIterator = new RecursiveIteratorIterator($directoryIterator);
// Createa *Iterator*.php 파일에 대한 필터
- $regexFilter = new RegexIterator($recursiveIterator, '/(.*?)Iterator(.*?).php$/');
- < p>// 반복
- foreach ($regexFilter as $key => $file) {
- /* @var SplFileInfo $file */
- echo $file->getFilename() . PHP_EOL;
- }
-
-
复主代码
功能:找到所有的php文件
(4)LimitItertor迭代器,imageSQL中的LIMIT
-
-
// 배열 정의
- $array = array(
- 'Hello',
- 'World ',
- '어떻게',
- '지금',
- '너',
- '뭐하고 있어?'
- );
// 만들기 반복자
- $iterator = new ArrayIterator($array);
// 처음 2개의 요소를 가져오기 위해 제한 반복자를 만듭니다
- $limitIterator = new LimitIterator($ iterator, 0, 2);
// 반복
- foreach ($limitIterator as $key => $value) {
- echo $key .': '. $ 값 . PHP_EOL;
- }
-
复代码
6. 관찰자 모드(관찰자)
관찰자 패턴의 핵심은 애플리케이션이 특정 이벤트가 발생할 때 이를 트리거하는 콜백을 등록한다는 것입니다.
-
-
/** - * 이벤트 클래스
- *
- * 이 클래스를 사용하면 주어진 이벤트에 대해
- * 호출(FIFO)되는 콜백을 등록할 수 있습니다.
- */
- 수업 이벤트 {
- / **
- * @var array 이벤트의 다차원 배열 => 콜백
- */
- static protected $callbacks = array();
-
- /**
- * 콜백 등록
- *
- * @param string $eventName 트리거 이벤트 이름
- * @param mix $callback Event_Callback 또는 Closure의 인스턴스
- */
- 정적 공개 함수 RegisterCallback($eventName, $callback)
- {
- if (!($callback instanceof Event_Callback) && !($callback instanceof Closure)) {
- throw new Exception("잘못된 콜백!");
- }
-
- $eventName = strtolower($eventName);
-
- self::$callbacks[$eventName][] = $callback;
- }
-
- /**
- * 이벤트 트리거
- *
- * @param string $eventName 트리거할 이벤트 이름
- * @param mix $data 콜백으로 보낼 데이터
- */
- static public 함수 트리거($eventName, $data)
- {
- $eventName = strtolower($eventName);
-
- if (isset(self::$callbacks[$eventName])) {
- foreach (self::$callbacks[$eventName] as $callback) {
- self::callback($callback, $data);
- }
- }
- }
-
- / **
- * 콜백 수행
- *
- * @param mix $callback Event_Callback 또는 Closure의 인스턴스
- * @param mix $data 콜백으로 전송된 데이터
- */
- 정적 보호 함수 콜백($callback, $data)
- {
- if ($callback instanceof Closure) {
- $callback($data);
- } else {
- $callback->run($data);
- }
- }
- }
/**
- * 이벤트 콜백 인터페이스
- *
- * 클로저를 사용하지 않으려는 경우
- * 대신 this를 확장하는 클래스를 정의할 수 있습니다
- *. run 메소드는
- * 이벤트가 트리거될 때 호출됩니다.
- */
- interface Event_Callback {
- 공용 함수 run($data);
- }
/**
- * 로거 콜백
- */
- class LogCallback은 Event_Callback을 구현합니다. {
- 공개 함수 run($data)
- {
- echo "로그 데이터" .
- var_dump($data);
- }
- }
- Event::registerCallback('save', new LogCallback());
// 캐시 지우기 콜백을 클로저로 등록
- 이벤트::registerCallback('save', function ($data) {
- echo "캐시 지우기" . PHP_EOL;
- var_dump($data);
- });
- < ;p>class MyDataRecord {
- public function save()
- {
- // 데이터 저장
-
- // 저장 이벤트 트리거
- Event::trigger('save', array ("Hello", "World"));
- }
- }
// 새 데이터 레코드 인스턴스화
- $data = new MyDataRecord();
- $data->save(); // '저장' 이벤트가 여기서 발생합니다
-
코드 복사
7. 의존성 주입 모드
종속성 주입 패턴을 사용하면 클래스가 이 동작을 사용하여 이 클래스에 종속성을 주입할 수 있습니다.
-
-
/**
- * 로그 클래스
- */
- 클래스 로그 {
- /**
- * @var Log_Engine_Interface
- */
- protected $engine = false;
-
- /**
- * 로그에 이벤트 추가
- *
- * @param string $message
- */
- 공개 함수 add($message)
- {
- if (!$this->engine) {
- throw new Exception('로그를 쓸 수 없습니다. 엔진이 설정되지 않았습니다.');
- }
-
- $data['datetime'] = time();
- $data[' message'] = $message;
-
- $session = Registry::get('session');
- $data['user'] = $session->getUserId();
-
- $this->engine->add($data);
- }
-
- /**
- * 로그 데이터 저장 엔진 설정
- *
- * @param Log_Engine_Interface $Engine
- */
- 공개 함수 setEngine(Log_Engine_Interface $engine)
- {
- $this->engine = $engine;
- }
-
- /**
- * 데이터 스토리지 엔진 검색
- *
- * @return Log_Engine_Interface
- */
- 공개 함수 getEngine()
- {
- return $this- >engine;
- }
- }
interface Log_Engine_Interface {
- /**
- * 로그에 이벤트 추가
- *
- * @param string $message
- */
- 공용 함수 add(array $data);
- }
class Log_Engine_File은 Log_Engine_Interface를 구현합니다. {
- /**
- * 로그에 이벤트 추가
- *
- * @param string $message
- */
- 공용 함수 add(array $data)
- {
- $line = '[' .data('r', $data['datetime']). '] ' .$data['message'] ' 사용자: ' .$data['user'] . 🎜>
- $config = Registry::get('site-config');
-
- if (!file_put_contents($config['location'], $line, FILE_APPEND)) {
- throw new Exception("파일에 쓰는 동안 오류가 발생했습니다.");
- }
- }
- }
$engine = new Log_Engine_File();
$log = new Log();
- $log->setEngine($engine);
// 레지스트리에 추가
- Registry::add($log);
-
-
코드 복사
종속성 주입에는 팩토리 모드가 필요하지 않습니다. 일본 등을 이해해야 합니다. 각기 다른 스토리지 엔진에 대한 지식이 필요합니다. 이는 로깅 클래스를 사용하는 모든 개발자가 자신의 스토리지 엔진을 추가하고 인터페이스를 간단하게 구성할 수 있음을 의미합니다.
8. 모델-뷰-컨트롤러
MVC 패턴이라고도 알려진 Model-View-Controller는 애플리케이션의 서로 다른 세 가지 수준 간의 관계를 설명하는 방법입니다.
모델-데이터 계층 모든 출력 데이터는 모델에서 나옵니다. 데이터베이스, 웹 서비스 또는 파일일 수 있습니다.
뷰 표현 계층은 모델에서 데이터를 꺼내 사용자에게 출력하는 역할을 담당합니다.
컨트롤러-애플리케이션 플로우 레이어는 사용자의 요청에 따라 해당 모델을 호출하여 요청된 데이터를 검색한 후, 뷰를 호출하여 작업 결과를 사용자에게 표시합니다.
일반적인 MVC 아키텍처 다이어그램:
9. 패턴의 이해 패턴은 많은 일반적인 문제에 대한 최고의 솔루션입니다.
당신이 관심을 가질 만한 기사:
php 디자인 패턴: 싱글턴 모드, 팩토리 모드, 관찰자 모드-
PHP 디자인 패턴 예제에 대한 심층 설명-
php 디자인 패턴 예제 명령 패턴-
PHP 디자인 패턴 예제 관찰자 패턴(2)-
PHP 디자인 패턴 예제의 관찰자 패턴-
PHP 디자인 패턴의 팩토리 패턴 예시-
PHP 디자인 패턴 예제 싱글턴 패턴-
PHP 디자인 패턴 예시 옵저버 패턴-
PHP 디자인 패턴 팩토리 패턴 예제 코드-
PHP 디자인 패턴의 싱글턴 모드 예제 코드-
팩토리 패턴과 싱글톤 패턴 소개, PHP 공통 디자인 패턴-
PHP 디자인 패턴 중 싱글턴 패턴 배우기-
PHP에서 일반적으로 사용되는 세 가지 디자인 패턴에 대한 연구 노트-
PHP 디자인 패턴의 싱글턴 패턴 학습-
|