# Adapter Pattern
딤 이블(Deam Evil)은 기사의 결투 시합 게임을 한다. 상금은 10만 달러이다.
"만약 당신들이 시스템을 깨고 나의 중무장한 코만도를 이 시합에 넣어 주면 상금의 반을 주겠소."
페드로: 드디어 재밌는 일을 하게 되네요.
이브: 시합을 보는 것은 재밌죠. 특히 M16과 철검의 대결이라면…
페드로: 기사들은 좋은 갑옷을 입고 있어요.
이브: F1 수류탄한테는 갑옷은 소용 없어요.
페드로: 신경쓸 거 없어요, 우리는 일을 하고, 돈을 받으면 돼요.
이브: 5만 달러 - 괜찮은 액수네요.
페드로: 네, 이것을 보세요, 시합 시스템의 소스를 훔쳤어요. 소스를 고칠 수는 없지만, 약점을 찾을 수 있어요.
이브: 여기 있어요.
public interface Tournament {
void accept(Knight knight);
}
페드로: 아하! 시스템은 Knight 인터페이스로 들어오는 입력 타입만을 검사하고 있어요. 우리는 그저 commando를 기사로 맞추어 넣기(adapt)만 하면 돼요. 기사가 어떤 모양인지 봅시다.
interface Knight {
void attackWithSword();
void attackWithBow();
void blockWithShield();
}
class Galahad implements Knight {
@Override
public void blockWithShield() {
winkToQueen();
take(shield);
block();
}
@Override
public void attackWithBow() {
winkToQueen();
take(bow);
attack();
}
@Override
public void attackWithSword() {
winkToQueen();
take(sword);
attack();
}
}
페드로: 코만도를 받기 위해서 이전 구현 코드를 가져옵시다.
class Commando {
void throwGrenade(String grenade) { }
shot(String rifleType) { }
}
페드로: 그리고 코만도를 기사로 맞추어 줍니다.
class Commando implements Knight {
@Override
public void blockWithShield() {
// commando don't block
}
@Override
public void attackWithBow() {
throwGrenade("F1");
}
@Override
public void attackWithSword() {
shotWithRifle("M16");
}
}
페드로: 됐어요.
이브: 클로저로는 더 쉬워요.
페드로: 정말로요?
이브: 클로저는 타입을 쓰지 않아서 타입 검사는 전혀 동작하지 않죠.
페드로: 그러면 기사를 어떻게 코만도로 바꾸죠?
이브: 기본적으로 기사란 무엇이죠? 그것은 맵이죠, 데이타와 행위로 된.
{:name "Lancelot"
:speed 1.0
:attack-bow-fn attack-with-bow
:attack-sword-fn attack-with-sword
:block-fn block-with-shield}
이브: 코만도를 기사로 맞추기 위해서는 단지 원래의 것 대신 코만도의 함수를 전달하면 되요.
{:name "Commando"
:speed 5.0
:attack-bow-fn (partial throw-grenade "F1")
:attack-sword-fn (partial shot "M16")
:block-fn nil}
페드로: 우리는 돈을 어떻게 나눌까요?
이브: 50 대 50
페드로: 내가 더 많은 코드를 작성했으니, 전 70을 원해요.
이브: 오케이, 70 대 70
페드로: 좋아요.