PHP의 특징 – 실제 사례/베스트 프랙티스가 있습니까?
특성은 PHP 5.4에 추가된 가장 큰 기능 중 하나입니다.로깅, 보안, 캐싱 등의 일반적인 용도로 사용되는 수평 코드 재사용과 같은 특성 뒤에 있는 구문을 이해하고 있습니다.
하지만, 저는 아직도 제 프로젝트에서 특성을 어떻게 활용해야 할지 모르겠습니다.
특성을 이미 사용하고 있는 오픈 소스 프로젝트가 있습니까?특성을 사용하여 아키텍처를 구성하는 방법에 대한 좋은 기사/읽기 자료가 있습니까?
인정되고 있는 Good/Best Practice를 학습하기 위해서는 당분간 특성을 가진 언어를 조사해야 할 것 같습니다.제 현재 Atribute에 대한 의견은 동일한 기능을 공유하는 다른 클래스에서 복제해야 하는 코드에만 사용해야 한다는 것입니다.
Logger 특성의 예:
interface Logger
{
public function log($message, $level);
}
class DemoLogger implements Logger
{
public function log($message, $level)
{
echo "Logged message: $message with level $level", PHP_EOL;
}
}
trait Loggable // implements Logger
{
protected $logger;
public function setLogger(Logger $logger)
{
$this->logger = $logger;
}
public function log($message, $level)
{
$this->logger->log($message, $level);
}
}
class Foo implements Logger
{
use Loggable;
}
그러고 나서 (데모)
$foo = new Foo;
$foo->setLogger(new DemoLogger);
$foo->log('It works', 1);
특성을 사용할 때 고려해야 할 중요한 점은 특성을 클래스에 복사하는 코드 조각에 불과하다는 것입니다.예를 들어 메서드의 가시성을 변경하려고 하면 충돌이 발생하기 쉽습니다.
trait T {
protected function foo() {}
}
class A {
public function foo() {}
}
class B extends A
{
use T;
}
위의 경우 오류(데모)가 발생합니다.마찬가지로 특성으로 선언된 메서드 중 이미 using 클래스에 선언된 메서드는 클래스에 복사되지 않습니다.
trait T {
public function foo() {
return 1;
}
}
class A {
use T;
public function foo() {
return 2;
}
}
$a = new A;
echo $a->foo();
는 2(표준)를 인쇄합니다.오류를 찾기 어렵기 때문에 피하고 싶은 것들입니다.또한 이를 사용하는 클래스의 속성이나 메서드에 영향을 미치는 특성(예:
class A
{
use T;
protected $prop = 1;
protected function getProp() {
return $this->prop;
}
}
trait T
{
public function foo()
{
return $this->getProp();
}
}
$a = new A;
echo $a->foo();
동작(데모)하지만, 그 특성이 A와 밀접하게 결합되어 수평 재사용에 대한 전체 개념이 없어졌습니다.
인터페이스 분리 원칙을 따르면 다수의 작은 클래스 및 인터페이스가 생성됩니다.따라서 Features는 (구조적인 의미에서) 오브젝트를 구성하지 않고 크로스커팅과 같은 문제에 이상적인 후보가 됩니다.위의 Logger 예에서는 특성이 완전히 격리되어 있습니다.그것은 구체적인 계급에 의존하지 않는다.
(이 페이지의 다른 부분과 같이) 집약/구성을 사용하여 동일한 클래스를 얻을 수 있지만 집약/구성을 사용할 경우 프록시/대리자 메서드를 각 클래스에 수동으로 추가해야 로그를 기록할 수 있다는 단점이 있습니다.특성 덕분에 보일러 플레이트를 한 곳에 보관하고 필요에 따라 선택적으로 적용할 수 있습니다.
주의: 특성이 PHP의 새로운 개념이기 때문에 위에서 설명한 모든 의견은 변경될 수 있습니다.아직 제가 직접 그 컨셉을 평가할 시간이 많이 없었어요.하지만 생각해 볼 만한 일이 있었으면 좋겠어요.
제 개인적인 의견은 클린 코드를 작성할 때 특징에 대한 적용은 실제로 거의 없다는 것입니다.
특성을 사용하여 코드를 클래스로 해킹하는 대신 컨스트럭터 또는 세터를 통해 종속성을 전달하는 것이 좋습니다.
class ClassName {
protected $logger;
public function __construct(LoggerInterface $logger) {
$this->logger = $logger;
}
// or
public function setLogger(LoggerInterface $logger) {
$this->logger = $logger;
}
}
특성을 사용하는 것보다 더 나은 이유는 특성에 대한 하드 커플링을 제거함으로써 코드가 훨씬 더 유연하기 때문입니다.예를 들어, 이제 다른 로거 클래스를 통과하기만 하면 됩니다.이를 통해 코드를 재사용하고 테스트할 수 있습니다.
:) 저는 무엇으로 무엇을 해야 하는지에 대해 이론을 세우고 토론하는 것을 좋아하지 않습니다.이 경우에는 특징이 있습니다.내가 뭘 위해 유용한지 보여줄게 넌 그걸 배우거나 무시해도 돼
특징 - 전략을 적용하기에 매우 좋습니다.즉, 전략 설계 패턴은 동일한 데이터를 다르게 처리(필터링, 정렬 등)하려는 경우에 유용합니다.
예를 들어, 일부 기준(브랜드, 사양 등)을 기준으로 필터링하거나 다른 방법(가격, 레이블 등)으로 정렬할 제품 목록이 있습니다.서로 다른 정렬 유형(숫자, 문자열, 날짜 등)에 대해 서로 다른 함수를 포함하는 정렬 특성을 생성할 수 있습니다.그런 다음 이 특성을 제품 클래스(예제 참조)뿐만 아니라 유사한 전략이 필요한 다른 클래스(일부 데이터에 숫자 정렬 적용 등)에서도 사용할 수 있습니다.
시험해 보세요:
<?php
trait SortStrategy {
private $sort_field = null;
private function string_asc($item1, $item2) {
return strnatcmp($item1[$this->sort_field], $item2[$this->sort_field]);
}
private function string_desc($item1, $item2) {
return strnatcmp($item2[$this->sort_field], $item1[$this->sort_field]);
}
private function num_asc($item1, $item2) {
if ($item1[$this->sort_field] == $item2[$this->sort_field]) return 0;
return ($item1[$this->sort_field] < $item2[$this->sort_field] ? -1 : 1 );
}
private function num_desc($item1, $item2) {
if ($item1[$this->sort_field] == $item2[$this->sort_field]) return 0;
return ($item1[$this->sort_field] > $item2[$this->sort_field] ? -1 : 1 );
}
private function date_asc($item1, $item2) {
$date1 = intval(str_replace('-', '', $item1[$this->sort_field]));
$date2 = intval(str_replace('-', '', $item2[$this->sort_field]));
if ($date1 == $date2) return 0;
return ($date1 < $date2 ? -1 : 1 );
}
private function date_desc($item1, $item2) {
$date1 = intval(str_replace('-', '', $item1[$this->sort_field]));
$date2 = intval(str_replace('-', '', $item2[$this->sort_field]));
if ($date1 == $date2) return 0;
return ($date1 > $date2 ? -1 : 1 );
}
}
class Product {
public $data = array();
use SortStrategy;
public function get() {
// do something to get the data, for this ex. I just included an array
$this->data = array(
101222 => array('label' => 'Awesome product', 'price' => 10.50, 'date_added' => '2012-02-01'),
101232 => array('label' => 'Not so awesome product', 'price' => 5.20, 'date_added' => '2012-03-20'),
101241 => array('label' => 'Pretty neat product', 'price' => 9.65, 'date_added' => '2012-04-15'),
101256 => array('label' => 'Freakishly cool product', 'price' => 12.55, 'date_added' => '2012-01-11'),
101219 => array('label' => 'Meh product', 'price' => 3.69, 'date_added' => '2012-06-11'),
);
}
public function sort_by($by = 'price', $type = 'asc') {
if (!preg_match('/^(asc|desc)$/', $type)) $type = 'asc';
switch ($by) {
case 'name':
$this->sort_field = 'label';
uasort($this->data, array('Product', 'string_'.$type));
break;
case 'date':
$this->sort_field = 'date_added';
uasort($this->data, array('Product', 'date_'.$type));
break;
default:
$this->sort_field = 'price';
uasort($this->data, array('Product', 'num_'.$type));
}
}
}
$product = new Product();
$product->get();
$product->sort_by('name');
echo '<pre>'.print_r($product->data, true).'</pre>';
?>
마지막으로 악세사리 등의 특징(데이터 변경에 사용할 수 있는 것)에 대해 생각합니다.유지보수가 용이하고 코드가 짧고 깔끔하기 위해 수업에서 제외되어 한 곳에 보관될 수 있는 유사한 방법 및 특성.
Features는 Magento e커머스 플랫폼용 확장 기능을 개발할 때 공통적인 문제를 해결하기 때문에 매우 기쁘게 생각합니다.이 문제는 확장을 통해 코어 클래스(사용자 모델 등)에 기능을 추가할 때 발생합니다.이를 수행하려면 XML 구성 파일을 통해 Zend 자동 로더를 포인팅하여 확장자에서 사용자 모델을 사용하고 새 모델이 코어 모델을 확장하도록 합니다.(예) 그러나 두 확장자가 동일한 모델을 덮어쓰면 어떻게 됩니까?"경주 조건"이 나타나고 하나만 로드됩니다.
현재 해결책은 확장자를 편집하여 다른 확장자의 모델 오버라이드 클래스를 체인으로 확장한 다음 상속 체인이 작동하도록 확장 구성을 올바른 순서로 로드하는 것입니다.
이 시스템에서는 오류가 자주 발생하므로 새 확장을 설치할 때 충돌을 확인하고 확장을 편집해야 합니다.이는 번거로운 일이며 업그레이드 프로세스가 중단됩니다.
저는 Features를 사용하는 것이 이러한 짜증나는 모델 오버라이드 "인종 조건" 없이 동일한 것을 달성할 수 있는 좋은 방법이라고 생각합니다.여러 개의 Features가 동일한 이름의 메서드를 구현하면 충돌이 발생할 수 있지만, 대부분의 경우 단순한 네임스페이스 규칙과 같은 것이 이 문제를 해결할 수 있다고 생각합니다.
TL;DR 특성은 Magento와 같은 대형 PHP 소프트웨어 패키지를 위한 확장/모듈/플러그인을 만들 때 유용할 수 있다고 생각합니다.
다음과 같은 읽기 전용 개체의 특성을 가질 수 있습니다.
trait ReadOnly{
protected $readonly = false;
public function setReadonly($value){ $this->readonly = (bool)$value; }
public function getReadonly($value){ return $this->readonly; }
}
이 특성이 사용되는지 여부를 감지하고 데이터베이스, 파일 등에 해당 개체를 작성해야 하는지 여부를 결정할 수 있습니다.
언급URL : https://stackoverflow.com/questions/7892749/traits-in-php-any-real-world-examples-best-practices
'programing' 카테고리의 다른 글
Eclipse에서 테스트하는 동안 -D 시스템 속성을 통과하려면 어떻게 해야 합니까? (0) | 2022.11.06 |
---|---|
Android 목록 기본 설정: 요약을 선택한 값으로 지정하시겠습니까? (0) | 2022.11.06 |
개체 배열에서 개체 속성별로 항목을 찾으려면 어떻게 해야 합니까? (0) | 2022.11.06 |
MySQL 구문 혼동 - 단일 행 삽입을 위한 간단한 데이터 병합 (0) | 2022.11.06 |
로컬 호스트 PHPmyAdmin에 저장 프로시저를 만들고 있는데 찾을 수 없는 오류가 있습니다. (0) | 2022.11.06 |