[Design Pattern] 어댑터 패턴

이재훈·2023년 8월 16일
1

디자인패턴

목록 보기
1/6

자주 사용되는 디자인 패턴

어댑터 패턴?


우리가 실생활에서 사용하는 여행용 어댑터입니다. 220V를 110V로 변환시켜줍니다.

프로그래밍적으로 접근해보겠습니다.

포트 모양의 변경 -> 인터페이스 변경
220V와 110V 사이의 변환 -> 호환을 위한 추가적인 동작

어댑터 패턴은 이 두가지를 다 수행합니다.

어댑터 패턴이 적용될 수 있는 상황

public class FileStorage {
    public File openFile(String fileName) {
        // 파일을 여는 코드
    }
    
    public String readFile(File file) {
        // 파일을 읽는 코드
    }
    public void saveFile(File file, String outputStr) {
        // 파일을 저장하는 코드
    }
}

기존에 프로젝트에서 FileStorage를 데이터베이스처럼 사용하고 있다고 가정해보겠습니다. 서비스는 커지고 이 코드를 사용하는 곳이 점점 늘어났습니다.

이 구성은 의존 역전에 대해 위반을 하고 있습니다. 저수준 컴포넌트를 고수준 컴포넌트가 의존하고 있기 때문입니다. 이제 interface를 사용하여 코드를 리팩토링 하기로 결정하였습니다. 하지만 문제가 있습니다. FileStorage는 사실 직접 개발한게 아닌 외부 라이브러리를 가져다 사용하고 있었다는 것 입니다. ㅇ0ㅇ

따라서 FileStorage는 직접 수정하지 못합니다. 이 때 어댑터 패턴을 사용하여 문제를 해결할 수 있습니다.

FileStorage와 Repository(interface) 중간에 FileStorageAdapter 클래스를 만들고 아래와 같은 예시로 작성합니다.

interface Repository {
	User findById(Long id);
    void save(User user);
}
class FileStorageAdapter implements Repository {
	private FileStorage fileStorage = new FileStorage();
    private String fileName = "anythingFile";
    
    @Overrid
    public User findById(Long id) {
    	File file = fileStorage.openFile(fileName);
        String fileContent = fileStorage.readFile(file);
        
        // ... convert User
    
    	return user;
    }

	@Override
    public void save(User user) {
    	File file = fileStorage.openFile(fileName);
        String fileContent = fileStorage.readFile(file);
        
        fileStorage.saveFile(file, fileContent);
    }

}

해당 코드는 인터페이스와 FileStorage 사이에 어댑터 역할을 해주는 클래스입니다. 해당 클래스가 없었다면 서비스 클래스 여기저기에 이런 코드들이 있었을 것입니다.

어댑터 패턴이 적용되면서 생기는 장점


더이상 Service 클래스는 FileStorage 클래스를 의존하지 않게 됩니다. DIP를 지키는 코드가 된 것입니다.

이제는 Service는 FileStorage의 복잡한 인터페이스가 아닌 간결해진 Repository 인터페이스를 사용하게 되었습니다. 이것은 Service의 가독성을 크게 올렸을 것입니다. File에 저장하는 복잡한 로직도 FileStorage 안에 캡슐화가 이루어졌습니다.

이제 Repository 인터페이스가 있기 때문에 확장에 열려있게 되었습니다. 데이터베이스를 사용하게 되더라도 Repository를 구현한 클래스를 만들고 그 안에 코드를 작성하면 되게 됩니다. 이제 OCP 역시 만족하게 되었습니다.

어댑터 패턴이 보호하고자 하는 것

어댑터 패턴은 일반적으로 손대기 어려운 코드나 외부 라이브러리를 우리 코드에서 사용할 때, 동일한 인터페이스로 사용하고 싶을 때 사용하게 됩니다.

어댑터 패턴은 Service를 보호해줍니다. 디자인 패턴을 배울 때는 어떤 것을 보호해야하는지가 굉장히 중요합니다.

결론

외부 라이브러리나 손대기 어려운 코드를 두고 그 중간에 인터페이스를 바꾸고 호환을 위한 추가적인 동작을 추가하여 코드를 객체지향적으로 바꿉니다. 이로 인해서, SOLID 원칙의 개방 폐쇄 원칙과, 의존 역전의 원칙을 지킬 수 있게 됩니다.


해당 게시글은 프로그래머스 스쿨 강의
"실무 자바 개발을 위한 OOP와 핵심 디자인 패턴(푸)"
를 정리한 내용입니다. 쉽게 잘 설명해주시니 여러분도 강의를 듣는 것을 추천드립니다.

profile
부족함을 인정하고 노력하자

0개의 댓글