객체 지향과 디자인 패턴 ‐ SOLID(S) - dnwls16071/Backend_Study_TIL GitHub Wiki

📚 단일 책임 원칙(Single Responsibility Principle)

  • 클래스는 단 한 개의 책임을 가져야 한다.
public class DataViewer {

	public void display() {
		String data = loadHtml();
		updateGui(data);
	}

	public String loadHtml() {
		HttpClient client = new HttpClient();
		client.connect(url);
		return client.getResponse();
	}

	private void updateGui(String data) {
		GuiData guiModel = parseDataToGuiData(data);
		tableUI.changeData(guiModel);
	}

	private GuiData parseDataToGuiData(String data) {
		// ...
	}
}
  • 코드의 실행 내용을 따라가다보면 데이터를 읽고 데이터를 받아서 UI를 업데이트하고 GUIData를 생성하는 코드로다가 흐름이 이어진다.
  • 이런 연쇄적인 코드 수정은 두 개의 책임(데이터 읽는 책임, 데이터를 받아서 화면에 반영하는 책임)을 두 개의 클래스로 분리하는 것이 좋다.
public class DataViewer {

    private final DataLoader dataLoader;  // 객체의 조립
    private final DataParser dataParser;  // 객체의 조립
    private final GuiUpdater guiUpdater;  // 객체의 조립

    public DataViewer(DataLoader dataLoader, DataParser dataParser, GuiUpdater guiUpdater) {
        this.dataLoader = dataLoader;
        this.dataParser = dataParser;
        this.guiUpdater = guiUpdater;
    }

    public void display() {
        String data = dataLoader.loadData();
        GuiData guiModel = dataParser.parseData(data);
        guiUpdater.updateGui(guiModel);
    }
}

// HTTP Data 로드 책임을 맡는 클래스
public class HttpDataLoader implements DataLoader {
    private final String url;

    public HttpDataLoader(String url) {
        this.url = url;
    }

    @Override
    public String loadData() {
        HttpClient client = new HttpClient();
        client.connect(url);
        return client.getResponse();
    }
}

public interface DataLoader {
    String loadData();
}

public interface DataParser {
    GuiData parseData(String data);
}

// HTML Data를 파싱하는 책임을 맡는 클래스
public class HtmlDataParser implements DataParser {
    @Override
    public GuiData parseData(String data) {
        // HTML 파싱 로직 구현
        return parseDataToGuiData(data);
    }

    private GuiData parseDataToGuiData(String data) {
        // ...
        return new GuiData();
    }
}

public interface GuiUpdater {
    void updateGui(GuiData guiModel);
}

// 화면의 GUI를 업데이트하는 책임을 맡은 클래스
public class TableGuiUpdater implements GuiUpdater {
    private final TableUI tableUI;

    public TableGuiUpdater(TableUI tableUI) {
        this.tableUI = tableUI;
    }

    @Override
    public void updateGui(GuiData guiModel) {
        tableUI.changeData(guiModel);
    }
}