모든 플러그인을 클래스에 캡슐화해야합니까?


28

플러그인을 개발할 때 네임 스페이스 충돌을 피하기 위해 함수를 클래스로 그룹화해야합니까?

클래스를 사용하면 PHP의 성능 오버 헤드가 발생합니까?

성능 저하가있는 경우 함수 이름을 미리 고정해야합니까?


8
아마도 WordPress 질문보다 PHP 질문이 더 많을 것입니다. 이 Stackoverflow 질문이 귀하의 질문에 적합한 지 확인하십시오.
t31os

답변:


24

플러그인을 개발할 때 네임 스페이스 충돌을 피하기 위해 함수를 클래스로 그룹화해야합니까?

예, 그러나 그것은 사소한 논쟁 중 하나 일뿐입니다. 사실 그것은 OOAD 클래스의 "진정한"특성이 아닙니다 .

클래스를 사용하면 PHP의 성능 오버 헤드가 발생합니까?

아닙니다. 잘못된 디자인 및 / 또는 잘못된 작성된 코드 또는 조기 최적화는 실제 언어 기능보다 훨씬 많은 성능 문제를 발생시킵니다.

성능 저하가있는 경우 함수 이름을 미리 고정해야합니까?

작성된대로 성능 저하가 없습니다. 잘못 작성된 코드는 더 많은 코드 줄을 가지고 있지만 나쁜 일을 강요하지 않는 좋은 작성된 코드보다 성능이 더 뛰어납니다.


결론 :

플러그인 클래스를 다르게 사용할 수 있습니다. 그것들을 사용하여 일종의 네임 스페이스를 가지고 전역 함수에 "그냥"사용할 수 있습니다. 가장 직접적인 형태는 정적 클래스 함수이며, 다음 코드 예는 먼저 전역 함수와 전역 정적 클래스 함수를 모두 보여줍니다.

/* global function */
function myplug_hook()
{
}

add_filter('the_hook', 'myplug_hook');


/* global static function */
class myplug
{
    public static function hook()
    {
    }
}

add_filter('the_hook', 'myplug::hook');

이것은 단일 후크에 더 많이 입력해야 함을 보여주는 작은 예입니다. 또한 네임 스페이스의 작동 방식을 보여줍니다. 단일 클래스 이름을 쉽게 바꾸어 모든 정적 함수의 이름을 바꾸고 오 탐지 myplug::myplug_인해 더 어려울 수있는 검색 및 바꾸기 를 수행 할 수 있습니다 . 그러나 결국 큰 차이는 없습니다.

핵심은 다음과 같습니다. 정적 클래스 함수 Docs전역 함수 Docs와 크게 다릅니다 .

그리고이 예제는 다음과 같이 표시합니다. 이름 간격은 훌륭하지만 worpdress에서는 이름 간격이 후크를 사용하여 중지됩니다. 콜백 함수는 하드 인코딩되어 클래스 (기본 이름, 클래스 이름의 한 장소)를 사용한 이름 공간의 이점이 없습니다. 후크 이름에 대한 워드 프레스로 코드를 개입시킬 때 도움이됩니다.

실제 이점은 실제 클래스 인스턴스와 비 정적 함수를 사용하는 것으로 시작됩니다. 이는 OO 원칙을 사용하기 시작하고 코드를 간소화 할 수있는 이점이 있습니다. 정적 클래스 함수는 실제로 솔루션보다 문제가됩니다.

그렇다면 그것은 단지 구문 설탕 이상의 것입니다.

요점은 다음과 같습니다. 쉽게 처리하고 유지할 수있는 코드를 작성하는 데 도움이되는 작업을 수행하십시오. 성능을 과대 평가하지 마십시오. 일반적인 실수입니다. 더 중요한 것은 읽고 이해하기 쉽고 필요한 기능 만 수행하는 코드를 작성하는 것입니다. 아마이 질문과 답변이 다음 맥락에서 더 큰 그림에 도움이 될 것입니다. Multiple Custom Metabox Help .

