본문 바로가기
DesignPattern

[Design Pattern] Facade Pattern

by 봄석 2019. 10. 8.

[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

 

qjatjr1108/DesignPattern

DesignPattern Sample. Contribute to qjatjr1108/DesignPattern development by creating an account on GitHub.

github.com

 

댓글