본문 바로가기

Domain/디자인패턴

[디자인패턴] 어댑터 패턴(Adapter Pattern)

어댑터 패턴(Adapter Pattern)

어댑터라는 말은 흔히 아는 듯 잘 맞지 않는 구조에 대해 호환이 되게끔 하는 것을 의미한다. 객체지향 관점에서는 클래스의 인터페이스를 사용자가 기대하는 인터페이스로 변환하는 패턴이다. 이를 통해 최대한 기존 코드를 유지할 수 있다는 장점이 있다. 단점으로는 사용하기 위해 클래스가 많아지면서 복잡할 수 있고 상속을 사용하기에 유연성이 떨어질 수 있다.

 

 

UML

  • ITarget: 타겟으로 하는 인터페이스 (기존 코드)
  • Client: ITarget 인터페이스를 요구하는 요소를 지닌 클래스
  • Adapter: Adaptee 클래스를 Target 인터페이스에 맞춰주는 클래스
  • Adaptee: ITarget 인터페이스의 요소로 집어넣고 싶은 클래스

 

실제 예시

전 포스팅의 전략 패턴 예시에서 구글 검색창을 예시로 들었다. 해당 검색창에서 동영상을 검색하는 탭이 새로 생겼는데 이 기능은 다른 서비스의 API를 이용하는 부분이라 기존 인터페이스와 호환되지 않는다고 가정하자.

 

기존 전략 패턴 코드

아래는 기존의 검색창에 대한 전략 패턴 코드이다.

interface SearchStrategy{
    fun search()
}

class AllSearchStrategy : SearchStrategy{
    override fun search(){
    	//전체 검색 코드
    }
}
class ImageSearchStrategy : SearchStrategy{
    override fun search(){
    	//전체 검색 코드
    }
}
class NewsSearchStrategy : SearchStrategy{
    override fun search(){
    	//전체 검색 코드
    }
}
class MapSearchStrategy : SearchStrategy{
    override fun search(){
    	//전체 검색 코드
    }
}

 

새로운 동영상 검색 알고리즘

아래는 새로운 동영상 검색 알고리즘에 대한 인터페이스와 클래스이다. 이를 위 전략 패턴 인터페이스에 적용시키는게 목적이다.

interface FindAlgorithm{
    fun find(global:Boolean)
}

class FindVideoAlgorithm : FindAlgorithm{
    override fun find(global:Boolean){
    	// 동영상 검색 알고리즘
    }
}

 

FindAlgorithm을 위한 Adapter 클래스를 생성한다.

이 어댑터 내부에 FindAlgorithm 인터페이스를 정의해주고, 초기화 과정에서 FindVideoAlgorithm을 전달해준다. 그리고 오버라이딩한 search() 메서드에서 FindAlgorithm의 필수 메서드인 find() 메서드를 수행하면 된다.

class SearchFindAdapter(private var findAlgorithm : FindAlgorithm) : SearchStrategy{
    override fun search(){
    	findAlgorithm.find(true)
    }
    
    fun changeFindAlgorithm(_findAlgorithm: FindAlgorithm){
    	findAlgorith = _findAlgorithm
    }
}

 

실제 사용

class MainActivity : AppCompatActivity() {

    private var searchStrategy : SearchStrategy = AllSearchStrategy()
    
    override fun onCreate(savedInstanceState: Bundle?) {
        super.onCreate(savedInstanceState)
        setContentView(R.layout.activity_main)

	setSearchStrategy(SearchFindAdapter(FindVideoAlgorithm()))

        serach_btn.setOnClickListener { 
            searchStrategy.search()
        }
    }
    
    fun setSearchStrategy(_searchStrategy :SearchStrategy){
    	searchStrategy = _searchStrategy
    }
}

 

 

요약

  • 새로운 인터페이스의 로직이 추가되었을 때 기존 인터페이스와 호환 가능하게 하는게 어댑터 패턴이다.
  • 기존 인터페이스를 상속받는 어댑터를 정의하고, 기존 인터페이스의 오버라이딩 메서드에서 새로운 인터페이스의 로직을 수행한다. (새 인터페이스는 변수로 받게 된다)