더 작은 플러그인으로도 한 가지 일반적인 접근 방식은 정적 도우미 함수를 사용하여 플러그인을 인스턴스화하고 나머지는 플러그인 인스턴스 내에 있습니다. 이는 주요 플러그인 로직을 캡슐화하는 데 도움이되고 후크를 사용하여 네임 스페이스를 사용하는 것뿐만 아니라 표준 전역 기능으로는 불가능한 후크간에 개인 구성원을 재사용 할 수 있습니다. 다음 코드 예제는 패턴을 보여줍니다.

<?php
/** Plugin Headers ... */

return MyPlugin::bootstrap(); 

class MyPlugin
{
    /** @var MyPlugin */
    static $instance;
    static public function bootstrap() {
        if (NULL === self::$instance) {
            self::$instance = new __CLASS__;
        }
        return self::$instance;
    }
    # ...
}

이것은 기본 플러그인 파일에 사용하는 일반적인 패턴입니다. 한편으로 플러그인 클래스는 워드 프레스에 대한 플러그인을 나타내며, 한편으로는 객체 지향 패러다임을 사용하여 자신의 코드에 대해 객체 지향 패러다임을 사용할 수 있습니다. 그것은 일종의 컨트롤러이며, 전체 wordpress API를 요청으로 인터페이스합니다.

예제에서 볼 수 있듯이 플러그인 인스턴스가 생성됩니다. 이를 통해 실제 플러그인을 초기화하기 위해 Constructor Docs ( __construct) 와 같은 알려진 공통점을 사용할 수 있습니다 .

# ...
class MyPlugin
{
    # ...
    public function __construct()
    {
        add_filter('the_hook', array($this, 'hook'));
    }

    public function hook()
    {
    }
    # ...
}

후크가 등록 될 때이 플러그인 객체는 이미 디자인의 이점을 얻습니다. 구체적인 플러그인 classname 에 대해 실제 후크 함수를 하드 코딩하는 것을 중단했습니다 . 콜백을 위해 클래스를 객체 인스턴스에 바인딩했기 때문에 가능합니다. 사운드 복잡 단지 말은 : $this 입니다 플러그인. 후크 콜백에서 사용할 수 있습니다. 클래스 메소드 등록 을 후크 콜백으로 비교 . .

이 패턴을 사용하면 워드 프레스와의 인터페이스가 더 쉬워집니다. 인젝션은 후크의 이름과 제공하는 데이터로 줄어 듭니다. 그런 다음이 플러그인 클래스에 직접 구현을 시작하거나 이에 대한 구현을 리팩토링 할 수 있으므로 워드 프레스에 대해 플러그인 인터페이스를 정의하기위한 최소한의 플러그인 클래스에만 코드를 삽입하고 worpdress를 제외하고 일반적인 논리를 유지하십시오. 이것은 재미가 시작되는 곳이며 아마도 각 플러그인 작성자가 장기적으로 달성하고자하는 것입니다.

따라서 worpdress로 프로그래밍하지 말고 반대하십시오. worpdress는 매우 유연하기 때문에 프로그래밍 할 인터페이스가 일반적이거나 설명하기 쉽지 않습니다. 기본 플러그인 클래스가이 역할을 수행 할 수 있으므로 코드에 대한 유연성이 향상되어 코드가 더 쉽고 성능이 향상됩니다.

따라서 이름 간격에 대한 이점 이상의 것이 있습니다. 내가 줄 수있는 가장 좋은 제안은 다음과 같습니다. 느슨하게 할 것이없고 새로운 것들만 발견 할 수 있습니다.

플러그인의 호환성을 유지하면서 워드 프레스에 대한 몇 가지 주요 업데이트를 전달한 후에 차이가있을 수 있습니다.

주의 사항 : 플러그인이 워드 프레스와 직접 통합되어 작업을 수행하는 경우 하나 또는 두 개의 공용 기능을 사용하는 것이 더 적합 할 수 있습니다. 작업에 적합한 도구를 사용하십시오.


1
정적 클래스 함수가 ​​전역 함수와 다르지 않고 네임 스페이스 충돌을 방지하는 것이 목적이라면 플러그인을 클래스로 작성하는 것으로 전환해야 할 필요성을 아직 이해하지 못했습니다. 또한 도우미 부트 스트랩 기능이 혼란 스럽습니다. 왜 새 객체를 $ new_object = new MyClass ();로 선언하지 않겠습니까?
AlxVallejo

