객체지향의 사실과 오해 3장 "타입과 추상화"
[개인적으로 요약하여 저자님의 생과가 다르게 전달될 수 있습니다..]
객체지향의 핵심은 추상화이다. 추상화란, 현실 세계에서 출발하지만 필요한 정보만을 추출하여 단순화하는 것이다.
분류와 일반화는 추상화를 위한 도구이다. 이를 통해 객체를 단순화하고, 객체 간의 관계를 명확하게 정의할 수 있다.
분류는 객체를 특정 그룹으로 분류하는 것이다. 예를 들어, 사람을 여성과 남성으로 분류하거나, 동물을 포유류와 조류로 분류할 수 있다. 분류를 통해 객체를 그룹화하고, 이를 기반으로 객체 간의 관계를 파악할 수 있다. 객체를 잘 설계하여야 유지보수가 편리한 애플리케이션을 설계할 수 있다. 최대한 직관적으로 설계하자.
일반화는 객체 간의 공통점을 찾아내서 이를 상위 개념으로 일반화하는 것이다. 이를 통해 객체 간의 관계를 더욱 명확하게 정의할 수 있다. 예를 들어, 새와 곤충은 모두 날개를 가지고 있으므로, 이들을 날개를 가진 동물로 일반화할 수 있다.
객체지향에서 가장 중요한 것은 동적으로 변하는 객체의 '상태'와 상태를 변경하는 '행위'이다.
애플리케이션을 설계할 때는 동적인 관점과 정적인 관점을 모두 고려해야 한다.
객체가 외부에 제공해야 하는 행동을 먼저 생각하여, 이 행동에 따라 객체를 분리할 수 있다
객체를 결정하는 것은 행동이다. 데이터는 단지 행동을 따르기 위한 수단일 뿐이며, 이것이 객체를 객체답게 만드는 가장 핵심적인 원칙이다. 객체를 데이터 중심으로 설계하면, 객체의 상태가 변경되었을 때 이에 따른 행동을 처리하기 어렵게 된다. 따라서 객체의 행동에 초점을 맞추어 객체를 설계해야 한다.(DDD -> RDD를 고안한 이유)
SQL
1. CONCAT(): 문자열을 결합하여 하나의 문자열로 만드는 함수
SELECT CONCAT(first_name, ' ', last_name, ' (', email, ')') AS user_info FROM users;
2. SUBSTR() : 문자열에서 일부분을 추출하여 반환하는 함수
SUBSTR(문자열, 시작 위치, 길이)
/* 시작위치는 1부터 시작한다. 길이를 생략하는 경우 마지막까지 찾는다*/
SELECT SUBSTR(name, 1, 3) FROM users;
3.INSTR() : 문자열 내에서 특정 문자열이 나타나는 위치를 찾아주는 함수 ( 없는 경우 0이 반환된다)
INSTR(원본 문자열, 찾을 문자열 , 시작 위치 , 발견 위치)
/* 원본 문자열 : 찾을 문자열
시작 위치: 검색을 시작할 위치를 지정한다. (생략시 1부터 시작)
발견위치 : 찾은 문자열의 발견 위치. (생략시에는 제일 처음 발견된 위치가 출력된다.)
*/
SELECT INSTR('Hello, World!', 'l', 3) AS position; -- 3번째 위치부터 찾음
SELECT INSTR('Hello, World!', 'l', 3, 2) AS position; -- 3번째 위치부터 두 번째로 발견한 위치를 찾음
1. sql에 조건문을 사용하는 방법
SELECT IF(조건, 참값, 거짓값) AS 결과;
--학생의 수업이 5개 이상인 경우 10% 할인율을, 3개 이상인 경우 5% 할인율을, 그 외의 경우는 할인율을 0으로 설정하는 경우.
SELECT
name,
num_classes,
IF(num_classes >= 5, 0.1, IF(num_classes >= 3, 0.05, 0)) AS discount_rate
FROM students;
-- 미성년과 성년을 구분하는
SELECT name, age,
IF(age >= 18, '성인', '미성년자') AS status
FROM users;
SELECT
column1,
column2,
...,
CASE
WHEN condition1 THEN result1
WHEN condition2 THEN result2
...
ELSE result /* 생략 가능, 생략시에는 else인 경우 null반환) */
END
FROM
table_name;
--학생의 수업이 5개 이상인 경우 10% 할인율을, 3개 이상인 경우 5% 할인율을, 그 외의 경우는 할인율을 0으로 설정하는 경우.
SELECT
name,
num_classes,
CASE
WHEN num_classes >= 5 THEN 0.1
WHEN num_classes >= 3 THEN 0.05
ELSE 0
END AS discount_rate
FROM students;
-- 미성년과 성년을 구분하는
SELECT name, age,
CASE
WHEN age >= 18 THEN '성인'
ELSE '미성년자'
END AS status
FROM users;
2. REGEXP(), RLIKE() : 정규식을 활용해서 확인하는 경우
-- 특정 단어를 포함하는 컬럼을 찾기
SELECT *
FROM my_table
WHERE column_name REGEXP 'specific_word';
-- 특정 패턴과 일치하는 행 찾기
SELECT *
FROM my_table
WHERE column_name RLIKE '^pattern.*$';
-- 특정 패턴과 일치하는 행 (주민번호)
SELECT *
FROM table_name
WHERE column_name REGEXP '^[0-9]{6}-?[0-9]{7}$';
/* ^시작, [0-9] 0~9안의 숫자가 {6} 6번 반복하고 -? -가 0번이나 1번 나올수 있다. $는 문자열의 끝을 의미한다. */
-- 특정 패턴과 일치하는 행 (전화번호)
SELECT *
FROM table_name
WHERE column_name REGEXP '^[0-9]{2,3}-?[0-9]{3,4}-?[0-9]{4}$';
/*^시작, [0-9] 0~9안의 숫자가 {2,3} 2~3번 반복하고 -? -가 0번이나 1번 나올수 있다. $는 문자열의 끝을 의미한다.*/
백준 17281 공 ⚾️ (자바, 골드 4, 구현)
package 백준.구현;
import java.io.BufferedReader;
import java.io.IOException;
import java.io.InputStreamReader;
import java.util.StringTokenizer;
public class boj_17281_공 {
private static int inning;
private static int[][] score;
private static final int NINE = 9;
private static final int[] permu = new int[NINE];
private static final boolean[] visited = new boolean[NINE];
private static int maxScore = 0;
public static void main(String[] args) throws IOException {
BufferedReader br = new BufferedReader(new InputStreamReader(System.in));
StringTokenizer st;
inning = Integer.parseInt(br.readLine());
score = new int[inning][NINE];
for (int j = 0; j < inning; j++) {
st = new StringTokenizer(br.readLine());
for (int i = 0; i < NINE; i++) {
score[j][i] = Integer.parseInt(st.nextToken());
}
}
// 4번째 타수는 이미 결정되었다.
permu[3] = 0;
visited[0] = true;
dfs(0);
System.out.println(maxScore);
}
private static void dfs(int nowDepth) {
if (nowDepth == NINE) {
// System.out.println(Arrays.toString(permu));
checkScore();
} else if (nowDepth == 3) {
dfs(nowDepth + 1);
} else {
for (int i = 0; i < NINE; i++) {
if (visited[i])
continue;
visited[i] = true;
permu[nowDepth] = i;
dfs(nowDepth + 1);
visited[i] = false;
}
}
}
private static void checkScore() {
boolean[] people;
int nowScore = 0;
int outScore;
int nowPlayer = 0;
for (int i = 0; i < inning; i++) {
people = new boolean[4];
outScore = 0;
while (outScore < 3) { // 3아웃
nowPlayer %= 9;
if (score[i][permu[nowPlayer]] == 0)
outScore++;
else {
// 뒤에서 부터 가장 점수를 옮긴다.
int tempScore = score[i][permu[nowPlayer]];
if (tempScore == 4) {// 홈런
for (int k = 0; k <= 3; k++) {
if (people[k]) {
people[k] = false;
nowScore++;
}
}
nowScore++;// 자기자신까지
} else { // 1,2,3
for (int k = 3; 1 <= k; k--) {
if (people[k]) {
people[k] = false;
if (k + tempScore >= 4)
nowScore++;
else
people[k + tempScore] = true;
}
}
people[tempScore] = true;
}
}
nowPlayer++;
}
}
// System.out.println(nowScore);
maxScore = Math.max(nowScore, maxScore);
}
}
'2023' 카테고리의 다른 글
[0406] (0) | 2023.04.07 |
---|---|
[0404] TIL (0) | 2023.04.05 |
Stomp convertAndSend (0) | 2023.04.02 |
[TIL]0327 : ERD(식별관계),@PrePersist (0) | 2023.03.28 |
[TIL] stomp origin문제, socket에서의 JWT 처리 (0) | 2023.03.24 |
댓글