일 | 월 | 화 | 수 | 목 | 금 | 토 |
---|---|---|---|---|---|---|
1 | 2 | 3 | 4 | 5 | 6 | 7 |
8 | 9 | 10 | 11 | 12 | 13 | 14 |
15 | 16 | 17 | 18 | 19 | 20 | 21 |
22 | 23 | 24 | 25 | 26 | 27 | 28 |
29 | 30 | 31 |
- 안드로이드 유닛테스트란
- rxjava cold observable
- android ar 개발
- 안드로이드 레트로핏 사용법
- 클래스
- 객체
- 스택 자바 코드
- 안드로이드 레트로핏 crud
- Rxjava Observable
- ar vr 차이
- rxjava disposable
- 플러터 설치 2022
- jvm 작동 원리
- 서비스 vs 쓰레드
- 안드로이드 라이선스
- 서비스 쓰레드 차이
- 안드로이드 유닛 테스트 예시
- 2022 플러터 안드로이드 스튜디오
- 안드로이드 os 구조
- 자바 다형성
- 안드로이드 유닛 테스트
- rxjava hot observable
- android retrofit login
- 안드로이드 라이선스 종류
- 스택 큐 차이
- ANR이란
- 2022 플러터 설치
- jvm이란
- 큐 자바 코드
- 멤버변수
- Today
- Total
나만을 위한 블로그
자바 - 퍼사드 패턴(Facade Pattern)이란? 본문
파카드 패턴이라고 읽을 것 같은데 퍼사드라고 읽는다
이번 포스팅에선 디자인 패턴 중 퍼사드 패턴에 대해서 포스팅해보려고 한다.
그 전에 퍼사드는 무슨 뜻이 있는지 먼저 확인해보자.
Facade : (건물의) 정면, 앞면 / (실제와 다른) 표면, 허울
정면이거나 진짜가 아닌 다른 것? 정도의 뜻이 있는 듯하다.
다음은 영문 위키백과의 내용이다.
(중략) 건축의 파사드와 유사하게 파사드는 더 복잡한 기본 또는 구조 코드를 마스킹하는 전면 인터페이스 역할을 하는 객체다. 퍼사드는 아래의 내용들을 수행할 수 있다.
- 단일(또는 단순화된) API 뒤에 있는 더 복잡한 구성요소와의 상호작용을 마스킹해서, 소프트웨어 라이브러리의 가독성과 유용성을 개선
- 일반적인 기능에 대한 컨텍스트 별 인터페이스 제공
- 느슨하게 결합된 코드를 선호하는 모놀리틱(Monolithic) 또는 긴밀하게 결합된 시스템의 광범위한 리팩토링을 위한 시작점 역할
개발자는 시스템이 복잡하거나 상호의존적인 클래스가 많아서, 또는 소스코드를 사용할 수 없을 때 퍼사드 패턴을 사용한다. 이 패턴은 더 큰 시스템의 복잡성을 숨기고 클라이언트에 더 간단한 인터페이스를 제공한다. 일반적으로 클라이언트에 필요한 구성원 집합을 포함하는 단일 래퍼 클래스가 포함된다. 이 멤버는 Facade 클라이언트를 대신하여 시스템에 액세스하고 구현 세부 사항을 숨긴다
대충 소스코드가 복잡할 때 인터페이스 써서 만드는 패턴인 듯하다.
다른 포스팅에선 퍼사드 패턴을 어떻게 설명하는지 확인해보자.
- 어떤 서브시스템의 인터페이스에 대한 통합된 인터페이스를 제공한다. 퍼사드에서 고수준의 인터페이스를 제공하기 때문에, 서브시스템을 더 쉽게 쓸 수 있다
- 퍼사드 패턴은 어떤 소프트웨어의 다른 커다란 코드 부분에 대해 간략화된 인터페이스를 제공하는 디자인 패턴이다. 복잡한 소프트웨어 바깥에 있는 코드가 라이브러리의 내부 코드에 의존하는 정도를 낮춰 주고, 복잡한 소프트웨어를 쓸 수 있도록 간단한 인터페이스를 제공한다
- 여러 메서드를 써서 하나의 단순한 기능을 수행하는 인터페이스를 만드는 패턴이다. 사용자가 객체의 여러 기능을 더 쉽게 사용할 수 있게 한다
세탁기, 건조기 등 가전제품을 예시로 생각할 수 있을 듯하다.
건조기를 예로 들면 나는 건조기에 빨래를 넣고 버튼만 누르면 된다. 패딩이면 패딩용, 이불이면 이불용 등등 필요하면 다른 옵션을 누르면 된다.
이 때 나는 건조기가 어떤 작동원리로 동작하는지 따위 알 필요 없다. 누르기 전에 매뉴얼을 보면서 작동원리를 이해해서 작동시켜야 한다면 그냥 자연건조 시키고 말지.
그래서 건조기 제조사들은 사람들이 단순한 버튼으로 건조기를 작동시킬 수 있도록 인터페이스를 제공한다.
말 나온 김에 건조기로 퍼사드 패턴의 예시를 들어보려고 한다. 건조기의 구성과 기능은 아래와 같다고 가정한다.
타이머 | 정해진 시간이 되면 건조기의 작동을 멈춘다 |
건조기 | 빨래를 건조시킨다 |
먼지받이 | 건조 과정에서 나오는 먼지를 모아둔다 |
회전통 | 통을 회전시킨다 |
일단 건조기를 켜야 하니까 건조기의 전원을 켜고 끄는 전원이 하나 있어야 할 것이다.
이 전원을 인터페이스로 만들면 아래 형태가 될 것이다.
// 전원
public interface PowerSupply
{
public void on();
public void off();
}
나머지 4개를 만든다면 아래처럼 만들 수 있다.
// 건조기
public class DryingMachine implements PowerSupply
{
@Override
public void on()
{
System.out.println("건조기 작동 시작...");
}
@Override
public void off()
{
System.out.println("...건조기 작동 종료");
}
}
// 먼지받이
public class DustAcceptor implements PowerSupply
{
@Override
public void on()
{
System.out.println("먼지받이 작동 시작...");
}
@Override
public void off()
{
System.out.println("...먼지받이 작동 종료");
}
}
// 회전통
public class Rumbler implements PowerSupply
{
@Override
public void on()
{
System.out.println("회전통 작동 시작...");
}
@Override
public void off()
{
System.out.println("...회전통 작동 종료");
}
}
// 타이머
public class MachineTimer implements PowerSupply
{
public static long TIME_INTERVAL = 1000;
private int finishTime;
private Timer timer;
private TimerTask task;
int count = 0;
MachineFacade facade;
public MachineTimer(int sec, MachineFacade facade)
{
this.finishTime = sec;
this.count = finishTime / 1000;
this.facade = facade;
timer = new Timer();
this.facade = facade;
task = new TimerTask()
{
@Override
public void run()
{
if (count > 0)
{
System.out.println("[Timer] " + (count--) + "초 남았습니다");
}
else
{
System.out.println("[Timer] 건조가 완료되었습니다");
timer.cancel();
facade.off();
}
}
};
}
@Override
public void on()
{
timer.schedule(task, 0, TIME_INTERVAL);
}
@Override
public void off()
{
timer.cancel();
}
}
이제 이것들을 일일이 작동시키려면 클래스 객체를 만들어 on()을 모두 호출해야 한다.
이 때 퍼사드 패턴을 쓰면 건조기 버튼 한 번 누르는 것으로 건조기를 작동시킬 수 있다.
아래는 퍼사드 패턴을 적용한 클래스다.
public class MachineFacade
{
DryingMachine dryingMachine;
Rumbler rumbler;
DustAcceptor dustAcceptor;
MachineTimer timer;
PowerSupply[] supplies;
boolean isActive = false;
public MachineFacade(DryingMachine dryingMachine, Rumbler rumbler, DustAcceptor dustAcceptor, MachineTimer timer)
{
this.dryingMachine = dryingMachine;
this.rumbler = rumbler;
this.dustAcceptor = dustAcceptor;
this.timer = timer;
supplies = new PowerSupply[]{dryingMachine, rumbler, dustAcceptor, timer};
}
public MachineFacade()
{
dustAcceptor = new DustAcceptor();
rumbler = new Rumbler();
dryingMachine = new DryingMachine();
timer = new MachineTimer(3000, this);
supplies = new PowerSupply[]{dryingMachine, rumbler, dustAcceptor, timer};
}
public void on()
{
for (int i = 0; i < supplies.length; ++i)
{
supplies[i].on();
}
isActive = true;
}
public void off()
{
for (int i = 0; i < supplies.length; i++)
{
supplies[i].off();
}
isActive = false;
}
}
이제 메인 클래스를 만들고 여기에 퍼사드 클래스의 객체를 만들어 on()만 호출하면 건조기가 작동하게 될 것이다.
public class Main
{
public static void main(String[] args)
{
MachineFacade facade = new MachineFacade();
facade.on();
}
}
메인의 결과는 아래와 같다.
건조기가 마지막에 종료돼야 하는데 순서가 좀 이상하지만 예제니까 넘어가자. 아무튼 이런식으로 on()을 한번 호출한것으로 다른 클래스의 on()들과 타이머를 시작시켜 건조기가 작동하는 것처럼 만들 수 있다.
주의할 것은 퍼사드 클래스가 서브 시스템 클래스들을 캡슐화하는 것은 아니다. 기능 편하게 쓰라고 인터페이스를 제공할 뿐이다.
'개인 공부 > 디자인 패턴' 카테고리의 다른 글
빌더(Builder) 패턴이란? (0) | 2022.01.02 |
---|---|
팩토리 패턴이란? (0) | 2021.10.05 |
[MVVM] MutableLiveData와 LiveData 차이 (0) | 2021.04.24 |
[Android] 관찰자(Observer) 패턴이란? (0) | 2021.04.11 |
MVC 패턴이란? (0) | 2020.11.27 |