@ AlxVallejo : 네임 스페이스만으로는 진정한 필요성이 없습니다 (답변에 쓴 것처럼 정적 클래스 메소드는 전역 함수와 거의 동일합니다). 따라서 자신 만의 네임 스페이스를 지정할 수 있습니다 (PHP 5.3 이전의 네임 스페이스 지정). 그래서 당신은 그것을 완벽하게 알았습니다. 정적 부트 스트랩 기능과 유사합니다. 기술적으로는 필요하지 않으며 간단 return $myPlugin = new MyPlugin(); 합니다. 그러나 더 큰 그림을 보려면 간단한 새로운 것만으로는 충분하지 않을 있습니다 . WordPress 플러그인을 비교하십시오 . .
hakre

9

클래스 VS 함수 세트


공연

일반 : Afaik, 클래스와 함수 세트 사이의 "성능"에는 차이가 없습니다.

세부 묘사:

  • 이 당신이 질문의 경우 큰 차이가있어 function_exists()비교 class_exists()하면 기능 (~ 1.800 (?) WP 코어에서) 많이 가지고 일반적으로 대 클래스 (~ 100 (?) WP 코어에서). 따라서 "플러그 가능"하게 만들고 존재에 의문을 갖는 것은 실행 시간의 차이입니다.
  • 클래스는 함수 세트에 비해 하나의 장점을 제공합니다. 필요하지 않은 요청에서 함수를 호출하지 않아도 훨씬 쉽게 호출 할 수 있습니다. 클래스에 대한 조건부 검사 만 수행하면되고 모든 기능에 대해 수행하면 안됩니다. 따라서 모든 페이지로드에서 필요하지 않고 많은 if / else 문을 호출하지 않아도되는 경우 함수가 "성능이 우수합니다".

아키텍처-작동 방식 :

함수 집합 : 일반적으로 함수는 호출하는 행에서 실행됩니다. 따라서 물건을 호출 할 때마다 한 번 이상 호출해야하는 경우 다시 작성해야합니다.

수업 : 수업에 다른 접근법이 있습니다. 함수 집합에 가장 가까운 클래스는 "factory"클래스 ( wikipedia / google )입니다. Imo 함수 세트와 거의 동일하지만 클래스로 캡슐화됩니다. 그러나 클래스의 다른 "유형"도 있습니다. 예를 들어, 추상 클래스 또는 부모 클래스 클래스를 작성하여 하위 클래스로 확장 할 수 있습니다. 실제 예에서 : 정적 텍스트 필드를 작성하는 클래스가 있다고 가정 해 봅시다. 당신의에서 __construct()기능 당신은 "left_column", "right_column"& "footer_field"와 같은 일련의 시나리오가 있습니다. 그런 다음 $text_field = new TextFieldClass();클래스를 인스턴스화하는 것과 같은 것을 호출합니다 . 그리고 나중에 당신은 단순히 전화 $text_field->add( $case => 'left_column', 'case' => 'foo text' );$text_field->add( $case => 'footer_field', 'case' => 'bar text' );. 그런 다음 클래스를 인스턴스화 할 때 모든 조건부 및 기타 작업이 이미 수행되었으며 텍스트 필드를 작성할 때 두 개의 클래스 함수 만 호출되었습니다. 이 시나리오에서는 몇 ms의 실행 시간을 절약 할 수 있습니다.


개인적인 의견

수업을 현명하게 작성하면 성능 이 약간 향상됩니다. 그러나 당신은 잘 조직 된 구조를 가지게 될 것입니다. 지금까지 멋진 것은 없습니다. 그러나 플러그인의 클래스 및 함수에 대해 다음과 같은 "분할"사용 사례를 고려하면 최종 결론을 얻게 됩니다. 클래스는 내부이고 함수는 API 입니다. 공개적으로 사용 가능한 함수 (클래스 또는 클래스 함수를 호출하는 함수)를 통해서만 API를 제공하는 한, 플러그인을 더욱 개발하는 데 도움이됩니다. 언제 어디서나 사용자에게 영향을 미치지 않으면 서 내부 구조를 변경하거나 플러그인의 가능성을 자유롭게 변경할 수 있습니다.

