의 18: 방문 자 모델

7404 단어 디자인 모드
Visitor Pattern 방문 자 모드 는 다음 과 같 습 니 다.
Represent an operation to be performed on the elements of an object structure. Visitor lets you define a new operation without changing the classes of the elements on which it operates.
특정한 데이터 인터페이스 에 작용 하 는 각 요소 의 조작 을 밀봉 하면 데이터 구 조 를 바 꾸 지 않 는 전제 에서 이러한 요소 에 작용 하 는 새로운 조작 을 정의 할 수 있다.
 
방문 자 모드 의 몇 가지 역할:
1, Visitor -- 추상 적 인 접근 인터페이스
방문 자가 어떤 요 소 를 방문 할 수 있 는 지 설명 합 니 다. 구체 적 으로 프로그램 에서 visit 방법의 매개 변 수 는 어떤 대상 이 방문 할 수 있 는 지 정의 합 니 다.
2, ConcreteVisitor -- 구체 적 인 방문 자
3, 요소 -- 추상 요소
인터페이스 나 추상 류, 어떤 방문 자의 방문 을 받 아들 이 는 지 설명 하고 프로그램 에서 accept 방법 매개 변 수 를 통 해 정의 합 니 다.
4, ConcreteElement -- 구체 적 인 요소
accept 방법 을 실현 하 는 것 은 보통 vistor. visit (this) 로 기본적으로 하나의 모델 이 형성 되 었 다.
5, ObjectStructure -- 구조 대상
원 격 생 성 자 는 일반적으로 여러 개의 서로 다른, 서로 다른 인터페이스의 용 기 를 수용 하 는데 예 를 들 어 List, Set, Map 등 은 프로젝트 에서 이 역할 을 추상 화하 지 않 는 다.
 
공통 소스 코드:
public abstract class Element {
    //       
    public abstract void doSomething();
    //       
    public abstract void accept(IVisitor visitor);
}

 
public class ConcreteElement1 extends Element {
    @Override
    public void doSomething() {
        System.out.println("do1...");
    }

    @Override
    public void accept(IVisitor visitor) {
        visitor.visit(this);
    }
}

 
public class ConcreteElement2 extends Element {
    @Override
    public void doSomething() {
        System.out.println("do2...");
    }

    @Override
    public void accept(IVisitor visitor) {
        visitor.visit(this);
    }
}

 
public interface IVisitor {
    //         
    public void visit(ConcreteElement1 element1);
    public void visit(ConcreteElement2 element2);
}

 
public class Visitor implements IVisitor {
    @Override
    public void visit(ConcreteElement1 element1) {
        element1.doSomething();
    }

    @Override
    public void visit(ConcreteElement2 element2) {
        element2.doSomething();
    }
}

 
public class Client {
    public static void main(String[] args) {
        for (int i = 0; i < 10; i++) {
            if (i % 2 == 0) {
                new ConcreteElement1().accept(new Visitor());
            } else {
                new ConcreteElement2().accept(new Visitor());
            }
        }
    }
}

 
방문 자 모드 의 장점:
1. 단일 직책 원칙 에 부합
구체 적 인 요소 역할 Element 추상 류 의 두 가지 유형 은 데이터 의 로드 를 담당 하고 Visitor 류 는 보고서 의 표현 을 책임 집 니 다. 두 가지 구체 적 이 고 서로 다른 직책 은 명확 하 게 분리 되 고 각자 의 표현 변화 가 있 습 니 다.
2, 우선 확장 성
직책 이 분리 되 기 때문에 데 이 터 를 계속 추가 하 는 작업 이 매우 빠르다. 예 를 들 어 큰 boss 에 게 보 내 는 보고 서 를 추가 하려 면 이 보고서 의 형식 이 다르다. 우 리 는 Visitor 에서 하나의 방법 을 추가 하고 데 이 터 를 전달 한 후에 정리 하고 인쇄 하면 된다. 원래 의 Element 는 움 직 이지 않 는 다.
3. 유연성 이 매우 높다
예 를 들 어 그 Employee 의 예 를 들 어 모든 사람의 보 너 스 를 통계 하려 면 계산 규칙 은 직원 월급 * 0.4, 부서 장 월급 * 0.6, 사장 님 월급 * 0.8 입 니 다. 그 전에 우 리 는 어떻게 했 습 니까?그러면 모든 Employee 를 순환 시 킨 다음 에 instanceof 로 판단 합 니 다. 제 가 닦 아 보 겠 습 니 다. 너무 아름 답지 않 습 니 다. 이 럴 때 방문 자 모드 로 완벽 하 게 해결 할 수 있 습 니 다. 데 이 터 를 방문 자 에 게 던 지고 방문 자가 통계 적 으로 계산 할 수 있 습 니 다.
 
