코진남
clean code 10편 클래스 본문
▶오늘 읽은 범위
10장. 클래스
📑 정리본
클래스 체계
- static public 상수
- static private 변수
- private instance 변수(public 변수가 필요한 경우는 거의 없음)
- public method
- private method는 자신을 호출하는 public method 직후에 위치
테스트를 위해 private method나 변수를 protected로 공개해야 할 경우가 있다. 이런 경우 공개하지 않을 방법을 충분히 생각한 이후에 캡슐화를 푸는 것이 좋다.
SOLID
객체지향 프로그래밍을 할 때 기본적으로 이해해야 하는 원리들입니다.
- SRP (Single Responsibillity Principle)
- 클래스틑 하나의 역할만 해야 한다
- 다양한 일을 할 수 있는 만능의 클래스를 만드는 것은 한가지 역할을 하는 클래스보다 좋지 않다
- 변경을 할 가능성이 높고 좋지 않은 영향을 받을 가능성도 높음
- 복잡한 자료구조와 메서드를 가질 가능성이 높으며 사용하기 어려울 가능성이 높음
- 명확히 정의된 하나의 구체적인 역할을 줄 수 있다면 SRP를 만족한다고 할 수 있다.
- OCP (Open Close Principle)
- 확장에 대해서는 열려있고, 변경에 대해서는 닫혀있게 만들어야 한다.
- 즉 새로운 기능 추가는 쉽지만 변경의 영향이 제한적이여야 한다.
- 확장에 대해서는 열려있고, 변경에 대해서는 닫혀있게 만들어야 한다.
- LSP (Liskov Substitution Principle)
- 같은 형을 가지는 객체로 대체되어 사용할 수 있어야 한다.
- 동일한 클래스를 상속하는 경우, 상위 클래스를 접근하는 Client 코드들은 상속받은 클래스로 대체하더라도 변경이 없어야 한다.
- ISP (Interface Segregation Principle)
- 필요한 인터페이스 각각에 대해서 따로 정의해서 사용하는 것이 좋다.
- 즉, 각각의 인터페이스를 공용화해서 한 인터페이스가 너무 많은 기능을 제공하도록 만드는 것은 확장성 및 변경의 영향을 제어하지 못하게 만든다.
- 만능보다는 한가지 일에 특화된 것이 좋다.
- 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를 위반합니다.
- update 문을 지원
- 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 |