코진남

clean code 10편 클래스 본문

Robert C.Martin 클린코드

clean code 10편 클래스

woojin126 2022. 3. 9. 16:38

▶오늘 읽은 범위

10장. 클래스

📑 정리본

클래스 체계

  • static public 상수
  • static private 변수
  • private instance 변수(public 변수가 필요한 경우는 거의 없음)
  • public method
    • private method는 자신을 호출하는 public method 직후에 위치

테스트를 위해 private method나 변수를 protected로 공개해야 할 경우가 있다. 이런 경우 공개하지 않을 방법을 충분히 생각한 이후에 캡슐화를 푸는 것이 좋다.

SOLID

객체지향 프로그래밍을 할 때 기본적으로 이해해야 하는 원리들입니다.

  1. SRP (Single Responsibillity Principle)
    • 클래스틑 하나의 역할만 해야 한다
    • 다양한 일을 할 수 있는 만능의 클래스를 만드는 것은 한가지 역할을 하는 클래스보다 좋지 않다
      • 변경을 할 가능성이 높고 좋지 않은 영향을 받을 가능성도 높음
      • 복잡한 자료구조와 메서드를 가질 가능성이 높으며 사용하기 어려울 가능성이 높음
    • 명확히 정의된 하나의 구체적인 역할을 줄 수 있다면 SRP를 만족한다고 할 수 있다.
  2. OCP (Open Close Principle)
    • 확장에 대해서는 열려있고, 변경에 대해서는 닫혀있게 만들어야 한다.
      • 즉 새로운 기능 추가는 쉽지만 변경의 영향이 제한적이여야 한다.
  3. LSP (Liskov Substitution Principle)
    • 같은 형을 가지는 객체로 대체되어 사용할 수 있어야 한다.
    • 동일한 클래스를 상속하는 경우, 상위 클래스를 접근하는 Client 코드들은 상속받은 클래스로 대체하더라도 변경이 없어야 한다.
  4. ISP (Interface Segregation Principle)
    • 필요한 인터페이스 각각에 대해서 따로 정의해서 사용하는 것이 좋다.
    • 즉, 각각의 인터페이스를 공용화해서 한 인터페이스가 너무 많은 기능을 제공하도록 만드는 것은 확장성 및 변경의 영향을 제어하지 못하게 만든다.
    • 만능보다는 한가지 일에 특화된 것이 좋다.
  5. DIP (Dependency Inversion Principle)
    • 구체적인 것에 의존하지 말라
    • 다른 클래스나 자료구조의 내부에 의존적인 코드를 짜면 변경에 취약하도록 만든다.
    • 추상 클래스를 사용하라.

 

클래스는 작아야 한다!

클래스를 만들 때 가장 중요한 규칙은 함수와 마찬가지로 작은 크기입니다.

클래스는 맡은 책임 를 기준으로 측정합니다.

변경하기 쉬운 클래스

대다수 시스템은 지속적인 변경이 가해집니다.

  • 변경 때마다 시스템이 의도대로 동작하지 않은 위험이 따름
  • 깨끗한 시스템은 클래스를 체계적으로 정리해 변경에 수반하는 위험을 낮춤

아래는 메타 자료로 적절한 SQL 문자열을 만들어주는 sql 클래스입니다.

public class Sql {
    public Sql(String table, Column[] columns)
    public String create()
    public String insert(Object[] fields)
    public String selectAll()
    public String findByKey(String keyColumn, String keyValue)
    public String select(Column column, String pattern)
    public String select(Criteria criteria)
    public String preparedInsert()
    private String columnList(Column[] columns)
    private String valuesList(Object[] fields, final Column[] columns) 
	private String selectWithCriteria(String criteria)
    private String placeholderList(Column[] columns)
}

위 클래스는 변경할 이유가 두 가지가 있기 때문에 SRP를 위반합니다.

  1. update 문을 지원
  2. select 문에 내장된 select 문을 지원하기 위해

 

아래 코드는 공개 인터페이스를 각각 SQL 클래스에서 파생하는 클래스로 만든 결과입니다.

  • valueList와 같은 비공개 메서드는 해당하는 파생 클래스로 옮김.
  • 공통적으로 사용하는 비공개 메서드는 Where와 ColumnList라는 두 유틸리티 클래스에 넣음
abstract public class Sql {
	public Sql(String table, Column[] columns) 
	abstract public String generate();
}
public class CreateSql extends Sql {
	public CreateSql(String table, Column[] columns) 
	@Override public String generate()
}

public class SelectSql extends Sql {
	public SelectSql(String table, Column[] columns) 
	@Override public String generate()
}

public class InsertSql extends Sql {
	public InsertSql(String table, Column[] columns, Object[] fields) 
	@Override public String generate()
	private String valuesList(Object[] fields, final Column[] columns)
}

public class SelectWithCriteriaSql extends Sql { 
	public SelectWithCriteriaSql(
	String table, Column[] columns, Criteria criteria) 
	@Override public String generate()
}

public class SelectWithMatchSql extends Sql { 
	public SelectWithMatchSql(String table, Column[] columns, Column column, String pattern) 
	@Override public String generate()
}

public class FindByKeySql extends Sql public FindByKeySql(
	String table, Column[] columns, String keyColumn, String keyValue) 
	@Override public String generate()
}

public class PreparedInsertSql extends Sql {
	public PreparedInsertSql(String table, Column[] columns) 
	@Override public String generate() {
	private String placeholderList(Column[] columns)
}

public class Where {
	public Where(String criteria) public String generate()
	public String generate() {
}

public class ColumnList {
	public ColumnList(Column[] columns) public String generate()
	public String generate() {
}

클래스가 서로 분리되었기 때문에 클래스가 단순하고 코드는 순식간에 이해할 수 있게 변했다.

  • 함수 하나를 수정했다고 다른 함수가 망가질 위험도 사라졌다.
  • 테스트하기도 쉬워졌다.
  • SRP와 OCP를 지원

Update 문을 추가할 때는 기존 클래스를 변경하지 않고 새로운 클래스 UpdateSql을 구현하면 된다.

✔오늘 책을 읽은 소감

위의 규칙들은 어느정도 알고 잇던 내용이었지만 막상 프로젝트에 들어가보면 뇌정지가 올때가 많다..

계속해서 생각하면서 클래스 설계를 하기위해 노력중이다.

 

궁금한 내용이 있거나, 잘 이해되지 않는 내용이 있다면 적어보세요.

이론적으로는 이해가되지만 적용해보는 것이 중요할 것같다.

'Robert C.Martin 클린코드' 카테고리의 다른 글

clean code 9편 테스트 코드  (0) 2022.03.06
clean code 8편 오류처리  (0) 2022.03.04
clean code 7편  (0) 2022.03.01
clean code 6편  (0) 2022.02.28
clean code 5편  (0) 2022.02.26