Java

Java - Constructor 생성자 메서드 / 클래스 모델 DTO, VO, DAO, Utility

wy-family 2024. 12. 1. 17:35

생성자 메서드 (Constructor)

**생성자(Constructor)**는 객체가 생성될 때 호출되는 특별한 메서드입니다. 생성자는 객체를 초기화하는 역할을 하며, 클래스의 이름과 동일한 이름을 가지는 메서드입니다. 자바에서는 생성자를 명시적으로 정의하지 않아도 기본 생성자가 자동으로 제공됩니다.


특징

  1. 클래스 이름과 동일:
    • 생성자의 이름은 반드시 클래스 이름과 동일해야 합니다.
    • 리턴 타입을 명시하지 않습니다(리턴 타입 자체가 없음 - return 이 없다고 해서 void 를 쓰면 안 되는 ).
  2. 객체 초기화:
    • 객체 생성 시 호출되며, 객체의 필드(멤버 변수)를 초기화하거나 특정 작업을 수행할 수 있습니다.
  3. 자동 호출:
    • 객체가 생성될 때 자동으로 호출됩니다.
    • 개발자가 명시적으로 호출할 수는 없습니다.
  4. 종류:
    • 기본 생성자(Default Constructor): 매개변수가 없는 생성자.
    • 매개변수 생성자(Parameterized Constructor): 인자를 받아 객체를 초기화하는 생성자.

예제 코드

1. 기본 생성자

public class Person {
    String name;
    int age;

    // 기본 생성자
    public Person() {
        name = "Unknown";
        age = 0;
    }

    public void displayInfo() {
        System.out.println("Name: " + name + ", Age: " + age);
    }

    public static void main(String[] args) {
        Person person = new Person(); // 기본 생성자가 호출됨
        person.displayInfo(); // 출력: Name: Unknown, Age: 0
    }
}

2. 매개변수 생성자

public class Person {
    String name;
    int age;

    // 매개변수 생성자
    public Person(String name, int age) {
        this.name = name; // 클래스의 필드와 매개변수를 구분하기 위해 this 사용
        this.age = age;
    }

    public void displayInfo() {
        System.out.println("Name: " + name + ", Age: " + age);
    }

    public static void main(String[] args) {
        Person person = new Person("Alice", 25); // 매개변수 생성자 호출
        person.displayInfo(); // 출력: Name: Alice, Age: 25
    }
}

생성자의 종류

  1. 기본 생성자:
    • 개발자가 명시적으로 생성자를 정의하지 않으면, 자바가 기본 생성자를 자동으로 제공.
    • 하지만, 클래스에 생성자를 하나라도 정의하면 자동 생성되지 않음.
  2. 매개변수 생성자:
    • 객체 생성 시 필요한 데이터를 인자로 전달받아 초기화.
  3. 오버로딩된 생성자:
    • 여러 생성자를 정의해, 객체 생성 시 다양한 초기화 방법 제공.

오버로딩 예제:

public class Person {
    String name;
    int age;

    // 기본 생성자
    public Person() {
        name = "Default";
        age = 0;
    }

    // 매개변수 생성자
    public Person(String name, int age) {
        this.name = name;
        this.age = age;
    }

    public static void main(String[] args) {
        Person p1 = new Person(); // 기본 생성자 호출
        Person p2 = new Person("John", 30); // 매개변수 생성자 호출
        System.out.println(p1.name + ", " + p1.age); // 출력: Default, 0
        System.out.println(p2.name + ", " + p2.age); // 출력: John, 30
    }
}

this 키워드와 생성자

  • this는 현재 객체를 참조합니다. (번지 정보를 담아낸다는 것)
  • 생성자 내부에서 다른 생성자를 호출할 때도 **this()**를 사용합니다.
  • 자신을 가리키는 객체변수, 참조변수(레퍼런스 변수), 포인터 변수 라고도 합니다. 

예제: 생성자 체이닝

public class Person {
    String name;
    int age;

    // 기본 생성자
    public Person() {
        this("Unknown", 0); // 다른 생성자를 호출
    }

    // 매개변수 생성자
    public Person(String name, int age) {
        this.name = name;
        this.age = age;
    }

    public static void main(String[] args) {
        Person p = new Person(); // 기본 생성자 호출 -> 매개변수 생성자 호출
        System.out.println(p.name + ", " + p.age); // 출력: Unknown, 0
    }
}