예:

// construction of object
if ( ! class_exists( 'WPSE_HelloWorld' ) )
{

class WPSE_HelloWorld
{
    function __construct( $args = array( 'text', 'html', 'echo' ) )
    {
        // call your object building procedures here
        $this->hello_world( 'text', 'html', 'echo' );
    }

    function hello_world( 'text', 'html', 'echo' )
    {
        $start_el = '<{$html}>';
        $end_el = '</{$html}>';
        if ( $echo )
        {
            return print "{$start_el}{$some}{$end_el}";
        }

        return "{$start_el}{$some}{$end_el}";
    }
} // END Class 

}

// API: public functions
function the_hello_world( $args( 'echo' => true ) )
{
    $new = new WPSE_HelloWorld();
    return $new->hello_world( $args );
}

function get_hello_world( array( $args( 'echo' => false) ) )
{
    $new = new WPSE_HelloWorld();
    return $new->hello_world( $args );
}

// then you can call it like get_the_title() or the_title(), which you know from the WP API:
// 'echo' is set to false per default:
$some_var = get_hello_world( array( 'text' => 'hello reader', 'html' => 'strong' ) );
# *returns* "<strong>hello reader</strong>"

// 'echo' is set to true per default:
the_hello_world( array( 'text' => 'hello reader', 'html' => 'strong' ) );
# *prints/echos* "<strong>hello reader</strong>"

참고 : Q에 대한 의견에 게시 된 @ t310s 링크도 읽으십시오.


궁금한 점이 있습니다. 왜 wordpress에 플러그인 파일이 두 번 이상 포함될 것으로 예상하십니까?
hakre

@hakre 정확히 어디에서 말했습니까? 엄마에게 지쳤어요.
카이저

1
@kaiser, @hakre가 if( ! class_exists )처음에 가지고 있는 라인을 참조한다고 가정 합니까?
jjeaton

1
@hakre @kaiser가 class_exists한 번 이상 포함될 수 있기 때문에 다른 클래스와의 충돌을 피하기 위해 검사를 수행한다고 가정 합니까?
Michal Mau

예, class_exists에 대해 궁금했습니다.
hakre

4

플러그인 작성자가 완전히 스타일리시 한 선택입니다. 속도 측면에서 실제 차이는 없습니다.


1

클래스는 일반적으로 성능면에서 이점을 제공하지 않지만 부정적인 영향을 거의 미치지 않습니다. 실제 이점은 코드를 더 명확하게하고 네임 스페이스 충돌을 피하는 것입니다.


그러나 @hakre가 언급했듯이 전역 함수에서 접두사를 사용할 때 네임 스페이스 충돌은 실제로 다르지 않습니다. 이 경우 "Cleaner"코드와 네임 스페이스 충돌 방지는 동의어입니다.
AlxVallejo

@AlxVallejo 나는 그렇게 추측 :)
Bainternet

0

대부분의 경우 함수를 사용하는 경우 각 함수 이름에 플러그인 이름을 입력하므로 플러그인에 약간의 드래그 기능이있는 함수가 여러 개있는 경우 해당 이름을 12 번 복제합니다. .

클래스를 사용하면 클래스 이름에 플러그인 이름이 한 번만있을 수 있습니다.

또한 상속 또는 다른 oo 구성을 사용하여 매우 깨끗한 방식으로 동작을 구현할 수 있습니다. 다음은 예입니다.

class animalplugin{
  //plugin functions...
  function talk(){print "animalnoise";}
}
class animalplugin_with_cat_mods extends abcplugin{
  //cat functions overrides
  function talk(){print "meow";}
}
if (iscat()){
  new animalplugin_with_cat_mods();
} else {
  new animalplugin();
}
당사 사이트를 사용함과 동시에 당사의 쿠키 정책개인정보 보호정책을 읽고 이해하였음을 인정하는 것으로 간주합니다.
Licensed under cc by-sa 3.0 with attribution required.