방문 자 모드 의 단점:
1. 구체 적 인 요소 Element 는 방문 자 에 게 세부 사항 을 발표 합 니 다.
2. 구체 적 인 요소 변경 이 어렵다
3. 거꾸로 의존 하 는 원칙 에 위배 된다.
방문 자가 방문 하 는 것 은 추상 적 인 요소 가 아니 라 구체 적 인 요소 이다. 이것 은 후진 원칙 에 의존 하고 확장 하 는 것 이 비교적 어렵다.
 
방문 자 모드 의 사용 장면:
1. 하나의 대상 구 조 는 여러 가지 대상 을 포함 하 는데 서로 다른 인터페이스 가 있다. 예 를 들 어 위의 Employee 의 자 류 는 일반 직원 과 매니저 등 이 있다.그리고 이러한 대상 에 대해 구체 적 인 실현 류 에 의존 하 는 조작 을 실시 하고 싶 습 니 다. 즉, 교체 기 모델 로 는 감당 할 수 없습니다. 인 스 턴 스 of 로 유형 을 판단 해 야 하기 때 문 입 니 다. 멘 붕.
2. 한 대상 구조 (일반적으로 집합) 의 대상 에 대해 여러 번 다 르 고 관련 이 없 는 조작 을 해 야 하 며, 이러한 조작 이 이러한 대상 을 오염 시 키 는 것 을 피하 고 싶 습 니 다.
3. 방문 자 모드 는 차단기 인 터 셉 터 역할 로 도 사용 할 수 있다.
 
방문 자 모드 확장:
통계 기능:
통계 보고 서 는 우리 가 자주 실현 해 야 하 는 기능 으로 대체적으로 계산 공식 이다. 그 다음 에 보고 서 를 내 면 많은 프로젝트 들 이 데이터 뱅 크 의 저장 과정 으로 실현 되 지만 이것 은 추천 하지 않 는 방법 이다.대량의 데 이 터 를 제외 하고 하룻밤 에 억, 수 십 억 개의 데 이 터 를 처리 해 야 하 며 저장 과정 을 제외 하고 처리 할 방법 이 없다.
public interface IVistor {
	//              
	public void visit(CommonEmployee commonEmp);
	//               
	public void visit(Manager manager);
	//            
	public int getTotalSalary();
}

public class Visitor implements IVisitor {
	//         5
	private final int managerRatio = 5;
	//         3
	private final int commonRatio = 3;
	//          
	private int commmonTotal = 0;
	//       
	private int managerTotal = 0;
	private void calManager(int salary) {
		managerTotal += salary*managerRatio;
	}
	private void calCommon(int salary) {
		commmonTotal += salary*commonRatio;
	}
	public int getTotalSalary() {
		return managerTotal + commmonTotal;
	}
	public void visit(CommonEmployee commonEmp) {
		System.out.println("          ");
		calCommon(commonEmp.getSalary());
	}
	public void visit(Manager manager) {
		System.out.println("       ");
		calManager(manager.getSalary());
	}
}

public class Client {
	public static void main(String[] args) {
		IVisitor vistor = new Visitor();
		List<Employee> list = null;
		for (Employee emp : list) {
			emp.accept(visitor);
		}
		System.out.println("    :" + vistor.getTotalSalary());
	}
}

 
여러 방문 자:
위의 것 은 두 방문 자로 나 뉘 어야 한다. 하 나 는 데 이 터 를 보 여 주 는 report 만 사용 하 는 visitor 이 고, 다른 하 나 는 총 집합 을 담당 하 는 totalk 의 visitor 이다.두 개의 인 터 페 이 스 를 추가 할 수 있 으 며, 모두 IVisitor 에서 계승 할 수 있 지만, 각자 의 방법 이 있다.마지막 순환 에서 호출
emp.accept(reportVisitor);
emp.accept(totalVisitor); 모든 정 보 를 Visitor 인 스 턴 스 에 축적 합 니 다.
그리고 맨 뒤에 있 을 때 는 각자 의 방법 을 직접 사용 할 수 있다.
 
질문
public interface Role {
    public void accept(AbsActor actor);
}

 
public class UglyRole implements Role {
    @Override
    public void accept(AbsActor actor) {
        actor.act(this);
    }
}

 
public class BeautyRole implements Role {
    @Override
    public void accept(AbsActor actor) {
        actor.act(this);
    }
}

 
public class Client {
    public static void main(String[] args) {
        //       
        AbsActor actor = new UglyActor();
        //       
        Role role = new BeautyRole();
//        //     
//        actor.act(role);
//        //     
//        actor.act(new BeautyRole());
        //     (     )
        role.accept(actor);
    }
}

 
본인 의 블 로 그 는 이미 이 사 했 습 니 다. 새 주 소 는 다음 과 같 습 니 다. http://yidao620c.github.io/

좋은 웹페이지 즐겨찾기