생성자와 메서드의 차이

     
특징 생성자 메서드
이름 클래스와 동일 임의의 이름
반환 타입 없음 (리턴 타입 명시하지 않음) 반드시 리턴 타입을 명시 (void 포함)
호출 시점 객체 생성 시 자동 호출 명시적으로 호출해야 함
목적 객체 초기화 객체의 동작을 정의

요약

  • 생성자는 클래스와 같은 이름의 특별한 메서드로, 객체 생성 시 초기화 작업을 담당합니다.
  • 리턴 타입이 없으며, 매개변수를 가질 수 있습니다.
  • 객체를 생성하면서 데이터를 초기화하거나 필수 작업을 실행할 수 있습니다.

우리가 클래스로 만들어 사용하게 될 모델의 종류

객체_object (현실적) = 클래스_class (프로그래밍적) = 모델_model (소프트웨어공학적)

객체지향프로그래밍에서 클래스를 역할에 따라 부르는 이름을 모델(Model)이라고 부른다.

역할에 따라 다양한 모델을 만들어 사용할 수 있다.

DTO, VO, DAO, Utility 모델 설명

이 네 가지 모델은 자바와 같은 언어에서 애플리케이션의 설계 및 아키텍처를 구성할 때 자주 사용되는 패턴과 설계 방식입니다. 각각의 역할과 사용 목적이 다릅니다.


1. DTO (Data Transfer Object)

정의

DTO는 데이터를 계층 간(주로 컨트롤러와 서비스, 서비스와 DAO 간) 전달하기 위해 사용하는 객체입니다. 주로 애플리케이션 내에서 데이터 이동을 단순화하고 구조화하기 위해 사용됩니다.

특징

  • 주요 목적: 데이터를 전달하는 데 초점이 있음.
  • 속성만 포함: 보통 데이터의 getter/setter 메서드만 포함하며, 로직은 포함하지 않음.
  • 직렬화: 네트워크를 통해 데이터를 주고받기 위해 직렬화 가능하도록 설계.
  • 데이터를 캡슐화하고 시스템 간 데이터 형식을 표준화하는 데 사용.

예제

import java.io.Serializable;

public class UserDTO implements Serializable {
    private String username;
    private String email;

    // Getter & Setter
    public String getUsername() {
        return username;
    }
    public void setUsername(String username) {
        this.username = username;
    }

    public String getEmail() {
        return email;
    }
    public void setEmail(String email) {
        this.email = email;
    }
}

사용 예시

  • API 요청 및 응답에서 데이터를 전달할 때.
  • 데이터베이스에서 가져온 데이터를 클라이언트에 전달할 때.

2. VO (Value Object)

정의

VO는 데이터를 표현하기 위해 사용하는 객체입니다. 불변 객체로 설계되며, 특정한 값 자체를 표현하는 데 초점이 있습니다.

특징

  • 주요 목적: 값을 표현하고 불변성을 보장.
  • 객체의 속성이 변경되지 않도록 불변으로 설계.
  • DTO와 비슷하지만, VO는 보통 읽기 전용(read-only)이며 값의 동일성(equality)에 중점을 둠.
  • 두 VO가 같은 값을 가지면 같은 객체로 간주됩니다.

예제

public class AddressVO {
    private final String street;
    private final String city;

    // 생성자를 통해 값 설정 (불변)
    public AddressVO(String street, String city) {
        this.street = street;
        this.city = city;
    }

    // Getter만 제공
    public String getStreet() {
        return street;
    }

    public String getCity() {
        return city;
    }

    // VO 객체의 동일성 비교를 위해 equals와 hashCode 오버라이딩
    @Override
    public boolean equals(Object o) {
        if (this == o) return true;
        if (o == null || getClass() != o.getClass()) return false;

        AddressVO address = (AddressVO) o;
        return street.equals(address.street) && city.equals(address.city);
    }

    @Override
    public int hashCode() {
        return street.hashCode() + city.hashCode();
    }
}

사용 예시

  • 값의 변경이 허용되지 않아야 하는 경우 (예: 화폐, 주소, 좌표 등).
  • 값의 동일성을 비교해야 하는 경우.
DTO - VO 는 보통 데이터를 담아내는 클래스 모델로 생각해서, 따로 생각하기 보다는 하나로 생각하는 것 같음.
그래서 DTO/VO 모델이라고도 하는 것 같음.

