마 젠토 2-매직 게터를 사용하거나 피하는 좋은 방법?


21

Varien_Object(M1)과 DataObject(M2)의 매직 게터 는 일반적인 관행이지만 Magento 2에서는 사용이 잘못되었습니다.

좋은:

  • 읽기 쉬운 쓰기

나쁜

의문

Magento 2에는 두 가지 새로운 방법이 있습니다.

  • getDataByKey($key)
  • getDataByPath($path)

여전히 사용 getData($key)하거나 마법 게터를 사용해야 할 이유가 있습니까?


편집하다:

@Vinai 감사합니다. @method내 접근 방식이 상당히 다르기 때문에 방법을 언급하지 않았습니다 .

IDE에만 도움이되지만 다른 것에는 영향을 미치지 않습니다.

루프 외부에서 배열 크기를 가져 오는 (int)대신 intval()작은 배열로 변환하는 것과 같은 "미세 최적화"인 여러 mergedf PR이 있습니다 .

반면에

  1. 마리우스가 묘사 한 것처럼 "오버 헤드"가있는 마법의 게터 ....

    strtolower(trim(preg_replace('/([A-Z]|[0-9]+)/', "_$1", $name), '_'));
  2. getData($key) mehtods는 2-3 추가 검사를해야합니다 ...

    • if ('' === $key) {
    • if (strpos($key, '/')) {
    • if ($index !== null) {

자체 코드의 경우 실제 방법을 선호하는 데 전적으로 동의하지만 같은 경우에는 불가능합니다 ... 예 : 사용자 정의 이벤트를 만들었습니다 ...

$value = $observer->getVar_1();
$value = $observer->getData('var_1');
$value = $observer->getDataByKey('var_1');

3을 사용하는 /** @var some $value */것이 가장 좋습니다. (?)


1
코드 분석 도구가 존재하지 않는 메소드에 대해 불평하지 않도록 클래스 doc 블록에 메소드를 추가 할 수 있습니다. 또한 키에 숫자를 사용하는 것은 나쁜 습관이므로 여기에 "나쁜"것으로 표시되어서는 안됩니다.
릴리 Bergonzat

답변:


20

위의 질문은 마술 방법 대 getDataByKey또는 getDataByPath. 세 번째 옵션도 있다고 생각하며 실제 getter 및 setter 메소드를 구현하고 있습니다.

getData*방법은 모두 형식 유추가 작동하려면 주석을 달아야한다는 단점이 있습니다.
일반적으로 호출 /* @var string $foo */위의 주석 으로 수행됩니다 getData*.
데이터 유형이 데이터를 호출하는 클래스가 아닌 데이터를 포함하는 클래스에서 선언되어야하기 때문에 약간 냄새가납니다 getData*.
그 이유는 데이터가 변경되면 모든 getData*콜 사이트가 아니라 클래스가 업데이트 될 가능성이 가장 높기 때문 입니다.
그렇기 때문에 실제 메서드가 getData*접근 자를 사용하는 것보다 유지 관리 성이 향상되는 것 같습니다 .

따라서 유지 관리 성과 빠른 구현 (코드 작성이 적음) 사이의 균형을 유지한다고 생각합니다.

운 좋게도 오늘날 IDE는 실제로 getter 및 setter 구현을 작성하는 데 능숙하므로 인수가 더 이상 적용되지 않습니다.

위의 질문에서 빠진 마술 게터와 세터에 대한 또 하나의 주장은 그것들을위한 플러그인을 만들 수 없다는 것입니다.

주제에 추가 할 수있는 유일한 다른 가치는 @method실제 방법을 구현하는 것이 어떤 이유로 문제가 아닌 경우 주석 을 사용하거나 사용하지 않는 이유를 수집하는 것입니다.

찬성

  • @method주석 진짜 getter 및 setter 구현에 비해 쓰기에 좀 덜 코드입니다. IDE가 액세서 메소드를 생성하는 데 능숙하기 때문에 현재로서는 거의 사실이 아니므로 더 이상 실제 이점이 아닙니다.

단점

  • 일이 잘못되기 쉽습니다.
    • 주석은 주석이며 코드가 진화 할 때 쉽게 사용되지 않지만 주석은 업데이트되지 않습니다. 실제 방법이 더 강력합니다.
    • 인터프리터 오류없이 다른 유형의 서명으로 여러 주석을 추가 할 수 있습니다. 정적 코드 분석 동작이 정의되지 않아 추적하기 어려운 미묘한 버그로 이어질 수 있습니다.
    • @method주석과 이름이 같은 실제 메소드가 모두 존재하는 경우, 주석 유형 서명은 정적 코드 분석 중에 실제 메소드를 대체합니다. 이는 PHP 인터프리터와는 반대입니다. 이것은 다시 쉽게 미묘한 버그로 이어질 수 있습니다.

위의 이유로 나는 @method주석을 피할 수 있다면 개인적으로 주석을 사용하지 않습니다 .
오래 살려는 코드의 경우 실제 getter 및 setter 메소드를 구현합니다. 유지 보수성 향상은 IDE를 생성하여 IDE를 생성하는 노력의 가치가 있습니다.

스파이크 중 더 실험적인 코드 또는 모듈의 간단한 구현 세부 정보를 위해서는 getData*게으른 메서드도 사용 합니다.


좋은 요약입니다. 비나이 감사합니다. 그것은 내가 실제로 요청한 것보다 더 많은 답변을 제공합니다.
sv3n

1

getData*방법은 모두 형식 유추가 작동하려면 주석을 달아야한다는 단점이 있습니다.

일반적으로 호출 /*@var string $foo */위의 주석 으로 수행됩니다 getData*. getData *를 호출하는 클래스가 아니라 데이터를 포함하는 클래스에서 데이터 유형을 선언해야하기 때문에 약간 냄새가납니다.

그 이유는 데이터가 변경되면 모든 getData*콜 사이트가 아니라 클래스가 업데이트 될 가능성이 가장 높기 때문 입니다. 그렇기 때문에 실제 메소드가 getData * 접근자를 사용하는 것과 비교하여 유지 보수성을 향상시키는 것으로 생각합니다.

그렇습니다. 냄새가 나지만 피할 수 있습니다. 나는 이것이 매우 일반적인 코드라고 생각하며 종종 제안합니다.

/** @var Foo $product */
$product = $model->getProduct()
if ($product->getId()) {
    $product->doSomething();
}

문제는 반환 값이 호출 가능한 메서드 의 유형이라고 추측 하는 것 입니다.FoogetId()

유지 관리를 위해 변수 유형을 가정하고 InvalidArgumentException?

$product = $model->getProduct()
if ($product instanceof Foo && $product->getId()) {
    $product->doSomething();
}

또한 $model->getProduct()리턴 유형이 다른 경우 정적 코드 분석을 수정 Foo|false합니다. 첫 번째 경우 doSomething()는 가능한 전화 에 대해 불평 할 것 false입니다.

당사 사이트를 사용함과 동시에 당사의 쿠키 정책개인정보 보호정책을 읽고 이해하였음을 인정하는 것으로 간주합니다.
Licensed under cc by-sa 3.0 with attribution required.