어느 날은 기술부장이 전체 기술직의 근무 현황을 알고 싶다고 했고, 다음날 상사는 모든 직원의 성과를 알고 싶다고 했습니다. 또 어느 날 인사부장은 급여를 알고 싶다고 했습니다. 모든 직원의. 매번 조합 모드를 사용하여 직원을 순회하고 직원의 관련 정보를 얻습니다. 아마 그냥 모든 정보를 출력하면 된다고 말할 겁니다. 그러면 아마도 상사에게 잡힐 것입니다. 상사는 성능을 알고 싶어합니다. 큰 테이블을 보면 알겠습니다. 방문자 패턴을 사용하여 이 문제를 해결해 보겠습니다. 클래스 다이어그램은 다음과 같습니다.
보시다시피 방문자가 있습니다. 약간 에이전트같아. 프록시 모드에 대해 이야기할 때 이미 방문자 모드에 대해 언급했습니다. 이번 구매에서는 좀 더 특별한 경우에 프록시 모드를 사용합니다. 구현 코드:
<?php interface IVisitor{ public function visitCommonEmployee( CommonEmployee $commonEmployee ); public function visitManager( Manager $manager ); } class Visitor implements IVisitor{ public function visitCommonEmployee( CommonEmployee $commonEmployee ) { echo $this->getCommonEmployee( $commonEmployee ); } public function visitManager( Manager $manager ) { echo $this->getManagerInfo( $manager ); } private function getBasicInfo( Employee $employee ) { $info = "姓名:".$employee->getName()."\t"; return $info; } private function getCommonEmployee( CommonEmployee $commonEmployee ) { $basicInfo = $this->getBasicInfo( $commonEmployee ); $otherInfo = "工作:".$commonEmployee->getJob()."\n"; return $basicInfo.$otherInfo; } private function getManagerInfo( Manager $manager ) { $basicInfo = $this->getBasicInfo( $manager ); $otherInfo = "业绩:".$manager->getPerformance()."\n"; return $basicInfo.$otherInfo; } } abstract class Employee { private $name; public function getName() { return $this->name; } public function setName( $name ) { $this->name = $name; } public function accept( IVisitor $visitor ) { $method = 'visit'.get_class( $this ); $visitor->$method( $this ); } } class CommonEmployee extends Employee{ private $job; public function getJob() { return $this->job; } public function setJob( $job ) { $this->job = $job; } } class Manager extends Employee{ private $performance; public function getPerformance() { return $this->performance; } public function setPerformance( $performance ) { $this->performance = $performance; } } $empList = array(); $zhangsan = new CommonEmployee(); $zhangsan->setName( '张三' ); $zhangsan->setJob( 'coding' ); $empList[] = $zhangsan; $lisi = new CommonEmployee(); $lisi->setName( '李四' ); $lisi->setJob( 'coding' ); $empList[] = $lisi; $wangwu = new Manager(); $wangwu->setName( '马云' ); $wangwu->setPerformance( '负值,但拍马屁厉害' ); $empList[] = $wangwu; foreach ($empList as $value) { $value->accept(new Visitor()); } ?>
실행 결과:
이름: Zhang San 작업: 코딩
이름: Li Si 작업: 코딩
이름: Jack 마 퍼포먼스: 부정적이지만 아주 잘 뿌듯함
[0.4초 만에 완료]
앞으로 특별한 목록이 있으면 특별한 방문자를 추가하면 됩니다. 이제 상사가 악용할 수 없습니다. 나 !
방문자 패턴 정의
는 특정 데이터 구조의 각 요소에 작용하는 일부 작업을 캡슐화하며 데이터 구조를 변경하지 않고도 이러한 요소에 작용하는 새로운 작업을 정의할 수 있습니다. 주요 역할은 다음과 같습니다.
1. VIsitor - 추상 방문자
방문자가 액세스할 수 있는 요소를 선언하는 추상 클래스 인터페이스는 프로그램에 따라 방문 메소드의 매개변수로 정의됩니다. 방문할 수 있습니다.
2. 구체적인 방문자——구체적인 방문자
방문자가 수업에 접속한 후 무엇을 해야 하는지에 영향을 미칩니다.
3. 요소 ——추상 요소
인터페이스 또는 추상 클래스는 승인되는 방문자 유형을 프로그래밍 방식으로 선언합니다.
4. ConcreteElement - 특정 요소
는 기본적으로 패턴을 형성하는 일반적으로 Visitor->visitor($this)인 accept 메소드를 구현합니다.
5. ObjectStruture - 일반적으로 다양한 클래스와 인터페이스의 여러 컨테이너를 수용하는 구조 개체
요소 생성기입니다.
방문자 패턴의 장점
1. 단일 책임 원칙을 준수합니다.
특정 요소 역할은 담당 Employee 추상 클래스의 두 하위 클래스입니다. 방문자 클래스는 보고서 표시를 담당하고 두 가지 다른 책임은 명확하게 구분되어 각각 변경을 수행합니다.
2. 뛰어난 확장성
책임 분리로 인해 데이터의 지속적인 운영 증가가 매우 빠릅니다. 예를 들어 대기업에 대한 보고서를 추가하려는 경우입니다. , Visitor Method에서 직접 보고서를 추가하고 데이터를 전달한 후 정렬되어 인쇄됩니다.
3. 매우 높은 유연성
예를 들어, 보고서와 동시에 총 급여를 계산해야 한다고 가정해 보세요.
방문자 모드의 단점
1. 특정 요소 방문자에게 세부 정보 게시
방문자가 클래스에 액세스하려면 클래스에서 몇 가지 메서드와 데이터를 게시해야 합니다. 즉, 방문자는 다른 클래스의 내부 세부 정보에 주의를 기울여야 합니다. 이는 데메테르의 규칙이 아닙니다.
2. 특정 요소를 변경하기 어렵다
위의 예에서 멤버 변수를 추가하려는 경우 특정 요소 역할을 추가, 삭제, 수정하기가 어렵습니다. 연령에 따라 방문자를 수정해야 합니까? 방문자가 2명 이상인 경우 각 방문자를 수정해야 합니까?
3. 종속성 역전 원칙을 위반합니다.
방문자는 추상 요소가 아닌 구체적인 요소에 의존합니다. 이는 특히 객체 지향 프로그래밍에서 종속성 역전 원칙을 파괴하고 인터페이스에 대한 종속성을 포기하지만 구현 클래스와 확장에 직접적으로 의존하는 것이 더 어렵습니다.
방문자 패턴의 사용 시나리오
1. 객체 구조에는 많은 클래스 객체가 포함되어 있으며 서로 다른 인터페이스를 가지며 특정 클래스에 따라 이러한 객체에 대해 일부 작업을 수행하려고 합니다. 즉, 반복자 패턴은 더 이상 적합하지 않습니다.
2. 객체 구조의 객체에 대해 서로 다른 여러 가지 작업을 수행해야 하며 이러한 작업이 해당 객체의 클래스를 "오염"시키는 것을 방지해야 합니다.
방문객 모드 확장
1. 통계 기능
예를 들어 전체 직원의 급여를 계산하려면 인터페이스에 메서드를 추가하고 구현하기만 하면 됩니다. 특정 수업에서.
2. 다중 방문자
앞서 말했듯이 방문자마다 보고 요구 사항이 다를 경우 방문자 클래스 구현을 직접 추가하면 됩니다.
3. 듀얼 디스패치(JAVA)
잔소리: 방문자 모드는 특히 대규모 리팩토링에 적합한 중앙 집중식 모드입니다. 방문자 모드를 통해 일부 기능을 쉽게 정리하여 통합 보고서 계산, UI 표시 등 기능 집중화를 달성할 수 있습니다. 또한 다른 패턴 블렌딩과 결합하여 자신만의 필터 또는 인터셉터 세트를 만들 수도 있습니다.