게임 개발/디자인 패턴

[디자인패턴] 9. 유니티에서의 어댑터 패턴 퍼사드 패턴

Heesuk Lee 2021. 9. 30. 18:55

이번 챕터에서는 두개의 패턴이 함께 있어서 같이 작성했습니다.

첫번째로 어댑터 패턴입니다.

 

어댑터 패턴 정의

한 클래스의 인터페이스를 클라이언트에서 사용하고자 하는 다른 인터페이스로 변환합니다. 어댑터를 이용하면 인터페이스 호환성 문제 때문에 같이 쓸 수 없는 클래스들을 연결해서 쓸 수 있습니다.

 

유니티에서 예시로는 결제모듈을 예시로 들었습니다. 실제로는 문제 없지만 만약에 AOS와 IOS의 결제 함수명이 다를때를 가정하고 구현했습니다.

// 결제 어댑터 인터페이스
public interface PurchaseAdapter
{
    void Purchase();
}

// AOS 결제 모듈
public class AndroidInApp : PurchaseAdapter
{
    public void Purchase()
    {
        this.InAppPurchase();
    }

    private void InAppPurchase()
    {
        // 실제 결제 함수
        Debug.Log($"AOS 결제 완료");
    }
}

// IOS 결제 모듈
public class IOSPurchase : PurchaseAdapter
{
    public void Purchase()
    {
        this.BuyAppProduct();
    }

    private void BuyAppProduct()
    {
        // 실제 결제 함수
        Debug.Log($"IOS 상품 결제 완료");
    }
}

// 실행부 구현
public class ShopPanel : MonoBehaviour
{
    [SerializeField]
    private Text statusText = null;

    private PurchaseAdapter purchaseAdapter = null;

    public void OnPurchased()
    {
    	// 결제 실행 버튼
        this.purchaseAdapter.Purchase();
        this.statusText.text = $"결제 완료!";
    }

    public void OnChangedAOS()
    {
    	// 안드로이드로 결제 전환
        this.purchaseAdapter = new AndroidInApp();
        this.statusText.text = "AOS 결제";
    }
    public void OnChangedIOS()
    {
    	// IOS로 결제 전환
        this.purchaseAdapter = new IOSPurchase();
        this.statusText.text = "IOS 결제";
    }
}

 

PurchaseAdapter를 상속받은 AOS결제모듈과 IOS결제모듈의 함수가 다른것을 하나로 함수로 합치도록 변경했습니다.

ShopPanel에서 결제가 실행되는 OnPurchase에서 현재 AOS인지 IOS인지 상관없이 PurchaseAdapter.Purchase()를 호출하면 진행되는것을 확인하실 수 있습니다.

 

 

두번쨰는 퍼사드 패턴입니다.

 

퍼사드패턴 정의

어떤 서브시스템의 일련의 인터페이스에 대한 통합된 인터페이스를 제공합니다. 퍼사드 패턴에서는 서브 시스템을 더 쉽게 사용할 수 있게 해 주는 고수준 인터페이스를 정의합니다.

 

유니티에서 자주 볼수있는 아웃게임에서 어떤 창을 띄울때 다른 창들은 꺼줘야하는 상황에 퍼사드 패턴으로 따로 관리하면 켜고끄는것을 관리할 수 있습니다.

 

public class OutGameFacade : MonoBehaviour
{
    [SerializeField]
    private GameObject inventoryPanel = null;
    [SerializeField]
    private GameObject shopPanel = null;
    [SerializeField]
    private GameObject readyPanel = null;
    [SerializeField]
    private GameObject optionPanel = null;
    
    private void Start()
    {
    	// 시작시 모든 패널 비활성화
        this.inventoryPanel.SetActive(false);
        this.shopPanel.SetActive(false);
        this.readyPanel.SetActive(false);
        this.optionPanel.SetActive(false);
    }

    public void OnInventoryPanel()
    {
    	// 인벤토리 패널 활성화
        this.inventoryPanel.SetActive(true);
        this.shopPanel.SetActive(false);
        this.readyPanel.SetActive(false);
        this.optionPanel.SetActive(false);
    }

    public void OnShopPanel()
    {
    	// 상점 패널 활성화
        this.inventoryPanel.SetActive(false);
        this.shopPanel.SetActive(true);
        this.readyPanel.SetActive(false);
        this.optionPanel.SetActive(false);
    }

    public void OnReadyPanel()
    {
    	// 로비 패널 활성화
        this.inventoryPanel.SetActive(false);
        this.shopPanel.SetActive(false);
        this.readyPanel.SetActive(true);
        this.optionPanel.SetActive(false);
    }

    public void OnOptionPanel()
    {
    	// 옵션 패널 활성화
        this.inventoryPanel.SetActive(false);
        this.shopPanel.SetActive(false);
        this.readyPanel.SetActive(false);
        this.optionPanel.SetActive(true);
    }
}

 

다른 화면은 비활성화 해주고 실행한 화면만 활성화 시킵니다.

 

내 코드가 엉망진창이지만 의도한 일을 하긴할때....

 

반응형