데이터를 계층 간 또는 네트워크를 통해 전달하기 위해 사용하는 객체.
주로 사용하는 곳: 컨트롤러 ↔ 서비스, 서비스 ↔ 레포지토리/DAO(Data Access Object) 간의 데이터 전달
주요 특징:
getter/setter가 모두 존재
주로 계층 간의 데이터 전달 목적
가변(mutable) 객체 → 데이터를 수정할 수 있음
비즈니스 로직을 담지 않음 (순수한 데이터 전달용)
객체 지향 프로그래밍에서 클래스의 필드(속성)에 직접 접근하지 않고 간접적으로 접근할 수 있도록 도와주는 메서드.
Getter : 필드 값을 읽어오는 역할Setter : 필드 값을 설정(변경)하는 역할캡슐화(Encapsulation) 원칙을 지킬 수 있다.package lesson07;
import java.time.LocalDate;
import java.util.*;
class WordDTO{
private String word;
private String meaning;
private String level;
private LocalDate regDate;
public WordDTO(String word, String meaning, String level) {
this.word = word;
this.meaning = meaning;
this.level = level;
this.regDate = LocalDate.now();
}
public String getWord() {
return word;
}
public void setWord(String word) {
this.word = word;
}
public String getMeaning() {
return meaning;
}
public void setMeaning(String meaning) {
this.meaning = meaning;
}
public String getLevel() {
return level;
}
public void setLevel(String level) {
this.level = level;
}
public LocalDate getRegDate() {
return regDate;
}
public void setRegDate(LocalDate regDate) {
this.regDate = regDate;
}
@Override
public String toString() {
return "[단어] " + word + " | 뜻: " + meaning + " | 레벨: " + level + " | 등록일: " + regDate;
}
}
class WordController {
private final WordService service = new WordService();
public void register(String word, String meaning, int levelNum){
String level = convertLevel(levelNum);
if(level == null){
System.out.println("잘못된 레벨입니다. (1: 초급, 2: 중급, 3: 고급)");
return;
}
try{
WordDTO dto = new WordDTO(word, meaning, level);
service.registerWord(dto);
}catch(IllegalArgumentException e){
System.out.println("등록 실패: " + e.getMessage());
}
}
public void printAllWords(){
List<WordDTO> list = service.getAllWords();
if(list.isEmpty()){
System.out.println("등록된 단어가 없습니다.");
}else{
System.out.println("등록된 단어 목록");
for(WordDTO dto : list){
System.out.println("- " + dto);
}
}
}
public void query(String word){
WordDTO dto = service.findWord(word);
if(dto == null){
System.out.println(word + "단어는 등록되어 있지 않습니다.");
}else{
System.out.println("조회 결과: " + dto);
}
}
private String convertLevel(int levelNum){
return switch (levelNum){
case 1 -> "초급";
case 2 -> "중급";
case 3 -> "고급";
default -> null;
};
}
}
class WordService{
private final WordRepository repository = new WordRepository();
public void registerWord(WordDTO dto){
if(dto.getWord().isBlank() || dto.getMeaning().isBlank()){
throw new IllegalArgumentException("단어와 뜻은 반드시 입력해야 합니다.");
}
repository.save(dto);
}
public List<WordDTO> getAllWords(){
return repository.findAll();
}
public WordDTO findWord(String word){
return repository.findByWord(word);
}
}
class WordRepository{
// private final HashMap<String, WordDTO> wordMap = new HashMap<>();
private final Map<String, WordDTO> wordMap = new HashMap<>();
public void save(WordDTO dto){
wordMap.put(dto.getWord(), dto);
System.out.println("저장 완료: " + dto.getWord());
}
public List<WordDTO> findAll(){
return new ArrayList<>(wordMap.values());
}
public WordDTO findByWord(String word){
return wordMap.get(word);
}
}
public class Ex06_Main {
public static void main(String[] args) {
Scanner sc = new Scanner(System.in);
WordController controller = new WordController();
while(true){
System.out.println("영어 단어 사전");
System.out.println("1. 단어 등록");
System.out.println("2. 전체 단어 목록 보기");
System.out.println("3. 단어 상세 조회");
System.out.println("0. 종료");
System.out.print("선택: ");
int choice = Integer.parseInt(sc.nextLine());
switch(choice){
case 0 -> {
System.out.println("프로그램을 종료합니다.");
sc.close();
return;
}
case 1 -> {
System.out.print("영단어 입력: ");
String word = sc.nextLine();
System.out.print("뜻 입력: ");
String meaning = sc.nextLine();
System.out.println("레벨 선택 (1: 초급, 2: 중급, 3: 고급): ");
int level = Integer.parseInt(sc.nextLine());
controller.register(word, meaning, level);
}
case 2 -> controller.printAllWords();
case 3 -> {
System.out.println("조회할 영단어 입력: ");
String word = sc.nextLine();
controller.query(word);
}
default -> System.out.println("잘못된 메뉴입니다.");
}
}
}
}
변경 불가능한 값 객체, 값 자체를 표현하기 위한 객체.
주로 사용하는 곳: 주로 읽기 전용 데이터를 표현할 때 사용
주요 특징:
불변(immutable) 객체 → 한번 생성되면 상태를 바꿀 수 없음
getter만 존재 (setter 없음)
값 자체에 의미가 있음 (예: Money, Address)
equals()와 hashCode() 재정의(오버라이드)하여 비교
package lesson07;
import java.util.Objects;
import java.util.Scanner;
class Point{
private final int x;
private final int y;
public Point(int x, int y){
this.x = x;
this.y = y;
}
public double distanceTo(Point other){
int dx = this.x - other.x;
int dy = this.y - other.y;
return Math.sqrt(dx * dx + dy * dy);
}
public int getX() {return x;}
public int getY() {return y;}
@Override
public int hashCode() {
return Objects.hash(x, y);
}
@Override
public boolean equals(Object obj) {
if (this == obj) return true;
if(!(obj instanceof Point)) return false;
Point other = (Point) obj;
return x == other.x && y == other.y;
}
@Override
public String toString() {
return "(" + x + ", " + y + ")";
}
}
class StoreService{
private final Point storeLocation = new Point(0, 0);
public boolean canDeliver(Point customerLocation) {
double distance = storeLocation.distanceTo(customerLocation);
System.out.println("거리 계산: " + distance);
return distance <= 5.0;
}
}
public class Ex07_Main {
public static void main(String[] args) {
Scanner sc = new Scanner(System.in);
StoreService service = new StoreService();
System.out.println("가게 기준점은 (0, 0)입니다.");
System.out.println("고객 위치 X좌표 입력: ");
int x = Integer.parseInt(sc.nextLine());
System.out.println("고객 위치 Y좌표 입력: ");
int y = Integer.parseInt(sc.nextLine());
Point customer = new Point(x, y);
System.out.println("고객 위치: " + customer);
if(service.canDeliver(customer)){
System.out.println("배달 가능 지역입니다.");
}else{
System.out.println("배달 불가능한 지역입니다.");
}
sc.close();
}
}
생성자, getter, toString(), equals(), hashCode() 등의 메서드를 자동으로 생성해준다.private final로 처리되어 불변(immutable) 객체가 된다.보일러플레이트 코드❓
: 어떤 기능을 만들 때 항상 비슷한 형태로 반복적으로 작성해야 하는 코드.
주로 프레임워크의 규칙이나 문법 때문에 필요하지만, 실제 로직은 거의 없는 코드들
package lesson07;
import java.time.LocalDate;
import java.util.*;
record Ex08_WordDTO(String word, String meaning, String level, LocalDate regDate){
public Ex08_WordDTO(String word, String meaning, String level){
this(word, meaning, level, LocalDate.now());
}
@Override
public String toString() {
return "[단어] " + word + " | 뜻: " + meaning + " | 레벨: " + level + " | 등록일: " + regDate;
}
}
//컨트롤러
class Ex08_WordController {
private final Ex08_WordService wordService = new Ex08_WordService();
public void register(String word, String meaning, int levelNum) {
String level = convertLevel(levelNum);
if (level == null) {
System.out.println("잘못된 레벨입니다.(1:초급, 2:중급, 3:고급)");
return;
}
try {
Ex08_WordDTO dto = new Ex08_WordDTO(word, meaning, level);
wordService.registerWord(dto);
} catch (IllegalArgumentException e) {
System.out.println("등록 실패: " + e.getMessage());
}
}
public void printAllWords() {
List<Ex08_WordDTO> list = wordService.getAllWords();
if (list.isEmpty()) {
System.out.println("📂 등록된 단어가 없습니다.");
} else {
System.out.println("📘 등록된 단어 목록:");
for (Ex08_WordDTO dto : list) {
System.out.println("- " + dto);
}
}
}
public void query(String word) {
Ex08_WordDTO dto = wordService.findWord(word);
if (dto == null) {
System.out.println("🔍 '" + word + "' 단어는 등록되어 있지 않습니다.");
} else {
System.out.println("🔎 조회 결과: " + dto);
}
}
private String convertLevel(int levelNum) {
return switch (levelNum) {
case 1 -> "초급";
case 2 -> "중급";
case 3 -> "고급";
default -> null;
};
}
}
//서비스 클래스
class Ex08_WordService {
private final Ex08_WordRepository repository = new Ex08_WordRepository();
public void registerWord(Ex08_WordDTO dto) {
if (dto.word().isBlank() || dto.meaning().isBlank()) {
throw new IllegalArgumentException("단어와 뜻은 반드시 입력해야 합니다.");
}
repository.save(dto);
}
public List<Ex08_WordDTO> getAllWords() {
return repository.findAll();
}
public Ex08_WordDTO findWord(String word) {
return repository.findByWord(word);
}
}
//레파지토리 데이터 저장
class Ex08_WordRepository {
private final Map<String, Ex08_WordDTO> wordMap = new HashMap<>();
// private final HashMap<String, WordDTO> meaningMap = new HashMap<>();
public void save(Ex08_WordDTO dto) {
wordMap.put(dto.word(), dto);
System.out.println("저장 완료: " + dto.word());
}
public List<Ex08_WordDTO> findAll() {
return new ArrayList<>(wordMap.values());
}
public Ex08_WordDTO findByWord(String word) {
return wordMap.get(word);
}
}
public class Ex08_Main {
public static void main(String[] args) {
Scanner sc = new Scanner(System.in);
Ex08_WordController controller = new Ex08_WordController(); // con
while (true) {
System.out.println("영어 단어 사전");
System.out.println("1. 단어 등록");
System.out.println("2. 전체 단어 목록 보기");
System.out.println("3. 단어 상세 조회");
System.out.println("0. 종료");
System.out.print("선택: ");
int choice = Integer.parseInt(sc.nextLine());
switch (choice) {
case 0 -> {
System.out.println("프로그램을 종료합니다.");
sc.close();
return;
}
case 1 -> {
System.out.print("영단어를 입력: ");
String word = sc.nextLine();
System.out.print("뜻 입력: ");
String meaning = sc.nextLine();
System.out.print("레벨 선택(1:초급, 2:중급, 3:고급): ");
int level = Integer.parseInt(sc.nextLine());
controller.register(word, meaning, level);
}
case 2 -> controller.printAllWords();
case 3 -> {
System.out.print("조회할 영단어 입력: ");
String word = sc.nextLine();
controller.query(word);
}
default -> System.out.println("잘못된 메뉴입니다.");
}
}
}
}
package lesson07;
import java.util.Scanner;
record Ex09_Point(int x, int y){
public double distanceTo(Ex09_Point other){
int dx = this.x - other.x;
int dy = this.y - other.y;
return Math.sqrt(dx * dx + dy * dy);
}
@Override
public String toString() {
return "(" + x + ", " + y + ")";
}
}
class Ex09_StoreService{
private final Ex09_Point storeLocation = new Ex09_Point(0, 0);
public boolean canDeliver(Ex09_Point customerLocation) {
double distance = storeLocation.distanceTo(customerLocation);
System.out.println("거리 계산: " + distance);
return distance <= 5.0;
}
}
public class Ex09_Main {
public static void main(String[] args) {
Scanner sc = new Scanner(System.in);
Ex09_StoreService service = new Ex09_StoreService();
System.out.println("가게 기준점은 (0, 0)입니다.");
System.out.println("고객 위치 X좌표 입력: ");
int x = Integer.parseInt(sc.nextLine());
System.out.println("고객 위치 Y좌표 입력: ");
int y = Integer.parseInt(sc.nextLine());
Ex09_Point customer = new Ex09_Point(x, y);
System.out.println("고객 위치: " + customer);
if(service.canDeliver(customer)){
System.out.println("배달 가능 지역입니다.");
}else{
System.out.println("배달 불가능한 지역입니다.");
}
sc.close();
}
}