table of contents
함수
- 코드를 알뜰하게 재사용하세요
- 하나하나 수정하다 오타 나면 어쩔래
- 그거 수정하는 시간은 공짜냐?
- 자바스크립트는 함수를 정의하기 전에 호출부터 해도 실행이 된다. 진짜 이상한 언어임. 코드 실행할 때 정의문이 전부 위로 끌어올려진대
함수 정의문과 함수 호출문을 기억하세요
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
public class DAY2_1 {
public static int getDiscountPrice(int basePrice, int discountAmount, double discountRate) { // -> "함수 정의문" 이름 기억하세요
return (int)(basePrice - discountRate * discountAmount);
}
public static void main(String[] args) {
int discountAmount = 30_000;
double discountRate = 1.2;
int jeju = getDiscountPrice(200_000, discountAmount, discountRate);
int gn = getDiscountPrice(150_000, discountAmount, discountRate);
int busan = getDiscountPrice(180_000, discountAmount, discountRate);
System.out.println("jeju 할인된 가격: " + jeju);
System.out.println("gn 할인된 가격: " + gn);
System.out.println("busan 할인된 가격: " + busan);
}
}
/*
jeju 할인된 가격: 164000
gn 할인된 가격: 114000
busan 할인된 가격: 144000
*/
- 같은 클래스 안에서 함수 정의의 순서는 상관 없으나 보통 main 함수는 가장 뒤에 작성하는 것을 권장함
- 함수 정의문은 “함수 이름”과 “매개변수”, “반환값”으로 구성됨
- 함수 이름은 함수의 기능을 나타내는 명사나 동사로 작성하는 것이 좋음
- 매개변수는 함수가 필요한 데이터를 전달받는 변수로, 함수 정의문에서 괄호 안에 작성됨
- 반환값은 함수가 작업을 수행한 후 결과를 반환하는 값으로, 함수 정의문에서 반환 타입으로 작성됨
- 반환형이 void인 함수는 반환값이 없다
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
public class DAY2_2 {
public static void say(String message) {
System.out.println(message);
}
public static void main(String[] args) {
say("Hello, World!\n");
int a = 10;
int b = 20;
int c = add(a, b);
System.out.println("a + b = " + c);
}
public static int add(int a, int b) {
return a + b;
}
}
/*
Hello, World!
a + b = 30
*/
참조 전달과 값 전달을 구분하세요
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
class Phone {
int battery = 10;
}
public class DAY2_3 {
public static void change(int a) {
a = 100;
}
public static void batteryCharge(Phone ph) {
ph.battery = 100;
}
public static void main(String[] args) {
Phone myPhone = new Phone();
System.out.println("Before value change: " + myPhone.battery);
change(myPhone.battery);
System.out.println("After value change: " + myPhone.battery);
System.out.println("-----------------------------");
System.out.println("Before battery ref charge: " + myPhone.battery);
batteryCharge(myPhone);
System.out.println("After battery ref charge: " + myPhone.battery);
}
}
/*
Before value change: 10
After value change: 10
-----------------------------
Before battery ref charge: 10
After battery ref charge: 100
*/
DTO
DTO(Data Transfer Object)는 프로세스 간 데이터를 전달하는 객체를 의미합니다. 주로 계층 간(Layered Architecture) 데이터 교환을 위해 사용되며, 내부에는 비즈니스 로직을 포함하지 않고 오직 데이터 접근을 위한 Getter와 Setter(또는 생성자)만을 가집니다.
DTO 설계의 핵심 목적
- 데이터 캡슐화: 도메인 모델(Entity)의 내부 구조를 숨기고 외부 인터페이스에 필요한 데이터만 선택적으로 노출합니다.
- 통신 효율성: 원격 호출 시 여러 개의 매개변수를 하나의 객체로 묶어 전달함으로써 네트워크 오버헤드를 줄입니다.
- 관심사 분리: 데이터베이스 구조를 반영하는 엔티티와 클라이언트 요구사항에 맞춘 데이터를 분리하여 상호 의존성을 낮춥니다.
DTO 설계 시 준수 사항
- 가변성 제어: 최근 설계 추세는 데이터의 무결성을 위해
final키워드를 사용하거나 생성자를 통해 값을 주입받는 불변(Immutable) 객체로 설계하는 것을 권장합니다. - 도메인 분리: DTO는 표현 계층(Presentation Layer)에서 사용되며, 영속성 계층(Persistence Layer)의 엔티티가 클라이언트까지 전달되지 않도록 변환 로직(Mapper)을 거쳐야 합니다.
- 순수성 유지: 비즈니스 로직이나 복잡한 계산식은 포함하지 않으며 단순한 데이터 저장소 역할만 수행해야 합니다.
디자인 패턴과의 연관성
DTO(Data Transfer Object)와 템플릿 메서드 패턴은 서로 다른 계층의 개념
- DTO는 계층 간 데이터 교환을 위한 데이터 구조(Data Structure) 설계에 해당.
- 템플릿 메서드 패턴은 코드의 재사용성과 확장성을 위한 행위(Behavioral) 설계 패턴.
즉, DTO를 생성하거나 변환하는 과정(예: Entity를 DTO로 변환하는 로직)에서 공통된 절차가 있다면 템플릿 메서드 패턴을 적용하여 구조화할 수 있으나, 두 개념이 동일한 것은 아님
DTO(Data Transfer Object)는 GoF(Gang of Four)의 23가지 디자인 패턴에는 포함되지 않으나, 마틴 파울러(Martin Fowler)가 정의한 엔터프라이즈 애플리케이션 아키텍처 패턴(Patterns of Enterprise Application Architecture) 중 하나로 분류됨
엔터프라이즈 애플리케이션 아키텍처 패턴 참고: https://martinfowler.com/articles/enterprisePatterns.html
DTO를 만들어서 코드를 좀 보기 좋게 해보세요
요구사항
- DTO 설계 (AlarmRequest):장비명(String), 에러코드(int), 현재온도(double)를 포함하세요.
함수 설계 (generateMessage):
- 파라미터로 AlarmRequest객체 하나를 받습니다.
에러코드에 따라 다른 메시지를 리턴합니다.
100: “과열 발생”
200: “전원 공급 불안정”
그 외: “알 수 없는 오류”
- 리턴값: “[장비명] 메시지 (현재온도: 00.0도)”형태의 문자열.
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
class AlarmRequest {
String deviceName;
int errorCode;
double currentTemperature;
public AlarmRequest(String deviceName, int errorCode, double currentTemperature) {
this.deviceName = deviceName; // 자기 참조 변수: 미래에 생성될 인스턴스에 바인딩됨
this.errorCode = errorCode;
this.currentTemperature = currentTemperature;
}
}
public class DAY2_4 {
public static void main(String[] args) {
AlarmRequest request1 = new AlarmRequest("냉장고", 100, 75.5);
AlarmRequest request2 = new AlarmRequest("에어컨", 200, 30.0);
AlarmRequest request3 = new AlarmRequest("세탁기", 300, 45.0);
System.out.println(generateMessage(request1));
System.out.println(generateMessage(request2));
System.out.println(generateMessage(request3));
}
public static String generateMessage(AlarmRequest request) {
String message;
switch (request.errorCode) {
case 100:
message = "과열 발생";
break;
case 200:
message = "전원 공급 불안정";
break;
default:
message = "알 수 없는 오류";
}
return String.format("[%s] %s (현재온도: %.1f도)", request.deviceName, message, request.currentTemperature);
}
}
/*
[냉장고] 과열 발생 (현재온도: 75.5도)
[에어컨] 전원 공급 불안정 (현재온도: 30.0도)
[세탁기] 알 수 없는 오류 (현재온도: 45.0도)
*/
객체를 쓰세요
- 일단 객체 지향 프로그래밍이 뭐냐. 표현 가능한 모든 것을 객체로 표현하고자 하는 프로그래밍 방식
- 함수 지향 프로그래밍은 객체 대신 함수를 쓴 거라고 보면 됨. 사상이 다른 거니까 틀린 건 아님
자료구조를 아세요
- 기본적으로 1변수 1값. 문제가 뭐냐? 저장할 값은 많은데 일일이 만들면 너무 비효율
- 배열에 넣기엔 용도에 따라 요구되는 최적 성능이 달라서 이것도 비효율
- 요구사항에 따른 적절한 자료구조를 쓰세요
자료구조를 좀 더 알아두세요
ArrayList
공정 발생 알림 누적 시스템
스마트팩토리 라인에서 발생하는 알림을 발생한 순서대로 저장하고 관리해야 합니다.
요구사항:
- String데이터를 저장할 ArrayList를 생성하세요.
- add()메서드를 사용하여 최소 3개의 알림 메시지를 입력하세요.
- 현재 저장된 로그가 총 몇 건인지 출력하세요.
- 모든 로그를 순서대로 출력하세요.
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
import java.util.ArrayList;
public class DAY2_5 {
public static void main(String[] args) {
ArrayList<String> logs = new ArrayList<>();
logs.add("장비 A에서 오류가 발생했습니다.");
logs.add("장비 B에서 오류가 발생했습니다.");
logs.add("장비 C에서 오류가 발생했습니다.");
System.out.println("현재 저장된 로그 수: " + logs.size());
System.out.println("모든 로그:");
for (String log : logs) {
System.out.println(log);
}
}
}
/*
현재 저장된 로그 수: 3
모든 로그:
장비 A에서 오류가 발생했습니다.
장비 B에서 오류가 발생했습니다.
장비 C에서 오류가 발생했습니다.
*/
hashmap
실시간 장비 상태 조회
수백 대의 장비 중 특정 ID를 가진 장비의 가동 상태(RUN, STOP, ERROR)를 즉시 찾아내야 합니다.
- Key는 String(ID), Value는 String(상태)인 HashMap을 생성하세요.
- 장비 ID 3개와 각각의 상태를 입력하세요.
- 특정 장비 ID(예: “P-500”)를 조회하여 현재 상태를 출력하세요.
- 만약 없는 ID를 조회하면 “등록되지 않은 장비입니다”라고 출력하세요.
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
public class DAY2_6 {
public static void main(String[] args) {
java.util.HashMap<String, String> equipmentStatus = new java.util.HashMap<>();
equipmentStatus.put("P-100", "RUN");
equipmentStatus.put("P-200", "STOP");
equipmentStatus.put("P-300", "ERROR");
String queryId = "P-500";
String status = equipmentStatus.get(queryId);
if (status != null) {
System.out.println("장비 ID: " + queryId + ", 상태: " + status);
} else {
System.out.println("장비 ID: " + queryId + ", 등록되지 않은 장비입니다");
}
queryId = "P-300";
status = equipmentStatus.get(queryId);
if (status != null) {
System.out.println("장비 ID: " + queryId + ", 상태: " + status);
} else {
System.out.println("장비 ID: " + queryId + ", 등록되지 않은 장비입니다");
}
}
}
/*
장비 ID: P-500, 등록되지 않은 장비입니다
장비 ID: P-300, 상태: ERROR
*/
객체 지향을 하세요
- 순차 지향, 절차 지향, 객체 지향
객체 지향의 구성 요소
- 객체 지향의 필요성
- 변수와 관련 함수가 흩여져 있어서 관리가 어렵다. → 관련된 데이터와 함수를 하나의 객체로 묶는다. (가독성 / 유지보수)
- 같은 종류의 데이터를 계속 새로운 변수로 생성 해야 한다. → 클래스 설계도로 객체를 복사하여 사용 (재사용성)
- 기능을 재활용 하려면 코드를 복사해야 한다. → 공통 기능은 클래스로 묶고 상속/구성으로 공유
- 프로그램 구조가 현실과 동떨어져 있다. → 현실 세계의 개념을 코드로 구조화 가능
- 생성자: 객체가 생성될 때 딱 한번만 실행하는 코드. 개념으로 정의된 객체를 데이터를 가진 실체로 만듦
- 상속: 같은 건 같은 것끼리 모아서 정리해놓자. → 공통 기능 재사용, 코드 재사용성 향상
- 오버라이드: 기반 클래스가 정의한 개념을 파생 클래스가 덮어쓰기하는 것
- 만약 어떤 클래스의 멤버들이 다 공개되어 있다고 치자. 부적절한 조작의 가능성이 아주 열려있다. → 정보를 은닉해야 한다 → 접근 제한자(제어자) 사용
- private: 클래스 안에서만 가능
- public: 아무데나 공개됨
- (default): 같은 패키지 안에서만 가능
- protected는 요즘 잘 안쓴다. 유지보수가 어렵고 파생 클래스에게 너무 많은 것을 오픈하기 때문. 필요하다면 private와 제한적 접근 허용(get/set-ter)으로 대체하는 편.



