웹사이트 검색

Java의 방문자 디자인 패턴


방문자 디자인 패턴은 행동 디자인 패턴 중 하나입니다.

방문자 디자인 패턴

방문자 패턴은 유사한 종류의 개체 그룹에 대해 작업을 수행해야 할 때 사용됩니다. 방문자 패턴의 도움으로 개체에서 다른 클래스로 운영 논리를 이동할 수 있습니다. 예를 들어 다양한 유형의 항목(요소)을 추가할 수 있는 쇼핑 카트를 생각해 보십시오. 체크아웃 버튼을 클릭하면 지불할 총 금액을 계산합니다. 이제 항목 클래스에 계산 논리를 포함하거나 방문자 패턴을 사용하여 이 논리를 다른 클래스로 이동할 수 있습니다. 방문자 패턴 예제에서 이를 구현해 보겠습니다.

방문자 디자인 패턴 Java 예제

방문자 패턴을 구현하기 위해 먼저 장바구니에 사용할 다양한 유형의 항목(Elements)을 생성합니다. ItemElement.java

package com.journaldev.design.visitor;

public interface ItemElement {

	public int accept(ShoppingCartVisitor visitor);
}

수락 방법은 방문자 인수를 사용합니다. 항목에 특정한 다른 방법도 사용할 수 있지만 간단하게 하기 위해 그다지 자세히 설명하지 않고 방문자 패턴에만 초점을 맞춥니다. 다양한 유형의 항목에 대한 몇 가지 구체적인 클래스를 만들어 봅시다. 책.자바

package com.journaldev.design.visitor;

public class Book implements ItemElement {

	private int price;
	private String isbnNumber;
	
	public Book(int cost, String isbn){
		this.price=cost;
		this.isbnNumber=isbn;
	}
	
	public int getPrice() {
		return price;
	}

	public String getIsbnNumber() {
		return isbnNumber;
	}

	@Override
	public int accept(ShoppingCartVisitor visitor) {
		return visitor.visit(this);
	}

}

과일.자바

package com.journaldev.design.visitor;

public class Fruit implements ItemElement {
	
	private int pricePerKg;
	private int weight;
	private String name;
	
	public Fruit(int priceKg, int wt, String nm){
		this.pricePerKg=priceKg;
		this.weight=wt;
		this.name = nm;
	}
	
	public int getPricePerKg() {
		return pricePerKg;
	}


	public int getWeight() {
		return weight;
	}

	public String getName(){
		return this.name;
	}
	
	@Override
	public int accept(ShoppingCartVisitor visitor) {
		return visitor.visit(this);
	}

}

구체적인 클래스에서 accept() 메서드의 구현, Visitor의 visit() 메서드를 호출하고 자신을 인수로 전달하는 것에 주목하십시오. 구체적인 방문자 클래스에 의해 구현될 방문자 인터페이스의 다양한 유형의 항목에 대한 visit() 메서드가 있습니다. ShoppingCartVisitor.java

package com.journaldev.design.visitor;

public interface ShoppingCartVisitor {

	int visit(Book book);
	int visit(Fruit fruit);
}

이제 방문자 인터페이스를 구현하고 모든 항목에는 비용을 계산하는 고유한 논리가 있습니다. ShoppingCartVisitorImpl.java

package com.journaldev.design.visitor;

public class ShoppingCartVisitorImpl implements ShoppingCartVisitor {

	@Override
	public int visit(Book book) {
		int cost=0;
		//apply 5$ discount if book price is greater than 50
		if(book.getPrice() > 50){
			cost = book.getPrice()-5;
		}else cost = book.getPrice();
		System.out.println("Book ISBN::"+book.getIsbnNumber() + " cost ="+cost);
		return cost;
	}

	@Override
	public int visit(Fruit fruit) {
		int cost = fruit.getPricePerKg()*fruit.getWeight();
		System.out.println(fruit.getName() + " cost = "+cost);
		return cost;
	}

}

클라이언트 애플리케이션에서 방문자 패턴 예제를 사용하는 방법을 살펴보겠습니다. ShoppingCartClient.java

package com.journaldev.design.visitor;

public class ShoppingCartClient {

	public static void main(String[] args) {
		ItemElement[] items = new ItemElement[]{new Book(20, "1234"),new Book(100, "5678"),
				new Fruit(10, 2, "Banana"), new Fruit(5, 5, "Apple")};
		
		int total = calculatePrice(items);
		System.out.println("Total Cost = "+total);
	}

	private static int calculatePrice(ItemElement[] items) {
		ShoppingCartVisitor visitor = new ShoppingCartVisitorImpl();
		int sum=0;
		for(ItemElement item : items){
			sum = sum + item.accept(visitor);
		}
		return sum;
	}

}

위의 방문자 패턴 클라이언트 프로그램을 실행하면 다음과 같은 결과가 나타납니다.

Book ISBN::1234 cost =20
Book ISBN::5678 cost =95
Banana cost = 20
Apple cost = 25
Total Cost = 160

구현 if accept() 메서드는 모든 항목에서 동일하지만 다를 수 있습니다. 예를 들어 항목이 비어 있는지 확인하는 논리가 있을 수 있으며 visit() 메서드를 전혀 호출하지 않습니다.

방문자 디자인 패턴 클래스 다이어그램

방문자 패턴의 이점

이 패턴의 이점은 작업 논리가 변경되면 모든 항목 클래스에서 변경하는 대신 방문자 구현에서만 변경해야 한다는 것입니다. 또 다른 이점은 시스템에 새 항목을 추가하는 것이 쉽다는 것입니다. 방문자 인터페이스 및 구현만 변경하면 되며 기존 항목 클래스는 영향을 받지 않습니다.

방문자 패턴 제한 사항

방문자 패턴의 단점은 디자인할 때 visit() 메서드의 반환 유형을 알아야 한다는 것입니다. 그렇지 않으면 인터페이스와 모든 구현을 변경해야 합니다. 또 다른 단점은 방문자 인터페이스 구현이 너무 많으면 확장하기 어렵다는 것입니다. 이것이 방문자 디자인 패턴의 전부입니다. 놓친 것이 있으면 알려주세요. 당신이 그것을 좋아한다면 다른 사람들과 공유하십시오.