객체 지향 프로그래밍

객체 지향 프로그래밍은 유연하고 변경에 용이한 프로그램을 만들수 있다는 장점이 있다.

그러한 프로그램을 만들수 있도록 하는 객체지향의 특징 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)이라고 함

의존관계 주입의 응용

  • 기능 구현의 교환
  • 부가기능 추가

메소드를 이용한 의존관계 주입

  • 수정자 메소드를 이용한 주입
  • 일반 메소드를 이용한 주입

Categories:

Updated:

Leave a comment