DTO/VO 모델을 설계할 때, 순서는,
1. 모든 생태정보 정보은닉 (private)
2. 디폴트 생성자 (Constructor) 반드시 만들기
3. 생성자 메서드를 오버로딩해서 매개변수 생성자 만들기 - 객체 초기화 하기
4. setter & getter 메서드 만들기 (값을 저장하는 용도와 값을 얻기 용도)
5. toString() 메서드를 만들기 (객체가 가지고 있는 전체 값 출력용도)
- toString() 을 정의하고 나서 사용할 때, 생략해도 되는 경우가 있음.
- System.out.println(person); // person.toString() 호출
- String result = "Person info: " + person; // 내부적으로 person.toString() 호출

3. DAO (Data Access Object)

정의

DAO는 데이터베이스와의 상호작용을 전담하는 객체입니다. 데이터베이스의 데이터를 CRUD(생성 create, 읽기 read, 수정 update, 삭제 delete) 작업을 통해 접근, 관리합니다.

특징

  • 주요 목적: 데이터베이스 작업의 분리 및 관리.
  • 데이터베이스에 접근하는 코드(쿼리, 연결 등)를 캡슐화.
  • 서비스 계층에서 DAO를 호출해 데이터베이스 작업을 수행.
  • 인터페이스로 설계하는 경우가 많아 추상화와 테스트 용이성을 높임.
  • DB의 SQL의 Insert, Select, Update, Delete  가 CRUD의 Create, Read, Update, Delete 에 대응.

예제

import java.sql.Connection;
import java.sql.PreparedStatement;
import java.sql.ResultSet;

public class UserDAO {
    private Connection connection;

    public UserDAO(Connection connection) {
        this.connection = connection;
    }

    public UserDTO getUserById(int id) throws Exception {
        String query = "SELECT * FROM users WHERE id = ?";
        PreparedStatement statement = connection.prepareStatement(query);
        statement.setInt(1, id);
        ResultSet resultSet = statement.executeQuery();

        if (resultSet.next()) {
            UserDTO user = new UserDTO();
            user.setUsername(resultSet.getString("username"));
            user.setEmail(resultSet.getString("email"));
            return user;
        }
        return null;
    }
}

사용 예시

  • 데이터베이스와 상호작용이 필요한 모든 작업.
  • 데이터 조회, 삽입, 삭제, 업데이트.

4. Utility (유틸리티) (Helper Object Model / Facade 이라고 부르기도 함)

정의

Utility 클래스는 특정 동작이나 연산을 수행하는 정적 메서드(static method)들로 구성된 클래스입니다. 데이터를 저장하지 않으며, 재사용 가능한 도구(툴)로 제공됩니다. 반복적으로 사용해야 될 동작(기능)을 별도의 클래스로 만들어놓고 필요할 떄 사용하는 클래스.

특징

  • 주요 목적: 공통적인 기능을 묶어 재사용성을 높임.
  • 자바에서도 java.util 패키지에 Utility 클래스가 많이 있음.
  • 상태를 가지지 않으며, 객체 생성이 필요 없음.
  • 정적 메서드와 정적 필드로 구성.
  • 일반적으로 final 키워드로 선언하며, 객체 생성 방지를 위해 private 생성자를 사용.

예제

public final class MathUtility {

    // private 생성자 (인스턴스화 방지)
    private MathUtility() {}

    public static int add(int a, int b) {
        return a + b;
    }

    public static int subtract(int a, int b) {
        return a - b;
    }
}

사용 예시

  • 공통적인 유틸리티 기능 제공 (예: 수학 연산, 문자열 처리).
  • 코드 중복을 줄이기 위해 여러 클래스에서 사용 가능.
public class Main {
    public static void main(String[] args) {
        int result = MathUtility.add(10, 5);
        System.out.println("Result: " + result); // 출력: 15
    }
}

차이점 요약

     
모델 주요 목적 특징
DTO 데이터 전달 (계층 간 전송) 속성만 포함, 로직 없음, 직렬화 가능
VO 값을 표현 (불변 객체, 동일성 보장) 읽기 전용, 불변, 동일성 비교를 위해 equals와 hashCode 메서드 오버라이딩
DAO 데이터베이스와의 상호작용 관리 CRUD 작업 캡슐화, 데이터베이스 관련 코드 분리
Utility 공통 기능 제공 (도구 클래스) 정적 메서드로 구성, 객체 생성 없이 사용 가능, 특정 작업을 수행

정리

  • DTO: 데이터를 전달하는 데 초점.
  • VO: 변경 불가능한 값 객체를 나타냄.
  • DAO: 데이터베이스 작업 전담.
  • Utility: 재사용 가능한 공통 기능 제공.