원래 클래스 구조를 바꾸지 않고, 내가 필요한 인터페이스 형태로 변환시켜서 통합 관리
서로다른 인터페이스를 가진 클래스들을 함께 작동하게 하고싶을때
기존 코드를 수정하지않고 새 클래스나 라이브러리를 기존 시스템에 맞춰 연결
Adapter 패턴은 레거시를 관리하는 목적이므로 꼭 사용하거나 하지않아도 됨. 테스트용 코드에 잠깐 적용하여 하는 용도로도 사용
Target,Adaptee, Adapter 의 3가지

장점 :기존코드 수정하지않고 새로운 클래스 추가, 인터페이스 연결가능, OCP 준수
단점: 코드가 복잡해짐, 단순히 호환성만 제공하기때문에 근본적인 설계 문제는 해결하지않음
//애초에 override로 설계되었었다면 그렇게 해도되는데
//상속관계를 설계하지 않았었을때 상속관계로 바꾸려하면 힘드므로 이럴때 어뎁터 패턴 사용 고려 가능
public class MonsterManager : MonoBehaviour
{
[SerializeField] private Zombie _zombie;
[SerializeField] private Alien _alien;
private List<IMonster> _monsters = new List<IMonster>();
public void PrintMonsters()
{
_monsters.Add(new ZombieAdapter(_zombie));
_monsters.Add(new AlienAdapter(_alien));
foreach (var mon in _monsters)
{
mon.Attack();
}
Debug.Log("시작3");
}
}
public class Zombie :MonoBehaviour
{
public void Bite()
{
Debug.Log("Zombie Bite");
}
}
public class Alien : MonoBehaviour
{
public void Shoot()
{
Debug.Log("Alien shoot!");
}
}
public interface IMonster
{
public void Attack();
}
public abstract class Adapter<T> : IMonster
{
protected T Adaptee;
public Adapter(T t)
{
Adaptee = t;
}
public abstract void Attack();
}
public class ZombieAdapter : Adapter<Zombie>
{
public ZombieAdapter(Zombie z) : base(z)
{
}
public override void Attack()
{
Adaptee.Bite();
}
}
public class AlienAdapter : Adapter<Alien>
{
public AlienAdapter(Alien a) : base(a)
{
}
public override void Attack()
{
Adaptee.Shoot();
}
}