1.3.1 클래스의 분리
상속 관계로 관리했던 클래스를 별개의 클래스로 나누는 과정을 다룹니다.
상속이 아닌 별개의 클래스로 나누기
public class UserDao {
private SimpleConnectionMaker simpleConnectionMaker;
public UserDao() {
simpleConnectionMaker = new SimpleConnectionMaker();
}
public void add(User user) throws ClassNotFoundException, SQLException {
Connection c = simpleConnectionMaker.makeNewConnection();
}
public void get(String id) throws ClassNotFoundException, SQLException {
Connection c = simpleConnectionMaker.makeNewConnection();
}
}
public class SimpleConnectionMaker {
public Connection makeNewConnection() throws ClassNotFoundException, SQLException {
Class.forName("com.mysql.cj.jdbc.Driver");
Connection c = DriverManager.getConnection("jdbc:mysql://localhost/springbook?serverTimezone=Asia/Seoul&useSSL=false"
+ "&characterEncoding=utf8&allowPublicKeyRetrieval=true&useSSL=false",
"spring", "book");
return c;
}
}
상속을 통해 하위 클래스에서 기능 변경 및 확장이 불가능해졌다.
그리고 UserDao는 DB 커넥션을 가져오는 구체적인 방법에 종속되어 버렸다.
1.3.2 인터페이스의 도입
분리한 클래스를 인터페이스로 구현하여 결합도를 낮추는 과정을 다룹니다.
클래스를 분리하면서도 기능 변경 및 확장에 유연한 방법은 무엇일까?
두 개의 클래스가 서로 긴밀하게 연결되어 있지 않도록 중간에 추상적인 느슨한 연결고리를 만들어 주는것이다.
public interface ConnectionMaker {
public Connection makeConnection() throws ClassNotFoundException, SQLException;
}
public class DConnectionMaker implements ConnectionMaker{
public Connection makeConnection() throws ClassNotFoundException, SQLException {
// D 사의 독자적인 방법으로 Connection 생성하는 코드
}
}
public class UserDao {
private ConnectionMaker connectionMaker;
public UserDao() {
connectionMaker = new DConnectionMaker();
}
public void add(User user) throws ClassNotFoundException, SQLException {
Connection c = connectionMaker.makeConnection();
}
public void get(String id) throws ClassNotFoundException, SQLException {
Connection c = connectionMaker.makeConnection();
}
}
connectionMaker = new DConnectionMaker();
인터페이스를 이용해 변경 및 확장은 가능해졌지만
초기에 어떤 클래스의 오브젝트를 사용할지 결정하는 생성자의 코드에서 결합 발생
1.3.3 관계설정 책임의 분리
UserDao가 독립적으로 확장하기 위해 관계를 설정하고 책임을 분리하는 과정을 다룹니다.
connectionMaker = new DConnectionMaker();
어떤 ConnectionMaker 구현 클래스를 사용할지 결정하는 코드로 인해 UserDao와 DConnectionMaker에서 관계가 생성되었다.
독립적으로 확장 가능한 UserDao클래스가 되기 위해선 UserDao의 모든 코드는 ConnectionMaker 인터페이스 외에는 어떤 클래스와도 관계를 가져서는 안 되게 해야한다.
특정 클래스를 전혀 알지 못하더라도 해당 클래스가 구현한 인터페이스를 사용했다면, 그 클래스의 오브젝트를 인터페이스 타입으로 받아서 사용할 수 있다. (다형성)
public UserDao(ConnectionMaker connectionMaker) {
this.connectionMaker = connectionMaker;
}
public class UserDaoTest {
public static void main(String[] args) throws ClassNotFoundException, SQLException{
ConnectionMaker connectionMaker = new DConnectionMaker();
UserDao dao = new UserDao(connectionMaker);
}
}
인스턴스 생성시점에서 생성자를 통한 관계부여 (UserDaoTest에서 ConnectionMaker클래스를 선정하는 책임)
public class UserDaoTest {
public static void main(String[] args) throws ClassNotFoundException, SQLException{
ConnectionMaker connectionMaker = new DConnectionMaker();
ConnectionMaker nconnectionMaker = new NConnectionMaker();
UserDao dao = new UserDao(connectionMaker);
UserDao ndao = new UserDao(nconnectionMaker);
}
}
1.3.4 원칙과 패턴
개방 폐쇄 원칙, SOLID원칙, 전략패턴에 대해 다룹니다.
개방 폐쇄 원칙(OCP, Open-Closed Principle)
'클래스나 모듈은 확장에는 열려 있어야 하고 변경에는 닫혀 있어야 한다.'
객체지향 설계 원칙(SOLID)
- SRP(The Single Responsibility Principle): 단일 책임 원칙
- OCP(The Open CLosed Principle): 개방 폐쇄 원칙
- LSP(The Liskov Substitution Principle): 리스코프 치환 원칙
- ISP(The Interface Segregation Principle): 인터페이스 분리 원칙
- DIP(The Dependency Inversion Principle): 의존관계 역전 원칙
http://butunclebob.com/ArticleS.UncleBob.PrinciplesOfOod
높은 응집도와 낮은 결합도 ( high coherence and low coupling)
- 높은 응집도
- 모듈에 포함된 내부 요소들이 하나의 책임/목적을 위해 응집됨
- 즉 모듈 내부의 기능적인 응집도가 크다
- 변화가 일어날시 변경 대상과 범위가 명확해 짐
- 낮은 결합도
- '하나의 오브젝트가 변경이 일어날 때에 관계를 맺고 있는 다른 오브젝트에 변화를 요구하는 정도'
- 변화에 대응하는 속도가 높아지고, 구성이 깔끔하며, 확장에 용이
전략 패턴 (Strategy Pattern)
자신의 기능 맥락(context)에서, 필요에 따라 변경이 필요한 알고리즘을 인터페이스를 통해 통째로 외부로 분리시키고, 이를 구현한 구체적인 알고리즘 클래스를 필요에 따라서 바꿔서 사용할 수 있게 하는 디자인 패턴
여기서 알고리즘이란 독립적인 책임으로 분리가 가능한 기능을 뜻한다. 즉 대체 가능한 전략에서 전략패턴 이라는 이름이다.
'BackEnd > Spring & Springboot Study' 카테고리의 다른 글
[토비의 스프링] 1.5 스프링의 Ioc (0) | 2022.12.02 |
---|---|
[토비의 스프링] 1.4 제어의 역전(IoC) (0) | 2022.12.01 |
[토비의 스프링] 1.2 DAO의 분리 (0) | 2022.11.28 |
[토비의 스프링] 1.1 초난감 DAO (0) | 2022.11.24 |
[토비의 스프링] 토비의 스프링 프로젝트 생성 (0) | 2022.11.22 |