[Design Pattern] Facade Pattern
Facade Pattern이란?
Facade는 '건물의 정면'을 의미합니다.
Facade는 클래스 라이브러리 같은 어떤 소프트웨어의 다른 커다란 코드 부분에 대한 간략화된 인터페이스를 제공하는 객체입니다.
말이 어려운데 예를 보는 것이 더 빠를 것 같습니다.
영화 시청하기(Java Facade Pattern)
어떤 사람이 영화를 시청하기 위해 아래와 같은 과정을 거친다 합시다.
팝콘 준비-> TV 켜기 -> 영화 검색 -> 영화 결제 -> 영화 재생
Snack snack = new Snack("popcon);
RemoteControl remote= new RemoteControl();
Movie movie = new Movie("joker");
snack.Prepare();
remote.turnOn();
movie.searchMovie();
movie.chargeMovie();
movie.playMovie();
영화를 시청하기 위해서는 위처럼 복잡한 내용을 통해야 영화를 볼 수 있습니다.
이것을 간략화하기 위하여 퍼사드 객체가 등장하게 되는데,
퍼사드 패턴은 이런 영화를 보기 위해 사용하는 서브클래스들 사이의 간단한 통합 인터페이스를 제공하는 역할을 합니다.
Apply Facade Pattern
public class RemoteControl {
public void turnOn()
{
System.out.println("TV를 켜다");
}
public void turnOff()
{
System.out.println("TV를 끄다");
}
}
public class Movie {
private String name="";
public Movie(String name)
{
this.name = name;
}
public void searchMovie()
{
System.out.println(name+" 영화를 찾다");
}
public void chargeMovie()
{
System.out.println("영화를 결제하다");
}
public void playMovie()
{
System.out.println("영화 재생");
}
}
public class Snack {
private String name="";
public Snack(String name)
{
this.name = name;
}
public void Prepare()
{
System.out.println(name+" 간식 준비 완료 ");
}
}
public class Facade {
private String snackName ="";
private String movieName="";
public Facade(String snackName,String movieName)
{
this.snackName=snackName;
this.movieName=movieName;
}
public void viewMovie()
{
Snack snack = new Snack(snackName);
RemoteControl remote= new RemoteControl();
Movie movie = new Movie(movieName);
snack.Prepare();
remote.turnOn();
movie.searchMovie();
movie.chargeMovie();
movie.playMovie();
}
}
public class Client {
public static void main(String[] args) {
Facade facade= new Facade("popcon","joker");
facade.viewMovie();
}
}
파사드 패턴을 사용하면 위의 클라이언트 main안의 viewMovie() 함수 하나만 호출하면
간식 준비, TV 켜기, 영화 검색, 영화 구입, 영화보기를 모두 진행할 수 있습니다.
즉 서브클래스에 대하여 알 필요가 없어지는 것입니다.
퍼사드 객체는 복잡한 소프트웨어 바깥쪽의 코드가 라이브러리의 안쪽 코드에 의존하는 일을 감소시켜 주고,
복잡한 소프트웨어를 사용할 수 있게 간단한 인터페이스를 제공해줍니다.
복합시스템 저장소(Kotlin Facade Pattern)
class ComplexSystemStore(private val filePath: String) {
private val cache: HashMap<String, String>
init {
println("Reading data from file: $filePath")
cache = HashMap()
//read properties from file and put to cache
}
fun store(key: String, payload: String) {
cache[key] = payload
}
fun read(key: String): String = cache[key] ?: ""
fun commit() = println("Storing cached data: $cache to file: $filePath")
}
복합시스템 저장소 클래스는 파일의 경로를 저장하고, 읽고 , 커밋합니다.
data class User(val login: String)
class UserRepository {
private val systemPreferences = ComplexSystemStore("/data/default.prefs")
fun save(user: User) {
systemPreferences.store("USER_KEY", user.login)
systemPreferences.commit()
}
fun findFirst(): User = User(systemPreferences.read("USER_KEY"))
}
UserRepository가 바로 Facade객체로 만들어질 클래스입니다.
save 함수 안에서는 서브클래스의 내용 store와 commit을 진행합니다.
class FacadeTest {
@Test
fun Facade() {
//given
val userRepository = UserRepository()
val user = User("bjso")
//when
userRepository.save(user)
//then
Assert.assertThat(user,CoreMatchers.`is`(userRepository.findFirst()))
}
}
클라이언트에서 Facade패턴이 적용된 인스턴스 userRepository를 생성하고 save를 호출합니다.
그리고 첫 번째 데이터를 찾아 출력하여봅니다.
Reading data from file: /data/default.prefs
Storing cached data: {USER_KEY=bjso} to file: /data/default.prefs
save를 호출하였을 때 , 위와 같이 store와 commit 함수가 호출된 로그가 쌓이고 ,
마지막으로 findFirst를 호출하였을 때 저장된 User가 일치합니다.
정리
Pacade Pattern을 사용하였을 때는
복잡한 서브클래스에 대하여 알 필요가 없고
퍼사드 객체는 복잡한 소프트웨어 바깥쪽의 코드가 라이브러리의 안쪽 코드에 의존하는 일을 감소시켜 주고,
복잡한 소프트웨어를 사용할 수 있게 간단한 인터페이스를 제공해줍니다.
소스코드 보러가기
https://github.com/qjatjr1108/DesignPattern
'DesignPattern' 카테고리의 다른 글
[Design Pattern] Proxy Pattern (4) | 2019.10.08 |
---|---|
[Design Pattern] Decorator Pattern (2) | 2019.10.08 |
[Design Pattern] Adapter Pattern (4) | 2019.10.07 |
[Design Pattern] Prototype pattern (2) | 2019.09.27 |
factory method pattern vs abstract factory pattern 차이 알아보기 (6) | 2019.09.18 |
댓글