제7장 대상(二) - 기본 대상 시스템

4380 단어

신성한 인용


Perl 기본 오브젝트 지향 시스템은 3가지 규칙으로 매우 작습니다.
  • 한 종류가 가방
  • 한 방법이 함수
  • 하나의 인용(blessed, 하복)은 하나의 대상이다(나는bless가 인용한 인용을 신성한 인용으로 번역했기 때문에 하나의 신성한 인용은 하나의 대상이다)
  • 이 세 가지 규칙으로 너는 무엇이든 만들 수 있다.그러나 이것만으로 대형 프로젝트를 구축하는 것은 분명히 너무 간략하다. 특히 원 프로그래밍의 고도의 추상적인 능력이 부족하다.수백 줄이 넘는 (현대) 프로그램에 대해서는 Moose를 사용하는 것이 더 좋은 선택이지만, 대량의 유류 코드는 여전히 기본적인 대상 시스템을 사용하고 있다.
    앞의 두 가지 규칙은 우리가 이미 전에 소개한 적이 있다.내장 함수bless의 역할은 클래스 이름과 인용을 연결시킨 다음에 이 인용은 효과적인 호출자가 되고 Perl은 이 인용에서 방법의 스케줄링을 할 수 있다.(인용을 통해 클래스, 스케줄링 클래스에 연결하는 방법)
    구조 함수는 대상을 만드는 방법(클래스 방법)이다.관례에 따르면, 구조 함수의 이름은 new () 이지만, 이것은 강제적인 것이 아니다.
    bless는 인용과 클래스 이름 두 개의 조작수가 있습니다.인용은 임의로 유효한 인용일 수 있고 빈 인용도 된다.클래스 이름은 옵션이며 기본값은 현재 패키지 이름입니다.bless의 반환값은bless의 인용입니다.간단한 구조 함수:
    sub new
    {
    my $class = shift;
    bless {}, $class;
    }
    

    이 구조 함수는 호출자를 분류명으로 추출한다.너도 클래스 이름을 하드코딩할 수 있지만, 그러면 융통성이 없다.파라미터를 가진 구조 함수는 계승, 의뢰, 내보낼 때 다시 사용할 수 있습니다.
    인용의 유형을 통해 대상의 실례가 어떻게 자신의 데이터를 저장하는지 알 수 있다.해시 인용이 가장 흔하지만 다른 유형의 인용도bless를 대상으로 할 수 있다.
    my $array_obj = bless [], $class;
    my $scalar_obj = bless \$scalar, $class;
    my $func_obj = bless \&some_func, $class;
    

    Moose의 클래스 정의는 속성에 대한 설명이 필요하지만 Perl의 기본 OO 시스템은 그다지 엄격하지 않습니다.농구 선수를 나타내는 클래스로 코트 번호와 위치를 저장하는데 그 구조 함수는 다음과 같다.
    package Player
    {
    sub new
    {
    my ($class, %attrs) = @_;
    bless \%attrs, $class;
    }
    }
    

    새 선수를 만드는 것은 이렇다.
    my $joel = Player->new( number => 10, position => 'center' );
    my $damian = Player->new( number => 0, position => 'guard' );
    

    클래스 메서드는 해시 요소에 액세스하는 것처럼 객체 속성에 직접 액세스할 수 있습니다.
    sub format
    {
    my $self = shift;
    return '#' . $self->{number} . ' plays ' . $self->{position};
    }
    

    문제는 대상의 내부 데이터를 수정하면 다른 코드를 파괴할 수 있기 때문에 액세서리를 사용하는 방식보다 더욱 안전하다는 것이다.
    sub number { return shift->{number} }
    sub position { return shift->{position} }
    

    이제는 무스가 무료로 제공하는 기능들을 직접 작성해야만 한다.Moose는 객체 등록 정보를 직접 조작하는 대신 액세스기, 설정기를 사용하도록 권장합니다.

    메소드 스케줄링 및 상속


    $joel을 신성하게 인용하여 메서드를 호출합니다.
    my $number = $joel->number;
    

    우선 클래스 (클래스가 인용과 연결되었음) $joel을 찾았습니다. 여기는Player 클래스입니다.다음 Perl은 Player에서number () 라는 함수를 찾을 것입니다.함수가 존재하지 않고 Player가 부류를 계승한다면 Perl은 부류에서 찾고 부류의 부류에서 찾으며,number () 를 찾을 때까지 차례대로 유추합니다. (어디든지) 찾으면 $joel을 호출자로 호출합니다.
    CPAN에 모듈 namespace: autoclean은 함수 가져오기로 인한 이름 충돌을 피하는 데 도움을 줍니다.
    Moose는 계승 관계를 추적하는 extends를 제공합니다. Perl은 패키지 전역 변수 @ISA를 사용합니다.방법 스케줄링은 모든 종류의 @ISA에서 부류를 찾는 것입니다.InjuredPlayer 클래스가 Player 클래스를 상속할 경우 다음과 같이 쓸 수 있습니다.
    package InjuredPlayer
    {
    @InjuredPlayer::ISA = 'Player';
    }
    

    컴파일 명령 parent를 사용하면 쓰기 작업이 더 간단해집니다.
    package InjuredPlayer
    {
    use parent 'Player';
    }
    

    Moose는 자신의 모형이 계승 정보를 저장하기 때문에 더 많은 원본 편정 기회를 가질 수 있다.
    당신은 여러 부류를 계승할 수 있습니다.
    package InjuredPlayer
    {
    use parent qw( Player Hospital::Patient );
    }
    

    AUTOLOAD


    만약 계속 호출할 방법을 찾지 못한다면, Perl은 AUTOLOAD () 방법을 찾으러 돌아갈 것이다.너는 어떤 상황에서는 문제가 복잡해진다는 것을 깨달았을 것이다.다중 상속 중 어떤 AUTOLOAD () 방법을 사용합니까?

    다시 쓰는 방법


    기본 OO는 다시 쓰는 방법을 지원하지만, 다음 메커니즘을 제공하지 않습니다: * * * * 부모 방법을 다시 쓰는 방법 * * * *.결과적으로, 당신이 정의하거나 설명하거나 하위 클래스에 가져온 함수는 부모 클래스의 동명 방법을 다시 쓴다.
    다시 쓰는 방법은 같은 이름의 방법을 설명하면 됩니다. 다시 쓰는 방법 내부에서 SUPER:::부류 방법을 호출할 수 있습니다.
    sub overridden
    {
    my $self = shift;
    warn 'Called overridden() in child!';
    return $self->SUPER::overridden( @_ );
    }
    

    SUPER::접두사는 모종 호출을 위한 메소드 스케줄러를 알려줍니다.사용자 정의 매개 변수를 제공할 수 있지만, 보통 @,호출자를 마운트 해제해야 합니다. (@ 의 첫 번째 인자)
    SUPER::다른 가방에서 가져오는 방법이 잘못되면Perl에서 올바른 부류를 찾을 수 없습니다.호환성 때문에 이 특성은 줄곧 보존되어 있다.CPAN의 SUPER 모듈은 해결 방법을 제공합니다.Moose는 그런 문제 없어요.

    신성 인용에 대응하는 전략


    기본 OO시스템(신성 인용)은 작지만 혼란스러워서 Mosse보다 사용하기 쉬우므로 가능한 한 Moose를 선택해야 합니다.신성한 인용을 사용하는 코드를 유지해야 하거나 팀 전체를 Moose로 옮기도록 설득하지 못했다면 구덩이를 피하는 데 도움을 줄 수 있는 조언이 있습니다.
  • 같은 클래스에서 함수와 방법을 혼합하지 마라
  • 가능한 한 종류별로 하나씩 사용하세요.pm 파일
  • 기본 OO시스템의 표준을 따른다. 예를 들어 구조 함수는 new()이고 $self는 호출자의 이름이다
  • 방법에서라도 액세서리를 사용합니다.Class::Accessor 이 모듈이 당신에게 유용할 수 있습니다
  • AUTOLOAD() 회피
  • 다른 사람이나 다른 곳에서 당신의 클래스를 사용할 것을 고려하고bless에서는 2개의 파라미터를 사용하여 클래스를 최소한의 행위 단원으로 분해합니다.
  • 코드를 다시 사용하는 데 도움을 주는 모듈을 사용합니다. 예를 들어 Role::Tiny
  • 좋은 웹페이지 즐겨찾기