CS/디자인패턴

[디자인패턴] Facade 패턴( 파싸드 패턴, 간단한 창구)

mabb 2023. 6. 22. 15:06
반응형

▶디자인 패턴 ( Design Pattern)

:프로그램 개발 시 문제 해결을 위하여 빈번히 사용되는 개발자들의 경험, 내적인 축적에 대하여,
GoF(Gang of Four) 라 불리는 4인의 개발자들이 각각을 패턴으로 정의하고 이름을 붙였다.
이를 디자인 패턴 (Design Pattern) 이라고 한다.
 23개의 디자인 패턴을
『Elements of Reusable Object-Oriented Software』
라는 책으로 발간하였다.

Gang of Four 분들은 모두 안경을 썼다.

 

▷디자인 패턴의 용어를 빌리면 서로의 아이디어를 보다 용이하게 비교, 논의할 수 있게 된다.
▷재사용과 기능확장이 쉬운 소프트웨어를 만들기 위한 유익한 기법이 바로 디자인 패턴이다.

 

---------------------------------------------------------
1. Iterator
2. Adapter
3. Template Method
4. Factory Method
5. Singleton
6. Prototype
7. Builder
8. Abstract Factory
9. Bridge
10. Strategy
11. Composite
12. Decorator
13. Visitor
14. Chain of Responsibility
15. Facade
16. Mediator
17. Observer
18. Memento
19. State
20. Flyweight
21. Proxy
22. Command
23. Interpreter
---------------------------------------------------------

▶Facade 패턴

"복잡한 기능들, 이것만 호출하면 OK 인터페이스"
"복잡한 것을 처리해 주는 간단한 창구"


-왜 사용하는가
-클래스다이어그램
-각 클래스(인터페이스)의 역할
-Java소스

▶Facade 패턴에 대한 이해

-간단한 창구 역할  

-뒷 단의 로직은 복잡하지만 이것만 호출하면 OK가 되는 인터페이스

-Facade는 건물의 '정면'이라는 뜻이다.

-프로그램은 점점 커지고 복잡해지고 메소드를 정확하게 순서대로 호출할 필요가 있다. 이 복잡한 과정을 앞단의 단순한 인터페이스가 처리해 준다.

-높은 레벨에서 단순한 인터페이스를 외부에 제공한다.

-파싸드의 인터페이스는 되도록 적게 하는 것이 좋다.

-클래스를 지나치게 외부로 노출하는 것은 좋지 않다.

-파싸드 패턴을 더 큰 단위에서 재귀적으로 적용할 수 있다.

-상당히 큰 시스템의 요소요소에 파싸드 패턴을 적용하면 시스템이 편리해진다.

-★확실하게 언어로 표현할 수 있는 노하우는 프로그래머의 머릿속에 숨겨둘 것이 아니라 코드로 표현해야 한다.

 

▶왜 사용하는가

거대하고 복잡한 클래스들의 관계 속에서 메서드들을 정확하게 순서대로 실행시켜 기능을 구현해야 할 때가 있다. 이때 내부의 복잡한 로직들을 정확하게 처리해 주는 단순한 창구(인터페이스)를 만들면 시스템이 편리해진다. 이 단순한 창구 역할을 하는 것이 Facade 패턴이다.

▶클래스다이어그램

Facade 패턴의 클래스다이어그램

 

▶각 클래스(인터페이스)의 역할

▷클라이언트 역할

 내부의 복잡한 구조는 모른다. 파싸드를 이용하여 손쉽게 요청하고 결과를 얻는 역할이다.

▷파싸드 역할 (창구)

뒷 단의 복잡한 기능을 도맡아서 순서대로 정확하게 특정한 기능을 수행하고 앞 단에는 아주 간단한 인터페이스만 보여준다.

▷복잡한 기능들 역할

내부적으로 복잡하고, 정확한 순서로 메서드를 호출하여 기능을 구현하여야 하는 상태이다. 이 기능들 자체는 파싸드를 전혀 알지 못한다. 

▶Java 소스

*java1.8 이전 버전을 사용하는 교재를 참고하였습니다.
Java API 문서 등을 참조하여 제네릭을 적용하는 등 소스를 개선할 필요가 있습니다.
(https://docs.oracle.com/en/java/javase/20/docs/api/)

▷클라이언트 역할 - Main.java

package main.java.designpattern.facade;

public class Main {
    public static void main(String[] args){
        PageMaker.makeWelcomePage("mbk1991@naver.com","test");
    }
}

 

▷파싸드 역할 (창구) - PageMaker.java

package main.java.designpattern.facade;

import java.io.File;
import java.io.FileWriter;
import java.io.IOException;
import java.util.Properties;

public class PageMaker {
    private PageMaker(){}
    public static void makeWelcomePage(String mailAddr, String fileName){
        try{
            Properties mailProp = Database.getProperties(fileName);
            String userName = mailProp.getProperty(mailAddr);

            fileName = fileName + ".html";
            File file = new File(fileName);

            if(!file.exists()){
                file.createNewFile();
            }
            HtmlWriter writer = new HtmlWriter(new FileWriter(file));
            writer.title("Welcome to " + userName + " 's Page!");
            writer.paragraph(userName + " 의 페이지입니다.");
            writer.mailTo(mailAddr, userName);
            writer.close();
            System.out.println("html파일이 생성되었습니다.");

        }catch(IOException e){
            e.printStackTrace();
        }
    }
}

 

▷복잡한 기능들 역할

DataBase.java

package main.java.designpattern.facade;

import java.io.File;
import java.io.FileInputStream;
import java.io.IOException;
import java.util.Properties;

public class Database {
    private Database(){}
    public static Properties getProperties(String dbname){
       String fileName = dbname + ".txt";
       File file = new File(fileName);
       if(!file.exists()){
           System.out.println("파일이 존재하지 않습니다. 새롭게 생성합니다.");
           try {
               file.createNewFile();
           } catch (IOException e) {
               e.printStackTrace();
           }
       }else{
           //System.out.println("파일이 존재합니다.");
           //System.out.println("경로 : " + file.getAbsolutePath());
       }
       Properties prop = new Properties();
       try{
           prop.load(new FileInputStream(file));
       }catch(IOException e){
           System.out.println("Warning: " + fileName + "is not found.");
       }
       return prop;
    }
}

 

HtmlWriter.java

package main.java.designpattern.facade;

import java.io.Writer;
import java.io.IOException;

public class HtmlWriter {
    private Writer writer;
    public HtmlWriter(Writer writer){
        this.writer =writer;
    }
    public void title(String title) throws IOException{
        writer.write("<html>");
        writer.write("<head>");
        writer.write("<title>"+ title +"</title>");
        writer.write("</head>");
        writer.write("<body>\n");
        writer.write("<h1>"+ title +"</h1>\n");
    }
    public void paragraph(String msg) throws IOException{
        writer.write("<p>"+ msg +"</p>\n");
    }
    public void link(String href, String caption) throws IOException{
        paragraph("<a href='" + href + "'>" + caption + "</a>");
    }
    public void mailTo(String mailAddr, String userName) throws IOException{
        link("mailTo: " + mailAddr, userName);
    }
    public void close() throws IOException{
        writer.write("</body>");
        writer.write("</html>\n");
        writer.close();
    }
}

---------------------------------------------------------
※참고자료
-Java언어로 배우는 디자인 패턴 입문
-Headfirst Design Pattern
-나무위키, 위키백과, 네이버백과
-리팩토링구루(https://refactoring.guru/ko)

반응형