오브젝트와 의존관계
객체 지향 프로그래밍
객체 지향 프로그래밍은 유연하고 변경에 용이한 프로그램을 만들수 있다는 장점이 있다.
그러한 프로그램을 만들수 있도록 하는 객체지향의 특징 4가지와 원칙 5가지가 있다.
관심사의 분리 (Separation of Concerns)
- 컴퓨터 프로그램을 구별된 부분으로 분리하는 것
- 객체지향에서는 관심이 같은 것끼리는 하나의 객체 안으로 또는 친한 객체로 모이게 하고 관심이 다른 것은 가능한 한 따로 덜어져서 서로 영향을 주지 않도록 분리하는 것
public class UserDao {
public void add(User user) throws SQLException, ClassNotFoundException {
Class.forName("org.postgresql.Driver");
String user = "postgres";
String password = "password";
Connection c = DriverManager.getConnection(
"jdbc:postgresql://localhost/toby_spring"
, user
, password
);
PreparedStatement ps = c.prepareStatement(
"insert into users(id, name, password) values (?, ?, ?)"
);
ps.setString(1, user.getId());
ps.setString(2, user.getName());
ps.setString(3, user.getPassword());
ps.executeUpdate();
ps.close();
c.close();
}
public User get(String id) throws SQLException, ClassNotFoundException {
Class.forName("org.postgresql.Driver");
String user = "postgres";
String password = "password";
Connection c = DriverManager.getConnection(
"jdbc:postgresql://localhost/toby_spring"
, user
, password
);
PreparedStatement ps = c.prepareStatement(
"select * from users where id = ?"
);
ps.setString(1, id);
ResultSet rs = ps.executeQuery();
rs.next();
User user = new User();
user.setId(rs.getString("id"));
user.setName(rs.getString("name"));
user.setPassword(rs.getString("password"));
rs.close();
ps.close();
c.close();
return user;
}
- 중복 코드의 메소드 추출
/*
* 중복된 코드를 독립적인 메소드로 만들어서 중복을 제거한다.
*/
private Connection getConnection() throws ClassNotFoundException, SQLException {
Class.forName("oracle.jdbc.driver.OracleDriver");
Connection c = DriverManager.getConnection("jdbc:oracle:thin:@localhost:1521:testDB" , "otep", "otep");
return c;
}
-
상속
- 인터페이스
- 관계설정 책임의 분리
다형성 : 역할과 구분을 분리 다형성 만으로는 좋은 객체지향 프로그래밍을 지킬 수 없음 → OCP 위반 (결국 구현 객체를 변경할 때 클라이언트 코드도 함께 변경됨.) IOC가 필요
제어의 역전(IoC : Inversion of Control)
구현 객체를 변경할때 크라이언트 코드도 같이 변경된다는 문제점이 있음
클라이언트 코드에 떠넘긴 책임을 분리시켜주자.
- 오브젝트 팩토리
스프링의 IOC
스프링 IoC의 장점
- 클라이언트는 구체적인 팩토리 클래스를 알 필요가 없다
- 애플리케이션 컨텍스트는 종합 IoC 서비스를 제공해준다
- 애플리케이션 컨텍스트는 빈을 검색하는 다양한 방법을 제공해준다
애플리케이션 컨텍스트
- 오브젝트 팩토리 == 애플리케이션 컨텍스트 == IOC 컨테이너 == DI 컨테이너
- @Configuration : 애플리케이션 오브젝트를 생성하고 구성할때 사용됨. 형상정보
- @Bean : 스프링이 관리하는 오브젝트
싱글톤 레지스트리
- 애플리케이션 컨텍스트는 싱글톤을 저장하고 관리하는 싱글톤 레지스트리
- 스프링 = 자바 엔터프라이즈 기술을 사용하는 서버환경
- 내부 구조가 복잡하고 많은 요청을 처리해야함. → 싱글톤이 아니면 매 요청마다 새로운 오브젝트가 생성되고 서버에 부하가 심해짐
싱글톤 패턴의 한계
- private 생성자를 갖고 있기 때문에 상속할 수 없다
- 싱글톤은 테스트하기 힘들다
- 서버환경에서는 싱글톤이 하나만 만들어지는 것을 보장하지 못한다
- 싱글톤의 사용은 전역 상태를 만들 수 있기 때문에 바람직하지 못하다
의존관계 주입(DI : Dependency Injection)
의존관계
- 인터페이스에 의존 → 느슨한 결합(변화에 영향을 덜 받음 → 결합도 낮음)
- UserDao → «interface» ConnectionMaker ← DConnectionmaker
- DConnectionmaker ← 의존 오브젝트 : UserDao 오브젝트가 만들어지고나서 런타임 시에 의존관계를 맺는 대상, 즉 실제 사용대상인 오브젝트
의존관계 검색과 주입
public UserDao() {
DaoFactory daoFactory = new DaoFactory();
this.connectionMaker = daoFactory.connectionMaker();
}
위의 코드는 IoC 개념을 따르고 있는 코드일까?
- UserDao는 어떤 의존 오브젝트를 사용할지 모른다(여전히 코드의 의존대상은 인터페이스)
- 스스로 IoC컨테이너인 DaoFactory에게 요청하고 있음.
- 이러한 방식을 의존관계 검색(Dependency lookup)이라고 함
의존관계 주입의 응용
- 기능 구현의 교환
- 부가기능 추가
메소드를 이용한 의존관계 주입
- 수정자 메소드를 이용한 주입
- 일반 메소드를 이용한 주입
Leave a comment