[개발자_객체지향_디자인패턴] 추상 타입을 이용한 구현 교체의 유연함

박상준·2024년 8월 15일
0

왜 추상 타입을 사용하는가?

  • 구상 클래스를 사용해도 문제가 없어 보인다.
  • 왜 추상 타입을 사용하는가?
// 콘크리트 클래스를 직접 사용하는 예
SocketLogReader reader = new SocketLogReader();
reader.collect();
  • 문제가 없어보임 ㅎ..과연..

파일 암호화 예시

public class FlowController {
    public void process() {
        FileDataReader reader = new FileDataReader();
        byte[] data = reader.read();
        
        Encryptor encryptor = new Encryptor();
        byte[] encryptedData = encryptor.encrypt(data);
        
        FileDataWriter writer = new FileDataWriter();
        writer.write(encryptedData);
    }
}
  • 지금은 단순하게 파일을 읽어서 암호화 → 암호화된 데이터 → 파일로 쓰기
  • 이렇게 구성이 되어 있습니다.

초기 해결 방안

  • 새로 클래스를 만들게 되겠죠
  • SocketDataReader 를 만들고 조건에 따라 FileDataReaderSockerDataReader 를 사용하도록 FlowController 를 수정합니다.
public class FlowController {
    private boolean useFile;
    
    public FlowController(boolean useFile) {
        this.useFile = useFile;
    }
    
    public void process() {
        byte[] data = null;
        if (useFile) {
            FileDataReader fileReader = new FileDataReader();
            data = fileReader.read();
        } else {
            SocketDataReader socketReader = new SocketDataReader();
            data = socketReader.read();
        }
        
        Encryptor encryptor = new Encryptor();
        byte[] encryptedData = encryptor.encrypt(data);
        
        FileDataWriter writer = new FileDataWriter();
        writer.write(encryptedData);
    }
}

문제점

  1. if - else
    • 해당 구문 상의 코드 구조가 엄청 유사하다.
  2. 확장성이 부족하다
    • 새로운 데이터 소스(HTTP) 가 추가될 때 마다 if-else 가 무한정 늘어나게 된다.
  3. 생성자 문제
    1. 데이터 소스 추가시마다 생성자 파라미터도 변경되어야 할 수 있음.
  4. 책임 분리
    1. FlowController 의 주요 책임은 흐름 제어이다. 데이터 읽기 구현의 변경점때문에 FlowControler 가 변경되어야 하는 문제점이 발생한다

해결

public interface DataReader {
    byte[] read();
}

public class FileDataReader implements DataReader {
    public byte[] read() {
        // 파일에서 데이터 읽기 구현
    }
}

public class SocketDataReader implements DataReader {
    public byte[] read() {
        // 소켓에서 데이터 읽기 구현
    }
}

public class FlowController {
    private DataReader reader;
    
    public FlowController(DataReader reader) {
        this.reader = reader;
    }
    
    public void process() {
        byte[] data = reader.read();
        
        Encryptor encryptor = new Encryptor();
        byte[] encryptedData = encryptor.encrypt(data);
        
        FileDataWriter writer = new FileDataWriter();
        writer.write(encryptedData);
    }
}
  • FlowController 는 구체적인 DataReader 구현에 의존하지 않으며, 새로운 데이터 소스가 추가되어도 FlowController 는 자유에요.
  • 런타임 중에 전략적으로 어떤 객체를 사용할 지 코드의 변경없이 제어할 수 있다는게 장점!
profile
이전 블로그 : https://oth3410.tistory.com/

0개의 댓글