>백엔드 개발 >PHP 튜토리얼 >가상 프록시에 대한 소개, 2 부

가상 프록시에 대한 소개, 2 부

William Shakespeare
William Shakespeare원래의
2025-02-27 10:41:13709검색

An Intro to Virtual Proxies, Part 2

코어 포인트

다형성을 기반으로 한 가상 프록시는 클라이언트 코드를 수정하지 않고 비용이 많이 드는 객체 그래프를 지연시킬 수 있습니다. 에이전트는 단일 객체 또는 객체 모음으로 작동하도록 설계되어 데이터 관리의 유연성과 효율성을 제공합니다. 가상 에이전트는 스토리지에서 도메인 오브젝트의 게으른로드 컬렉션에 특히 효과적입니다 (예 : 요청시 데이터베이스에서 관련 주석을 추출 할 수있는 블로그 게시물 배치).

실제 주석 컬렉션의 동작을 시뮬레이션하는 프록시는 데이터 맵퍼를 통해 실현되므로 지속성의 관련성이 향상됩니다. 가상 프록시는 값 비싼 작업의 실행을 지연시키는 효과적인 도구 (예 : 스토리지 계층에서 다량의 데이터로드 지연) 및 객체 지향 애플리케이션에서 일반적인 강성 및 취약성 문제를 줄이는 효과적인 도구입니다.
  • 가상 에이전트의 이름은 화려하게 들리지만 아마도 지루한 독단적 원칙 이상인 "인터페이스 지향 프로그래밍"이라는 개념의 가장 두드러진 예 중 하나 일 것입니다. 가상 프록시는 다형성 (간단한 방법을 통해 구현 된 일시적인 다형성보다는 동적 다형성)을 기반으로하며, 클라이언트 코드를 수정하지 않고 비용이 많이 드는 객체 그래프를 빌드/로드 할 수있는 간단하고 신뢰할 수있는 개념입니다. 에이전트의 큰 장점은 단일 객체 또는 객체 모음으로 작동하도록 개념적으로 설계 될 수 있다는 것입니다 (또는 둘 다를 수행하면 문제의 분리를 위태롭게하고 시간이 지남에 따라 관리하기 어렵습니다). 실제 관점에서 가상 프록시가 제공하는 기능을 활용하는 방법을 보여주기 위해이 시리즈의 첫 번째 부분에서는 기본 프록시를 사용하여 데이터베이스에서 집계를 추출하여 간단한 도메인 모델을 만족시키는 방법을 보여주는 몇 가지 예제 개발 프로세스를 소개합니다. 경험이 유익 할 수 있고 운 좋게도 재미 있지만, 다른 쪽은 가상 에이전트의 INS를 보여주기 때문에 약간 기만적이지만보다 현실적인 시나리오에서이를 구현하는 방법을 보여주지는 않습니다. 프록시는 게으른 하중 저장에서 도메인 객체의 수집 측면에서 비교할 수 없습니다. 이 개념을 이해하려면 블로그 게시물의 배치 만 고려하십시오. 각 관련 주석 세트를 주문시 데이터베이스에서 추출 할 수 있습니다. 일반적으로 연습은 최고의 교사입니다. 이 섹션에서는 프록시를 도메인 별 객체 모음에 연결하는 방법을 보여 드리겠습니다. 이 전형적인 시나리오를 매우 기본적인 수준으로 재현하여 운전 논리를 쉽게 이해할 수 있습니다.
  • 영역 객체 모음을 만듭니다앞에서 언급 한 바와 같이, 가상 에이전트는 일반적으로 지속성 계층에서 기본 영역 객체 컬렉션에 결합 된 집계 루트를 얻을 때 생성됩니다. 컬렉션의 특성으로 인해 많은 경우 컬렉션의 사전 설정이 비싸므로 데이터베이스 왕복 오버 헤드를 줄이기 위해 주문형으로로드하는 좋은 후보입니다. 또한 블로그 게시물과 해당 의견 사이의 "일대일"관계 가이 사용 사례에 상당히 충실하게 반영된다는 점을 고려할 때 특정 에이전트를 다루기 전에 간단한 도메인 클래스를 통해 관계를 먼저 모델링하는 것이 도움이 될 것입니다. 상황을 쉽게 이해할 수 있도록 테스트 단계에서 추가 할 두 참가자는 격리 된 인터페이스와 기본 구현자가됩니다. 이 두 가지 결합으로 일반 블로그 게시물 개체의 계약 및 구현을 정의합니다.

    위의 포스트 클래스의 논리를 이해하는 것은 간단한 과정이며 실제 설명이 필요하지 않습니다. 그럼에도 불구하고 여기에는 주목할만한 관련 세부 사항이 있습니다. 클래스는 생성자에 정의되지 않은 주석 모음에 대한 종속성을 명시 적으로 선언합니다. 이제 게시물 주석을 생성하는 클래스를 만들어 봅시다 :
    <code class="language-php"><?php namespace Model;
    use ModelCollectionCommentCollectionInterface;
    
    interface PostInterface
    {
        public function setId($id);
        public function getId();
    
        public function setTitle($title);
        public function getTitle();
    
        public function setContent($content);
        public function getContent();
    
        public function setComments(CommentCollectionInterface $comments);
        public function getComments();
    }</code>
    <code class="language-php"><?php namespace Model;
        use ModelCollectionCommentCollectionInterface;
    
    class Post implements PostInterface
    {
        protected $id;
        protected $title;
        protected $content;
        protected $comments;
    
        public function __construct($title, $content, CommentCollectionInterface $comments = null)  {
            $this->setTitle($title);
            $this->setContent($content);
            $this->comments = $comments;
        }
    
        // ... (Post class methods remain largely unchanged) ...
    }</code>

    지금까지 모든 것이 잘 진행되고 있습니다. 기본 도메인 모델의 얇은 블록 외에도 각 블로그 게시물 객체가 관련 주석과 "일대일"연관성을 열리는 위의 도메인 클래스에 대해 할 말이 없습니다. 원한다면 저를 순수 주의자라고 부를 수 있지만, 현재 모델의 구현이 주석 모음으로 향상되지 않으면 불완전하고 서투른 것처럼 보입니다. 이 추가 구성 요소를 추가하여 모델을 더 풍부하게 만들어 보자.

    <code class="language-php"><?php namespace Model;
    
    interface CommentInterface
    {
         public function setId($id);
         public function getId();
    
         public function setContent($content);
         public function getContent();
    
         public function setPoster($poster);
         public function getPoster();
    }</code>
    CommentCollection 클래스를주의 깊게보고 찾아 보면 먼저 화려한 변장 뒤에 숨겨진 반복적이고 셀 수있는 배열 래퍼에 지나지 않습니다. 실제로, 배열 컬렉션은 여러 형태와 스타일로 제공되지만 대부분의 시간은 반복자 및 ArrayAccess SPL 클래스의 간단한 사용법입니다. 이 경우, 나는 그러한 지루한 작업에서 나 자신 (그리고 당신)을 저장하고 클래스를 iteratoraggregate의 구현 자로 만들고 싶습니다. 댓글 컬렉션을 사용하면 한 걸음 더 나아가 도메인 모델이해야 할 일을 수행 할 수 있습니다. 일부 블로그 게시물 객체에서 작동하거나 데이터베이스에서 열심히 가져온 댓글의 배치와 상호 연결 할 수 있습니다. 그러나 그렇게하는 것은 가상 프록시가 제공하는 기능을 최대한 활용하지 않고 자신을 속일 수 있습니다. 일반적인 구현에서 프록시는 실제 도메인 객체와 동일한 API를 노출한다는 점을 고려할 때, 프록시는 이전 CommentCollection 클래스와 상호 작용하는 프록시는 문제가있는 조건부 진술의 무리를 도입하지 않고 클라이언트 코드와 계약을 준수하기 위해 댓글 collectionInterface를 구현해야합니다.
    <code class="language-php"><?php namespace Model;
    
    class Comment implements CommentInterface
    {
        protected $id;
        protected $content;
        protected $poster;
    
        public function __construct($content, $poster) {
            $this->setContent($content);
            $this->setPoster($poster);
        }
    
        // ... (Comment class methods remain largely unchanged) ...
    }</code>
    가상 에이전트를 통한 도메인 객체의 수집과의 상호 작용 솔직히 말하면, 앞에서 언급했듯이 래핑 어레이 모음은 다른 종속성에 의존하지 않고 독립적으로 존재할 수 있습니다. (회의적이라면, 교리의 컬렉션이 무대 뒤에서 어떻게 작동하는지 자유롭게 확인하십시오.) 여전히 실제 검토 컬렉션의 행동을 시뮬레이션하는 대리를 구현하려고하지만 실제로는 가벼운 대안입니다. 질문해야 할 질문은 다음과 같습니다. 데이터베이스에서 댓글을 추출하여 이전 컬렉션에 넣는 방법은 무엇입니까? 이를 달성하는 방법에는 여러 가지가 있지만 가장 매력적인 것은 데이터 맵퍼를 통한 것이라고 생각합니다. 아래 매퍼는 Storage에서 댓글 모음을 얻는 것이 좋습니다. 확인하십시오 :

    <code class="language-php"><?php namespace Model;
    use ModelCollectionCommentCollectionInterface;
    
    interface PostInterface
    {
        public function setId($id);
        public function getId();
    
        public function setTitle($title);
        public function getTitle();
    
        public function setContent($content);
        public function getContent();
    
        public function setComments(CommentCollectionInterface $comments);
        public function getComments();
    }</code>
    주석 매퍼 클래스에 노출 된 파인더는 일반적으로 표준 데이터 맵퍼 구현에서 예상되는 API를 고수하지만 FetchAll () 메소드는 가장 매력적인 방법입니다. 먼저 스토리지에서 모든 블로그 게시물 주석을 추출하고 컬렉션에 넣고 최종적으로 컬렉션을 클라이언트 코드로 반환합니다. 당신이 나와 같다면, 당신은 컬렉션이 방법 안에 직접 인스턴스화되기 때문에 당신의 마음에 모닝콜이있을 수 있습니다. 실제로, 컬렉션은 실제로 "주입 가능한"카테고리가 아닌 "생성 된"범주에 속하는 일반적인 구조이기 때문에, 적어도이 경우에는 공장 밖에서 몰래 빠져 나오는 새로운 운영자에 대해 당황 할 필요가 없습니다. 어쨌든, 컬렉션을 맵퍼의 생성자에 주입하여 죄책감을 느끼면 자유롭게하십시오. 댓글 매퍼를 사용하면 실제 주현절을 경험하고 이전 세트로 중재하는 프록시 클래스를 구축 할 때입니다.
    <code class="language-php"><?php namespace Model;
        use ModelCollectionCommentCollectionInterface;
    
    class Post implements PostInterface
    {
        protected $id;
        protected $title;
        protected $content;
        protected $comments;
    
        public function __construct($title, $content, CommentCollectionInterface $comments = null)  {
            $this->setTitle($title);
            $this->setContent($content);
            $this->comments = $comments;
        }
    
        // ... (Post class methods remain largely unchanged) ...
    }</code>
    예상대로 CommentCollectionProxy는 실제 주석 모음과 동일한 인터페이스를 구현합니다. 그러나 GetComments () 방법은 실제 작업을 수행하고 Mapper가 생성자에 전달 된 Mapper를 통해 데이터베이스의 주석을로드하는 것을 지연시킵니다. 이 간단하고 효과적인 방법을 사용하면 과로하지 않고 의견에 대한 모든 종류의 영리한 행동을 수행 할 수 있습니다. 어떤 방법을보고 싶습니까? 모든 주석을 데이터베이스에서 특정 블로그 게시물에 제대로 묶어야한다고 가정 해 봅시다. 다음 코드 스 니펫은 다음을 수행 할 수 있습니다

    이 접근법의 단점은 주석이 저장소에서 먼저 추출한 다음 게시물 객체의 내부에 주입된다는 것입니다. 다른 방법으로 어떻게 해야하는지, 이번에는 클라이언트 코드를 프록시로 "스푸핑"하는 것입니까?

    <code class="language-php"><?php namespace Model;
    
    interface CommentInterface
    {
         public function setId($id);
         public function getId();
    
         public function setContent($content);
         public function getContent();
    
         public function setPoster($poster);
         public function getPoster();
    }</code>
    주석은 프록시가 Foreach 루프에 배치 된 후 데이터베이스에서로드를 투명하게 지연시킬뿐만 아니라 클라이언트 코드에 노출 된 API는 프로세스 전반에 걸쳐 원래 구조를 변경하지 않습니다. 우리는 심지어 더 나은 것을 요구하기도합니까? 당신이 매우 욕심이 없다면, 그렇게 생각하기가 어렵습니다. 두 경우 모두 가상 에이전트의 무대 뒤에서 현실과 도메인 오브젝트의 작동 효율성 및 기본 지속성 계층의 작동 효율성을 향상시키는 능력을 최대한 활용하는 방법을 이해해야합니다.

    <🎜 🎜> <<> 결론

    <code class="language-php"><?php namespace Model;
    
    class Comment implements CommentInterface
    {
        protected $id;
        protected $content;
        protected $poster;
    
        public function __construct($content, $poster) {
            $this->setContent($content);
            $this->setPoster($poster);
        }
    
        // ... (Comment class methods remain largely unchanged) ...
    }</code>
    간단하지만, 특히 생산 환경에서 사용할 수있을 정도로 대담한 경우, 이전 예제는 몇 가지 흥미로운 개념을 간략하게 보여줍니다. 첫째, 가상 에이전트는 설정 및 사용이 쉬울뿐만 아니라 런타임의 다른 구현을 혼합하여 비용이 많이 드는 작업을 지연시키는 데 비교할 수 없습니다 (예 : 스토리지 계층에서 다량의 데이터로드를 지연 시키거나 헤비급 객체 그래프 생성). 둘째, 그들은 다형성이 어떻게 효과적인 백신이되어 많은 객체 지향 응용 프로그램이 겪고있는 일반적인 강성 및 취약성 문제를 줄이는 방법에 대한 전형적인 예입니다. 또한 PHP의 객체 모델은 간단하고 폐쇄를 지원하기 때문에 이러한 기능을 영리하게 혼합하고 폐쇄의 장점에 의해 기본 논리가 주도되는 프록시를 구축 할 수 있습니다. 이 도전을 직접 다루고 싶다면 사전에 최선을 다하길 바랍니다.

    (imredesiuk / shutterstock의 그림)

위 내용은 가상 프록시에 대한 소개, 2 부의 상세 내용입니다. 자세한 내용은 PHP 중국어 웹사이트의 기타 관련 기사를 참조하세요!

성명:
본 글의 내용은 네티즌들의 자발적인 기여로 작성되었으며, 저작권은 원저작자에게 있습니다. 본 사이트는 이에 상응하는 법적 책임을 지지 않습니다. 표절이나 침해가 의심되는 콘텐츠를 발견한 경우 admin@php.cn으로 문의하세요.