티스토리 뷰
반응형
Adapter Pattern(Wrapper)
의도
클래스의 인터페이스를 사용자가 기대하는 인터페이스 형태로 적응시킨다. 서로 일치하지 않는 인터페이스를 갖는 클래스들을 함께 동작
side effect
가끔 적응자는 적응 대상 클래스가 제공하지 않는 기능을 제공하는 책임도 지니게 된다.
활용성
기존 클래스를 사용하고 싶은데 인터페이스가 맞지 않을 때
아직 예측하지 못한 클래스나 실제 관련되지 않는 클래스들이 기존 클래스를 재사용하고자 하지만, 이미 정의된 재사용 가능한 클래스가 지금 요청하는 인터페이스를 꼭 정의하고 있지 않을 때. 다시 말해, 이미 만든 것을 재사용하지고자 하나 이 재사용 가능한 라이브러리를 수정할 수 없을 때
[객체 적응자(object adapter)만 해당됨] 이미 존재하는 여러 개의 서브 클래스를 사용해야 하는데, 이 서브클래스들의 상속을 통해서 이들의 인터페이스를 다 개조한다는 것이 현실성이 없을 때, 객체 적응자를 써서 부모 클래스의 인터페이스를 변형하는 것이 더 바람직함
구성요소
- Target: 사용자가 사용할 응용 분야에 종속적인 인터페이스를 정의하는 클래스로서, Shape를 예로 들 수 있다.
- Client: Target 인터페이스를 만족하는 객체와 동작할 대상으로 DrawingEditor를 예로 들 수 있다.
- Adaptee: 인터페이스의 적응이 필요한 기존 인터페이스를 정의하는 클래서로서, 적응 대상자라고 한다.
- Adapter: Target 인터페이스에 Adaptee의 인터페이스를 적응시키는 클래스
결과 (장단점)
- Adapter 클래스는 Adapter 클래스를 Target 클래스로 변형하는데, 이를 위해서 Adaptee 클래스를 상속받아야 하기 때문에, 하나의 클래스와 이 클래스의 모든 서브클래스들을 개조할 때라면 클래스 적응자 방식을 사용할 수 없다. 즉, Adapter는 명시적으로 Adaptee의 서브클래스에 정의된 기능들을 사용할 수 없다.
- Adapter 클래스는 Adaptee 클래스를 상속하기 때문에 Adaptee에 정의된 행동을 재정의할 수도 있다.
- 한 개의 객체(Adapter)만 사용하며, Adaptee로 가기 위한 추가적인 포인터 간접화는 필요하지 않다.
- Adapter 클래스는 하나만 존재해도 수많은 Adaptee 클래스들과 동작할 수 있다. 그 이유는 Adapter 객체가 포함하는 Adaptee에 대한 참조자는 Adaptee의 인스턴스를 관리할 수도 있고, Adaptee 클래스를 상속받는 다른 서브클래스들의 인스턴스도 관리할 수 있기 때문. 하나의 Adapter 클래스로 모든 Adaptee 클래스와 이를 상속받는 서브클래스 모두를 이용할 수 있게 된다.
- Adaptee 클래스의 행동을 재정의하기가 매우 어렵다. 이것을 위해서는 Adaptee 클래스를 상속받아서 새로운 서브클래스를 만들고, Adapter 클래스는 Adaptee 클래스가 아닌 Adaptee 클래스의 해당 서브클래스를 참조하도록 해야 한다.
예시
1. WarriorSkill.java
public interface WarriorSkill {
void attack(String skill);
}
2. MagicianSkill.java
public interface MagicianSkill {
void magicalSpells(String skill);
}
3. Spearman.java
public class Spearman implements WarriorSkill{
@Override
public void attack(String skill) {
System.out.println("창 찌르기 스킬은 "+skill+"입니다.");
}
}
4. Swordman.java
public class Swordsman implements WarriorSkill{
@Override
public void attack(String skill) {
System.out.println("검술 스킬 이름은 "+skill+"입니다.");
}
}
5. BattleMage.java
public class BattleMage implements MagicianSkill{
@Override
public void magicalSpells(String skill) {
System.out.println("마술 스킬 이름은 "+skill+"입니다.");
}
}
6. JobAdapter.java
public class JobAdapter implements WarriorSkill{
private MagicianSkill magicianSkill;
public JobAdapter(MagicianSkill magicianSkill){
this.magicianSkill = magicianSkill;
}
@Override
public void attack(String skill) {
System.out.println("JobAdapter 사용");
magicianSkill.magicalSpells(skill);
}
}
7. Test Case
class SimpleTest {
@Test
void test_adapter_패턴_사용(){
WarriorSkill player = new Swordsman();
player.attack("한 손 찌르기");
player = new Spearman();
player.attack("창 찌르기");
player = new JobAdapter(new BattleMage());
player.attack("매직 크루");
}
}
검술 스킬 이름은 한 손 찌르기입니다.
창 찌르기 스킬은 창 찌르기입니다.
JobAdapter 사용
마술 스킬 이름은 매직 크루입니다.
3. Bonus(단점에 대한 케이스 추가)
만약에 warriorSkill 부분에 powerAttack()이라는 전사 고유의 스킬이 있고 마법사는 사용못하게 된다면 어떻게 처리해야 할까?
public interface WarriorSkill {
void attack(String skill);
void powerAttack();
}
public class JobAdapter implements WarriorSkill{
private MagicianSkill magicianSkill;
public JobAdapter(MagicianSkill magicianSkill){
this.magicianSkill = magicianSkill;
}
@Override
public void attack(String skill) {
System.out.println("JobAdapter 사용");
magicianSkill.magicalSpells(skill);
}
@Override
public void powerAttack() {
throw new RuntimeException("사용할 수 없는 스킬입니다.");
}
}
검술 스킬 이름은 한 손 찌르기입니다.
창 찌르기 스킬은 창 찌르기입니다.
JobAdapter 사용
마술 스킬 이름은 매직 크루입니다.
사용할 수 없는 스킬입니다.
java.lang.RuntimeException: 사용할 수 없는 스킬입니다.
참고: GoF 디자인 패턴
https://nickeman.tistory.com/141
반응형
'knowledge' 카테고리의 다른 글
[JAVA] [Python] 자바의 상속과 파이썬의 상속 비교 (0) | 2021.11.19 |
---|---|
[Pattern][Java][Python] Singleton 생성 패턴에 대하여 (0) | 2021.11.04 |
[Java] Prototype 생성 패턴 (0) | 2021.11.02 |
[git] stash 활용 (0) | 2021.10.28 |
반응형
공지사항
최근에 올라온 글
최근에 달린 댓글
- Total
- Today
- Yesterday
링크
TAG
- 프로그래머스
- DRF
- BFS
- setattr
- 2021 KAKAO BLIND RECRUITMENT
- dockerignore
- 자바
- Linux
- Python
- Command Line
- 파이썬
- 그래프
- Collections
- docker-compose
- 카카오
- thread
- Java
- PostgreSQL
- docker
- 면접
- Spring
- ubuntu
- headers
- Celery
- 백준
- 알고리즘
- django
- postgres
- Pattern
- env
일 | 월 | 화 | 수 | 목 | 금 | 토 |
---|---|---|---|---|---|---|
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 |
글 보관함