💡 퍼사드 패턴(Facade Pattern)
구조적 패턴(Structural Pattern) 중 하나로, 복잡한 서브 시스템의 여러 기능을 쉽게 사용할 수 있도록 통합된 인터페이스를 제공하는 방식이다.
- Facade 객체는 다양한 서브 시스템의 기능을 클라이언트에게 하나의 인터페이스로 제공한다.
- 퍼사드 패턴을 사용하면 서브 시스템을 단순화해 직관적으로 관리할 수 있고, 클라이언트가 내부 구현에 의존하지 않는 유연한 구조를 갖출 수 있다.
- 적용 가능성
- 복잡한 서브 시스템 감추고 싶은 경우
- 서브 시스템과 클라이언트 간의 결합도를 낮추고 싶은 경우
- 서브 시스템의 로직이 자주 변경되는 경우
📍 구조 및 구현
- Facade 클래스 : 클라이언트가 자주 쓰는 기능을 묶은 메서드를 제공함
- Subsystem 클래스 : 실제 로직 담당, Facade 내부에서 생성·주입
- 클라이언트 : Facade의 간단 메서드만 호출
📍 코드
📌 구현 전
1️⃣ 기능 구현
package day16;
// 홈시어터
class Projector{
public void on(){
System.out.println("프로젝터를 켭니다");
}
public void setInput(String source){
System.out.println("프로젝터 입력을 "+ source + "로 설정합니다.");
}
}
class Curtain{
public void on(){
System.out.println("전동커튼이 열립니다.");
}
public void off(){
System.out.println("커튼을 닫습니다.");
}
}
class Amplifier{
public void on(){
System.out.println("앰프를 켭니다. ");
}
public void setVolume(int level){
System.out.println("볼륨을 "+ level + "로 설정합니다. ");
}
}
class MoviePlayer{
public void on(){
System.out.println("MoviePlayer를 켭니다.");
}
public void play(String movie){
System.out.println("영화 "+ movie + " 를 재생합니다. ");
}
}
2️⃣ 동작 구현
public class FacadeDemo {
public static void main(String[] args) {
Curtain curtain = new Curtain();
MoviePlayer moviePlayer = new MoviePlayer();
Amplifier amplifier = new Amplifier();
Projector projector = new Projector();
// 영화 시청
curtain.off();
projector.on();
projector.setInput("넷플릭스");
amplifier.on();
amplifier.setVolume(5);
moviePlayer.on();
moviePlayer.play("해리 포터");
}
}
📌 구현 후
package day16;
//기능부 아래 추가·변경
class HomeTheaterFacade{
private Curtain Curtain;
private MoviePlayer moviePlayer;
private Amplifier amplifier;
private Projector projector;
public HomeTheaterFacade(Curtain curtain, MoviePlayer moviePlayer, Amplifier amplifier, Projector projector){
this.curtain = curtain;
this.moviePlayer = moviePlayer;
this.amplifier = amplifier;
this.projector = projector;
}
public void watchMovie(String movie){
System.out.println("영화를 보기위한 준비를 시작합니다.");
curtain.off();
projector.on();
projector.setInput("넷플릭스");
amplifier.on();
amplifier.setVolume(5);
moviePlayer.on();
moviePlayer.play(movie);
System.out.println("준비가 끝났어요. 즐거운 시간^^");
}
public void endMovie(){
System.out.println("영화가 종료되었습니다. ");
System.out.println("장비를 모두 끕니다. ");
}
}
public class FacadeDemo {
public static void main(String[] args) {
Curtain curtain = new Curtain();
MoviePlayer moviePlayer = new MoviePlayer();
Amplifier amplifier = new Amplifier();
Projector projector = new Projector();
HomeTheaterFacade homeTheater = new HomeTheaterFacade(curtain,moviePlayer,amplifier,projector);
homeTheater.watchMovie("해리 포터");
//영화 상영 끝
homeTheater.endMovie();
}
}
- 클라이언트 : home.watchMovie 1번 호출
- Facade : 내부에서 처리 수행
- Subsystem: : 실제 로직 실행, Facade가 호출
💡 전략 패턴(Strategy Pattern)
행위 패턴(Behavioral Pattern) 중 하나로, 동일한 목적의 작업을 다양한 방식으로 수행할 수 있도록 설계**하는 방식이다.**
- Strategy 패턴은 같은 목적을 가진 방법들을 쉽게 추가 및 교체할 수 있도록 설계하여 코드의 유지 보수성과 확장성을 높인다.
- 적용 가능
- 여러 알고리즘 중 하나를 동적으로 선택해야 하는 경우
- 알고리즘의 변경이 잦고, 코드 수정 범위를 최소화시키는 경우
- 조건문을 통한 분기점을 제거해 가독성을 높이고 싶은 경우
- 알고리즘을 독립적으로 테스트·재사용하고 싶은 경우
📍 구조 및 구현
- Strategy 인터페이스 정의
- ConcreteStrategy : 각 알고리즘을 별도 클래스로 구현
- Context : Strategy 인터페이스 타입을 참조해, 메서드 호출 시 해당 알고리즘 실행
- 클라이언트 : 필요에 따라 전략 개체를 생성해 Context에 주입
- 유연한 전략 교체 : 런타임에 setStrategy()로 다른 구현체 끼워넣음
📍 코드
package day16;
// Strategy 인터페이스: 문자열을 변환하는 알고리즘
interface TextStrategy {
String formatText(String input);
}
// ConcreteStrategy A: 문자열을 모두 대문자로 변환
class UpperCaseStrategy implements TextStrategy {
@Override
public String formatText(String input) {
return input.toUpperCase();
}
}
// ConcreteStrategy B: 문자열을 모두 소문자로 변환
class LowerCaseStrategy implements TextStrategy {
@Override
public String formatText(String input) {
return input.toLowerCase();
}
}
// ConcreteStrategy C: 문자열 양 끝에 * 추가
class StarSurroundStrategy implements TextStrategy {
@Override
public String formatText(String input) {
return "*" + input + "*";
}
}
// Context 클래스: 작업 수행
class TextFormatter {
private TextStrategy strategy;
public TextFormatter(TextStrategy strategy) {
this.strategy = strategy;
}
public void setStrategy(TextStrategy strategy) {
this.strategy = strategy;
}
public String format(String input) {
return strategy.formatText(input);
}
}
// 클라이언트 코드: 런타임에 메소드 교체해 문자열을 포맷팅
public class StrategySample {
public static void main(String[] args) {
// Strategy A
TextFormatter formatter = new TextFormatter(new UpperCaseStrategy());
System.out.println(formatter.format("Hello Strategy Pattern"));
// 결과: "HELLO STRATEGY PATTERN"
// Strategy B
formatter.setStrategy(new LowerCaseStrategy());
System.out.println(formatter.format("Hello Strategy Pattern"));
// 결과: "hello strategy pattern"
// Strategy C
formatter.setStrategy(new StarSurroundStrategy());
System.out.println(formatter.format("Hello Strategy Pattern"));
// 결과: "*Hello Strategy Pattern*"
}
}
- 런타임(프로그램 실행 시점)에 전략을 자유롭게 교체 가능(setStrategy)
- 조건문 없이 필요한 알고리즘만 구현 후 Context에 주입
- 전략 추가 시 기존 코드 거의 수정 없이 확장 가능
'🏕 멋사 Java 백엔드 13기 > TIL' 카테고리의 다른 글
250121 TIL | AOP (2) | 2025.01.21 |
---|---|
240117 TIL : DI (1) | 2025.01.17 |
[멋쟁이사자처럼 부트캠프 TIL 회고] 백엔드 Java 부트캠프 12일차 | DB (2) | 2024.12.17 |
[멋쟁이사자처럼 부트캠프 TIL 회고] 백엔드 Java 부트캠프 11일차 | DB (1) | 2024.12.16 |
[멋쟁이사자처럼 부트캠프 TIL 회고] 백엔드 Java 부트캠프 8일차 (1) | 2024.12.11 |