[GoF] Facade 패턴

패턴명칭

Facade

필요한 상황

어떤 기능을 실행할때 다양한 타입의 객체들의 함수를 정확한 순서로 호출해야 할때 발생하는 복잡도를 단순화시켜주는 패턴이다.

예제 코드

데이터베이스부터 사용자의 정보를 가져오기 전에 먼저 캐쉬를 통해 정보를 가져오고, 만약 캐쉬에 없다면 데이터베이스로부터 사용자 정보를 가져와 캐쉬에 저장한다. 그 다음은 이 정보를 원하는 형태의 메세지로 출력하기 위한 기능을 개발한다고 하자. 이 기능에 대해서 사용자 정보는 Row 클래스, 데이터베이스는 DBMS 클래스, 캐쉬는 Cache 클래스, 메세지 출력을 위한 내용의 구성은 Message 클래스가 담당한다. 이러한 클래스들 간의 정확한 관계와 매서드들간의 복잡한 관계를 Facade 클래스를 도입하여 단순화 시킨다. 먼저 사용자 정보는 Row는 다음과 같다.

package pattern;

public class Row {
	private String name;
	private String birthday;
	private String email;
	
	public Row(String name, String birthday, String email) {
		this.name = name;
		this.birthday = birthday;
		this.email = email;
	}
	
	public String getName() {
		return name;
	}
	
	public String getBirthday() {
		return birthday;
	}
	
	public String getEmail() {
		return email;
	}
}

DBMS 클래스는 다음과 같다.

package pattern;

import java.util.HashMap;

public class DBMS {
	private HashMap<String, Row> db;
	
	public DBMS() {
		db = new HashMap<String, Row>();
		
		db.put("jane", new Row("Jane", "1990-02-14", "jane09@geosee.co.kr"));
		db.put("robert", new Row("Robert", "1979-11-05", "nice@googl.com"));
		db.put("dorosh", new Row("Dorosh", "1985-08-21", "doshdo@nave.net"));
	}
	
	public Row query(String name) {
		try {
			Thread.sleep(2000);
		} catch (InterruptedException e) {
			e.printStackTrace();
		}
		
		return db.get(name.toLowerCase());
	}
}

Cache 클래스는 다음과 같다.

package pattern;

public class Facade {
	public void run(DBMS dbms, Cache cache, String name) {
		Row row = cache.get(name);
		if(row == null) {
			row = dbms.query(name);
			if(row != null) {
				cache.put(row);
			}
		}
		
		if(row != null) {
			Message message = new Message(row);
			System.out.println(message.makeName());
			System.out.println(message.makeBirthday());
			System.out.println(message.makeEmail());
		} else {
			System.out.println(name + " is not exists.");
		}
	}
}

Message 클래스는 다음과 같다.

package pattern;

public class Message {
	private Row row;
	
	public Message(Row row) {
		this.row = row;
	}
	
	public String makeName() {
		return "Name: \"" + row.getName() + "\"";
	}
	
	public String makeBirthday() {
		return "Birthday: " + row.getBirthday();
	}
	
	public String makeEmail() {
		return "Email: " + row.getEmail();
	}
}

이제 위의 클래스들에 대한 상호간의 API 호출을 단순화시킨 Facade 클래스는 다음과 같다.

package pattern;

public class Facade {
	public void run(DBMS dbms, Cache cache, String name) {
		Row row = cache.get(name);
		if(row == null) {
			row = dbms.query(name);
			if(row != null) {
				cache.put(row);
			}
		}
		
		if(row != null) {
			Message message = new Message(row);
			System.out.println(message.makeName());
			System.out.println(message.makeBirthday());
			System.out.println(message.makeEmail());
		} else {
			System.out.println(name + " is not exists.");
		}
	}
}

실제 사용 예제 코드는 다음과 같다.

package pattern;

public class Main {
	public static void main(String[] args) {
		DBMS dbms = new DBMS();
		Cache cache = new Cache();
		
		String name = "Dorosh";
		
		Facade facade = new Facade();
		facade.run(dbms, cache, name);
	}
}

실행 결과는 다음과 같다.

Name: "Dorosh"
Birthday: 1985-08-21
Email: doshdo@nave.net

Facade 패턴의 도입으로 복잡한 클래스간의 함수 호출이 단순화되고 재사용성이 높아진다.

이 글은 소프트웨어 설계의 기반이 되는 GoF의 디자인패턴에 대한 강의자료입니다. 완전한 실습을 위해 이 글에서 소개하는 클래스 다이어그램과 예제 코드는 완전하게 실행되도록 제공되지만, 상대적으로 예제 코드와 관련된 설명이 함축적으로 제공되고 있습니다. 이 글에 대해 궁금한 점이 있으면 댓글을 통해 남겨주시기 바랍니다.

댓글 남기기

이메일은 공개되지 않습니다. 필수 입력창은 * 로 표시되어 있습니다