From 85d578105e8f681d37107ef6faee36327bd33840 Mon Sep 17 00:00:00 2001 From: baaamk <136908616+baaamk@users.noreply.github.com> Date: Mon, 25 Mar 2024 13:27:45 +0900 Subject: [PATCH 01/56] =?UTF-8?q?Rename=20week01/week01.md=20to=20week01?= =?UTF-8?q?=EB=B0=A9=ED=98=84=EC=9A=B0.md?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .../week01.md => "week01\353\260\251\355\230\204\354\232\260.md" | 0 1 file changed, 0 insertions(+), 0 deletions(-) rename week01/week01.md => "week01\353\260\251\355\230\204\354\232\260.md" (100%) diff --git a/week01/week01.md "b/week01\353\260\251\355\230\204\354\232\260.md" similarity index 100% rename from week01/week01.md rename to "week01\353\260\251\355\230\204\354\232\260.md" From 9f7b1035207f2e647b8ad904da436cf723d3ae0f Mon Sep 17 00:00:00 2001 From: baaamk <136908616+baaamk@users.noreply.github.com> Date: Mon, 25 Mar 2024 13:28:20 +0900 Subject: [PATCH 02/56] =?UTF-8?q?Rename=20week01=EB=B0=A9=ED=98=84?= =?UTF-8?q?=EC=9A=B0.md=20to=20week01/=EB=B0=A9=ED=98=84=EC=9A=B0.md?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .../\353\260\251\355\230\204\354\232\260.md" | 0 1 file changed, 0 insertions(+), 0 deletions(-) rename "week01\353\260\251\355\230\204\354\232\260.md" => "week01/\353\260\251\355\230\204\354\232\260.md" (100%) diff --git "a/week01\353\260\251\355\230\204\354\232\260.md" "b/week01/\353\260\251\355\230\204\354\232\260.md" similarity index 100% rename from "week01\353\260\251\355\230\204\354\232\260.md" rename to "week01/\353\260\251\355\230\204\354\232\260.md" From 683d5078f4f3863cba6c573e2a28c0ecb50e5096 Mon Sep 17 00:00:00 2001 From: baaamk <136908616+baaamk@users.noreply.github.com> Date: Mon, 25 Mar 2024 18:55:41 +0900 Subject: [PATCH 03/56] =?UTF-8?q?Update=20=EB=B0=A9=ED=98=84=EC=9A=B0.md?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .../\353\260\251\355\230\204\354\232\260.md" | 103 +++++++++++++++++- 1 file changed, 102 insertions(+), 1 deletion(-) diff --git "a/week01/\353\260\251\355\230\204\354\232\260.md" "b/week01/\353\260\251\355\230\204\354\232\260.md" index 3f1a1db..18bcfbe 100644 --- "a/week01/\353\260\251\355\230\204\354\232\260.md" +++ "b/week01/\353\260\251\355\230\204\354\232\260.md" @@ -18,6 +18,41 @@ # 필수 ## 자바 역사와 버전별 특징 +LTS는 Long Term Support로 오랜기간 지원하는 특별한 버전 에디션. +자바에서 많이 쓰는 LTS버전을 주로 정리해보았다. +java1 +1996년 1월에 공개되었으며 발표 이전에 불린 이름은 Oak였다. +안정화 작업을 거친 1.0.2 버전에서 Java로 이름이 바뀌었다. + +java8 +오라클이 java를 인수한 후 첫번재 LTS출시버전 +32비트 지원 공식적인 마지막 버전 +유료버전(오라클), 무료버전(오픈)으로 나뉨 +Unsigned Integer 계산 +람다식 제공 +Stream API제공 +Primitive Type과 Reference Type의 차이점 +Static Link JNI Library 제공 +java11 +Open JDK와 Oracle JDK 통합 +Oracle JDK가 구독형 유료모델로 전환 +G1 GC가 기본 GC로 설정 (GC : Garbage Collection) +람다 지역변수 var 키워드 사용 가능 +컬렉션, 스트림 등에 메소드 추가 + +java17 +recode class 키워드 사용 가능 +애플 M1 및 이후 프로세서 탑재 제품군에 대한 정식 지원 +난수 생성 API 추가 +봉인 클래스(Sealed Class) 정식 추가 +String 여러줄 사용시 텍스트 블록 기능 사용 가능 +NumberFormat,DateTimeFormatter 기능 향상 +Stream.toList() 사용 가능 + +자바 버전 사용비율은 8은 원래 많았지만 17채택 비율이 많아지는 중이다 +17선택 이유로는 java 서포트 기간이 길다, 신규버전을 위한 대비용, 스프링부트 3.0부터는 자바 17이상을 지원 등이 있다. + +현재는 21까지 나왔으며 21도 LTS 지원을 한다고한다. --- @@ -26,25 +61,91 @@ --- ## JAVA의 접근 제어자 +public, protected, default, private 네가지가 있다. +purblic의 적용 대상은 클래스, 필드, 생성자, 메소드 전부 가능하며 접근할 수 없는 클래스는 없다. +protected의 적용대상은 필드, 생성자, 메소드가 가능하며 접근할 수 없는 클래스는 자식클래스 외 다른 패키지에 소속된 클래스다. +default는 클래스, 필드, 생성자, 메소드 에서 적요앧상이며, 같은 패키지에 소속된 클래스에서만 사용이 가능하다. +private는 필드, 생성자, 메소드 에서 적용가능하며 외부 클래스들은 접근 불가능하다. --- ## static 키워드 +static은 '고정된' 또는 '공통적인'의 의미를 가지고 있다. +즉 모든 객체가 공유하는 값이다. +static 값은 클래스 이름을 통해서 접근해야 하며, 객체를 생성하지 않고도 사용할 수 있다. +특히 상수에 많이 쓰인다. +static이 붙은 멤버변수는 객체의 개수에 상관 없이 단 하나만 생성되며, +이를 모든 객체가 공유하기 때문에 메모리를 효율적으로 사용할 수 있다. + +멤버변수 중 모든 객체에 공통으로 사용하는 것에 static을 붙인다. +메서드 내에서 인스턴스 변수나 인스턴스 메서드를 사용하지 않는 메서드에 +staitc을 붙이는 것을 고려한다. + +나온 의미 +멤버변수 +모든 객체에 공통적으로 사용되는 클래스 변수가 된다. +클래스 변수는 인스턴스를 생성하지 않고도 사용 가능하다. +클래스가 메모리에 로드될 때 생성된다. + +메서드 +객체를 생성하지 않고도 호출이 가능한 static 메서드가 된다. +static메서드 내에서는 인스턴스멤버들을 직접 사용할 수 없다. --- ## final 키워드 +기본적으로 final이 붙으면 변경할 수 없다고 생각하면 된다. +1. final 변수 +변수 선언할 때 클래스 앞 final 키워드가 들어간다. 이 변수는 초기화 후 변경이 불가능 하다. +2. fianl arguments(인자) +final로 선언된 인자는 메소드 내에서 변경이 불가능하다. 따라서 다음과 같이 final int로 선언한 number는 읽을 수 있지만, number = 2처럼 값을 변경하려고 하면 컴파일 에러가 발생한다 +3.final 클래스 +클래스에 final을 붙이면 다른 클래스가 상속할 수 없는 클래스가 된다. 다음과 같이 final 클래스를 상속하려고 하면 컴파일 에러 발생. +4.final 메소드 +final 메소드는 Override가 안되도록 한다. 예를 들어 다음과 같이 MJ 클래스를 상속하는 MMJ 클래스에서는 getHello()를 재정의할 수 없다. Override하려고 하면 컴파일 에러가 발생한다. + +재할당만을 막아줄 뿐, 참조하고 있는 객체 내부의 상태가 변하지 않았음을 보장해주지는 않는다. --- ## 오버로딩(Overloading)과 오버라이딩(Overriding) +오버로딩 +메서드의 이름은 같고 매개변수의 유형과 개수가 다르도록 하는 것 +- 리턴값만을 다르게 갖는 오버로딩은 작성할 수 없다. + +오버라이딩 +-상위 클래스가 가지고 있는 메서드를 하위 클래스가 재정의해서 사용하는 것을 의미한다 +메서드의 이름은 물론 파라미터의 개수나 타입도 동일해야 하며, 주로 상위 클래스의 동작을 상속받는 하위 클래스에서 변경하기 위해 사용된다 --- ## 추상 클래스와 인터페이스 +공통점 +객체생성: 객체를 생성(인스턴스화)할 수 없다. +추상메서드: 추상 메서드 포함 +기능적 목적: 상속받는 클래스에서는 추상 메서드를 반드시 재정의할여 구현해야 한다. + +차이점 +개념적 목적 +상속 받아서 기능을 확장 | 구현 객체의 동일한 실행 기능 보장 + +클래스 +클래스O | 클래스 X + +일반 메서드 +일반 메서드 정의 가능 | 일반 메서드 정의 불가능(자바 8 이후 static, default 메서드 정의 가능) + +멤버 변수 +클래스와 동일하게 변수 선언 및 사용 가능 | 상수만 사용 가능 + +상속 키워드 +extends | implements + +다중상속 +불가능 | 가능 --- @@ -68,7 +169,7 @@ # 선택사항 (추가로 공부하면 좋은 것들입니다!) - +이번주 내로 추가하도록 하겠습니다! ## Java Annotation --- From d026878f3f84382180dd1c9f416aaf5cad69ac0f Mon Sep 17 00:00:00 2001 From: baaamk <136908616+baaamk@users.noreply.github.com> Date: Mon, 25 Mar 2024 19:35:31 +0900 Subject: [PATCH 04/56] =?UTF-8?q?Update=20=EB=B0=A9=ED=98=84=EC=9A=B0.md?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .../\353\260\251\355\230\204\354\232\260.md" | 61 +++++++++++++++++++ 1 file changed, 61 insertions(+) diff --git "a/week01/\353\260\251\355\230\204\354\232\260.md" "b/week01/\353\260\251\355\230\204\354\232\260.md" index 18bcfbe..15e8de3 100644 --- "a/week01/\353\260\251\355\230\204\354\232\260.md" +++ "b/week01/\353\260\251\355\230\204\354\232\260.md" @@ -150,15 +150,76 @@ extends | implements --- ## JAVA Enum +열거형으로 서로 관련된 상수들을 정의하여 편리하게 사용하기 위한 자료형 +장수들을 사용하면소 발생했던 문제점, 불편했던 점 들을 개선하고자 jdk1.5부터 추가됨 + + +생긴 이유 +코드의 가독성 높혀줌 +열거형의 값뿐아니라 타입까지 관리해 오류 저하 +상수와 리터럴이 논리적 연관이 없다 +서로가른 개넘끼리 이름충돌 가능 +서로 다른 개념임에도 비교 연산 가능 + + 개념 +num에 정의된 상수들은 해당 enum type의 객체이다 + +enum Fruit {apple, peach, banana} + +Enum에 생성자와 메서드를 추가할 수 있다 + +enum은 위와 같이 생성자를 정의할 수 있는데, 접근제어자는 private이기 때문에 외부에서 접근할 수 없으며 열거형의 멤버 중 하나를 호출하면 열거된 모든 상수의 객체가 생성된다 + +값을 가진 enum상수는 생성자도 함께 정의해줘야 함 --- ## 객체지향 +객체 지향 프로그래밍에서는 이와 같은 각각의 객체를 추상화시켜 속성(state)과 기능(behavior)으로 분류한 후에 이것을 다시 각각 변수(variable)와 함수(function)로 정의. + +프로그래밍에서 필요한 데이터를 추상화시켜 상태와 행위를 가진 객체를 만들고 그 객체들 간의 유기적인 상호작용을 통해 로직을 구성하는 프로그래밍 방법 +여러 독립적인 부품들의 조합,  +즉 객체들의 유기적인 협력과 결합으로 파악하고자 하는 컴퓨터 프로그래밍의 패러다임 + +장점 +코드 재사용 용이: 클래스, 상속 이용 +유지보수 쉬움: 해당 부분만 수정 +대형프로젝트 적합 : 업무분담이 쉬움 + +처리속도가 절차지향보다 느림 +객체많으면 용량 커질 수 있음 +설계시 많은 시간과 노력이 듦 --- ## 객체지향 4대 특성 +1. 추상화 +객체의 공통적인 속성과 기능을 추출하여 정의하는것 + + +2. 상속 +기존의 클래스를 재활용하여 새로운 클래스를 작성하는 자바의 문법 요소 + 클래스로부터 확장된 여러 개의 하위 클래스들이 모두 상위 클래스의 속성과 기능들을 간편하게 사용 +반복적인 코드를 최소화하고 공유하는 속성과 기능에 간편하게 접근 +재사용성 용이 + +3. 다형성 +객체 지향 프로그래밍의 꽃 +어떤 객체의 속성이나 기능이 상황에 따라 여러 가지 형태를 가질 수 있는 성질 +어떤 객체의 속성이나 기능이 그 맥락에 따라 다른 역할을 수행할수 있는 객체 지향의 특성 +오버라이딩 오버로딩이 그 예 +4. 캡슐화 +서로 연관있는 속성과 기능들을 하나의 캡슐(capsule)로 만들어 데이터를 외부로부터 보호하는 것 +이유 +• 데이터 보호(data protection) – 외부로부터 클래스에 정의된 속성과 기능들을 보호 + +• 데이터 은닉(data hiding) – 내부의 동작을 감추고 외부에는 필요한 부분만 노출 + + +각 객체 고유의 독립성과 책임 영역을 안전하게 지키고자 하는 목적 + +접근제한자 사용해 캡슐화 --- From 3d51e0f5be4953171a521ffd2da496d5856f90a9 Mon Sep 17 00:00:00 2001 From: baaamk <136908616+baaamk@users.noreply.github.com> Date: Mon, 25 Mar 2024 23:03:49 +0900 Subject: [PATCH 05/56] =?UTF-8?q?Update=20=EB=B0=A9=ED=98=84=EC=9A=B0.md?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .../\353\260\251\355\230\204\354\232\260.md" | 47 +++++++++++++++++++ 1 file changed, 47 insertions(+) diff --git "a/week01/\353\260\251\355\230\204\354\232\260.md" "b/week01/\353\260\251\355\230\204\354\232\260.md" index 15e8de3..7c4fa20 100644 --- "a/week01/\353\260\251\355\230\204\354\232\260.md" +++ "b/week01/\353\260\251\355\230\204\354\232\260.md" @@ -57,6 +57,19 @@ Stream.toList() 사용 가능 --- ## Primitive Type과 Reference Type의 차이점 +Primitive Type +원시형(기본형) 타입은 정수, 실수, 문자, 논리 리터럴 등의 실제 데이터 값을 저장하는 타입. +int, long, double,float,boolean,byte,short,char +기본 타입은 반드시 사용하기 전에 선언 되어야하며, java에서 미리 정의, 제공한다. + +Reference Type +참조타입은 객체를 참조(주소를 저장)하는 타입으로 메모리 번지 값을 통해 객체를 참조하는 타입. +배열, 열거, 클래스, 인터페이스 이렇게 크게 4가지로 나뉨. + +참조형 타입은 빈 객체를 의미하는 Null값 존재. +참조형 타입의 변수는 값이 저장되어 있는 변수의 메모리 주소를 저장하는 공간-> 메모리 영역의 힙(Heap)영역에 저장됨. + +참조형 타입의 특성 상 배열이나 객체를 Null 값으로 받으면 NullPointException에러가 발생. --- @@ -225,6 +238,40 @@ enum은 위와 같이 생성자를 정의할 수 있는데, 접근제어자는 p ## SOLID 원칙 +SPR(Single Responsibility Principle) 단일 책임 원칙 +한 클래스는 하나의 원칙만 가지고 있어야 한다. +다른 책임이 있게되면 결합을 불러온다. +SRP원리를 적용하면 무엇보다도 책임 영역이 확실해지기 때문에 한 책임의 변경에서 다른 책임의 변경으로의 연쇄작용에서 자유로워 진다. +따라서 책임이 적절히 분배되어 코드 가독성, 유지보수 용이 등의 장점이 생긴다. +변경이 있을 때 파급효과가 적으면 단일 책임 원칙이 잘 지켜진다는 것! + +OCP(Open Closed Principle) 개방 폐쇄 원칙 +클래스나 모듈은 확장에는 열려 있으나, 변경에는 닫혀있어야 한다. +면경을 위한 비용 가능한 축소, 확장 위한 비용은 가능한 극대화 +구현에 의존하기 보다는 정의한 인터베이스에 의존하도록 코드를 작성해야 한다. +다형성을 잘 활용해 구현 가능하다. + +LSP(Liskov Substitution Principle) 리스코프 치환 원칙 +서브 타입은 언제나 기반 타입으로 교체할 수 있어야한다. +하위 클래스의 인스턴스는 상휘형 객체 참조 변수에 대입해 상위 클래스의 인스턴스 역할을 하는데 문제가 없어야 한다는 말이다. +상속은 다형성을 통한 확장성 획득을 목표를 하기 때문에 확장에 대한 인터페이스를 준수해야한다. + +ISP(Interface Segregation Principle) 인터페이스 분리 원칙 +하나의 일반적인 인터페이스 보다는, 여러 개의 구체적인 인터페이스가 낫다. +한 클래스는 자신이 사용하지 않는 인터페이스는 구현하지 말아야 한다는 원리다. +가능한 최소한의 인터페이스만을 사용해야 한다는 의미! + +SRP가 클래스의 단일책임 강조<->ISP는 인터페이스의 단일책임 강조 +ex) 자동차 인터페이스 -> 운전 인터페이스, 정비 인터페이스로 분리 +ex) 사용자 인터페이스 -> 운전자 클라이언트, 정비사 클라이언트로 분리 +분리시 정비 인터페이스 자체가 변해도 운전자 클라이언트에 영향을 주지 않음 + + +DIP(Dependency Inversion Principle) 의존 역전 원칙 +추상화에 의존해야하며, 구체화에 의존하면 안된다 +상위 모듈은 하위 모듈의 구현에 의존해서는 안 된다. +하위의 모듈이 상위 모듈에 정의한 추상 타입(interface)에 의존 해야한다. +즉, 상위 클래스에 기반을 두고 생각해야 된다는 것이다. --- From e73f94f416f6c1fef0c7f38ed22eb1598ede19c6 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?=EC=9D=B4=EC=8A=B9=EC=A3=BC?= <129913026+Juuuu-power-e@users.noreply.github.com> Date: Fri, 29 Mar 2024 17:13:50 +0900 Subject: [PATCH 06/56] Create Juuuu-power-e.md . --- week02/Juuuu-power-e.md | 1 + 1 file changed, 1 insertion(+) create mode 100644 week02/Juuuu-power-e.md diff --git a/week02/Juuuu-power-e.md b/week02/Juuuu-power-e.md new file mode 100644 index 0000000..8b13789 --- /dev/null +++ b/week02/Juuuu-power-e.md @@ -0,0 +1 @@ + From 0d7c385d2599fbd8177cb78bb20a8c1ef443fb7c Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?=EC=9D=B4=EC=8A=B9=EC=A3=BC?= <129913026+Juuuu-power-e@users.noreply.github.com> Date: Fri, 29 Mar 2024 17:34:12 +0900 Subject: [PATCH 07/56] Update Juuuu-power-e.md . --- week02/Juuuu-power-e.md | 9 ++++++++- 1 file changed, 8 insertions(+), 1 deletion(-) diff --git a/week02/Juuuu-power-e.md b/week02/Juuuu-power-e.md index 8b13789..f2d09ca 100644 --- a/week02/Juuuu-power-e.md +++ b/week02/Juuuu-power-e.md @@ -1 +1,8 @@ - +1. 잔액이 출금요청액보다 작을 경우를 조건문으로 처리할까, 예외를 발생시켜 처리할까 + 조건문으로 처리할 경우 가독성이 증가하고 빠름 / 예외발생은 구조적 통일성? +2. 생각해보니 1)의 내용을 판단하는 주체는 계좌가 아닌 은행이어야함. + -> 이 경우를 생각해보니 예외처리가 맞는것 같음. ∵ 입금액을 한글로 입력한 것과 같이 입력값의 오류이므로, 또한 다시 입력기회를 줘야하므로 동일하게 처리해야할듯 +3. 아예 BigDecimal의 서브클래스를 만들어 subtract()를 재정의하고 compareTo<0인 경우 예외처리를 하면 어떤가? + -> 코드가 간결해지고 예외 발생의 위치가 논리적으로 옳은방향인듯 하지만 추후 마이너스통장이 추가되거나 기타 상황들에서 문제가 발생할 수 있어 좋은구조는 아닌듯함 +4. +5. From 09888a2dd046a6c112725fbe308ffadb1820d923 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?=EC=9D=B4=EC=8A=B9=EC=A3=BC?= <129913026+Juuuu-power-e@users.noreply.github.com> Date: Fri, 29 Mar 2024 19:41:44 +0900 Subject: [PATCH 08/56] Update Juuuu-power-e.md . --- week02/Juuuu-power-e.md | 30 ++++++++++++++++++++++++++++-- 1 file changed, 28 insertions(+), 2 deletions(-) diff --git a/week02/Juuuu-power-e.md b/week02/Juuuu-power-e.md index f2d09ca..b17de0f 100644 --- a/week02/Juuuu-power-e.md +++ b/week02/Juuuu-power-e.md @@ -4,5 +4,31 @@ -> 이 경우를 생각해보니 예외처리가 맞는것 같음. ∵ 입금액을 한글로 입력한 것과 같이 입력값의 오류이므로, 또한 다시 입력기회를 줘야하므로 동일하게 처리해야할듯 3. 아예 BigDecimal의 서브클래스를 만들어 subtract()를 재정의하고 compareTo<0인 경우 예외처리를 하면 어떤가? -> 코드가 간결해지고 예외 발생의 위치가 논리적으로 옳은방향인듯 하지만 추후 마이너스통장이 추가되거나 기타 상황들에서 문제가 발생할 수 있어 좋은구조는 아닌듯함 -4. -5. +4. 입,출금 메서드는 데이터무결성이 중요한 파트임 -> 여러 은행 객체가 동시에 계좌에 접근하면 안되고, 입출금 과정중 문제가 발생한 부분이 생기면 실행 이전의 상태를 복구해놔야함. 1) 아직 쓰레드를 사용하지 않으므로 synchronized를 사용하진 않아도됨. 2) 입출금메서드가 boolean을 리턴해서 성공여부를 파악 가능하도록함. +5. 이자율 테이블을 변동가능하게 하고 싶은데, 어렴풋하게만 그려져서 일단 구현은 뒤로미룸. +6. + + +--- +생성형 AI사용 + +1. 사용쿼리 : 프로그래밍을 연습하면서 가상의 은행시스템을 만들거야. 계좌번호를 발급하는 규칙을 만들어줘. + 가상 은행 시스템을 만들 때 사용할 수 있는 일반적인 계좌번호 발급 규칙은 다음과 같습니다. 이러한 규칙은 보안과 중복을 방지하기 위해 설계됩니다. + + 1. **고유성 보장**: 모든 계좌 번호는 고유해야 합니다. 중복된 계좌 번호가 있으면 안 됩니다. + + 2. **길이와 형식 지정**: 계좌 번호의 길이와 형식을 지정합니다. 일반적으로 숫자로만 이루어진 길이가 일정한 형식을 가집니다. + + 3. **지역 식별자**: 계좌 번호의 일부는 해당 은행이나 지역을 식별할 수 있는 정보를 포함할 수 있습니다. 이는 보안을 강화하고 은행 시스템을 운영하는 데 도움이 될 수 있습니다. + + 4. **체크 디지트**: 계좌 번호의 유효성을 검사하기 위한 체크 디지트를 포함할 수 있습니다. 이를 통해 입력 오류를 방지하고 데이터 정합성을 유지할 수 있습니다. + + 5. **랜덤 발급**: 계좌 번호를 무작위로 발급하여 보안성을 높일 수 있습니다. 또한 일련 번호를 통해 계좌 번호를 쉽게 예측할 수 없도록 합니다. + + 예를 들어, 다음은 일반적인 계좌 번호 형식의 예입니다: + + - **은행 코드**: 3자리 숫자로 구성됩니다. + - **고객 번호**: 7자리 숫자로 구성됩니다. + - **체크 디지트**: 1자리 숫자로 구성됩니다. + + 이러한 경우, 계좌 번호는 총 11자리로 구성됩니다. 이 숫자는 각 은행에서 고유하게 할당됩니다. 각 은행은 자체적으로 이러한 계좌 번호를 생성하고 관리할 수 있습니다. From 01c72098339350917fe973c5294d1afeafc2ffdf Mon Sep 17 00:00:00 2001 From: starshape77 <111961655+starshape7@users.noreply.github.com> Date: Sun, 31 Mar 2024 10:53:43 +0900 Subject: [PATCH 09/56] =?UTF-8?q?starshape.md=ED=8C=8C=EC=9D=BC=20?= =?UTF-8?q?=EC=B6=94=EA=B0=80?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- week02/starshape7.md | 358 +++++++++++++++++++++++++++++++++++++++++++ 1 file changed, 358 insertions(+) create mode 100644 week02/starshape7.md diff --git a/week02/starshape7.md b/week02/starshape7.md new file mode 100644 index 0000000..9f588f0 --- /dev/null +++ b/week02/starshape7.md @@ -0,0 +1,358 @@ +# 2주차 + +--- + +**COW L2 백엔드 과정 JAVA 객체지향프로그래밍 과제** + +뱅킹 시스템 (기본계좌 & 적금 계좌 포함) + +→ 다형성을 이용하여 구현 + +구현기능 : 계좌 생성, 출금, 입금, 송금 ( BigDecimal 데이터 타입 ) + +**계좌 클래스 설계와 구현** + +1. 계좌(일반 예금 계좌)에는 일반 예금 계좌와 적금 계좌가 있습니다. 계좌 클래스의 속성은 계좌종류(N: 예금계좌, S:적금계좌), 계좌번호, 소유자, 잔액, 활성화 여부 다섯 가지 입니다. +2. 적금 계좌 클래스는 일반 예금 계좌 클래스에서 상속을 받고 목표 금액 속성이 추가 됩니다. +3. 일반 예금 계좌 클래스의 각 속성에 getter/setter를 제공하고, 계좌 정보를 보여주는 getAccountInfo() 메서드를 구현합니다. 적금 계좌 클래스는 이 메서드를 재정의 하여 목표 금액 정보도 보여주도록 합니다. +4. 뱅크 클래스에서 호출할 출금, 입금 기본 메서드를 생성합니다. + +**뱅크 클래스 설계와 구현** + +1. 계좌 클래스에서 구현한 기본 클래스를 이용하여 계좌생성, 출금, 입금, 송금 메서드를 구현합니다. 메서드 내부적으로 입력값을 받는 액션이 있습니다. +2. 적금 계좌는 적금 계좌는 잔액이 목표 금액(%s원) 이상이어야 출금 가능하도록 상속받은 출금 메서드를 조금 다르게 구현해줍니다. + +**인터페이스 설계와 구현** + +1. 일반 예금 계좌와 적금 계좌의 이자율 정책은 다릅니다. (여기서의 이자 계산은 잔액의 x%를 추가로 제공해주는 것으로 한정합니다. 현실세계의 포인트 개념과 비슷합니다.) 일반 예금 계좌인 경우 1000만원 이상은 이자율이 50%, 500만원 이상은 7%, 100만원 이상은 4%, 1만원 이상은 2%, 그 외에는 1% 이자를 제공해줍니다. 적금 계좌의 경우 100만원 이상은 이자율이 50%, 그 외에는 1% 이자를 제공해줍니다. +2. 각 할인 정책을 구현하기 위해 InterestCalculator 인터페이스에 계좌 잔액에 대한 이자금액을 반환하는 메서드(BigDecimal getInterest(balance))를 선언하고, 이를 구현한 일반 예금 계좌 이자 계산 정책과 적금 계좌에 대한 이자 계산 정책 클래스를 만듭니다. + +**계좌 관리를 위한 컬렉션 프레임 워크 사용하기** + +1. 모든 계좌를 관리하기 위한 중앙은행 클래스를 만듭니다. 계좌를 배열에 관리하기 위해 ArrayList를 활용합니다. +2. 계좌별 이자 정책을 관리하기 위해 HashMap을 활용하고, key에 category, value에 각 category의 InterestCalculator 인스턴스 를 담습니다. + +**예외 처리** + +1. 입금할 금액을 적으라고 했는데 한글로 입력할 경우 +2. 없는 계좌로 송금, 입금, 출금을 시도할 경우 +3. 계좌 생성 시 계좌 형식에 알맞지 않는 경우 -> 계좌 번호 형식 ( 00000-00-00000 ) // 정규표현식 사용 +4. 계좌 생성 시 목표 금액을 현재 금액보다 낮게 설정하는 경우 +4. + +## BigDecimal + +--- + +- java 언어에서 숫자를 정밀하게 저장하고 표현하는 방법 + - 돈과 소수점을 다루기 위해 사용 +- 단점 : 느린 속도 & 불편한 사용법 +- Double의 문제점 + - Double은 기댓값과 실제값이 다르게 저장 ( 실제 저장값은 근사치 ) + - 십진수를 이진수로 변환하여 저장할 때 근사치 저장됨. + +- 기본 용어 + - Precision : 전체 숫자의 자릿수 + - 전체 숫자 중 가장 왼쪽의 0이 아닌 수부터 끝나는 0이 닌 수로 끝나는 위치까지의 자릿수 ( 소수점 아래 포함 ) == unscale + - Scale : 전제 소수점 아래 자릿수 + - 소수점 아래 첫째자리부터 0이 아닌 수로 끝나는 끝자리까지 + - DECIMAL128 : 부호와 소수점 수용 ( 최대 34자리까지 가능 ) - 10진수 +- 기본상수 + + ```java + // 0 + BigDecimal.ZERO + + // 1 + BigDecimal.ONE + + // 10 + BigDecimal.TEN + ``` + +- **초기화** + - double 타입을 BigDecimal로 초기화 + - 문자열의 형태로 생성자에 전달하여 초기화 + - double타입 그대로 전달하면 다른 결과값 가짐 + + ```java + // double 타입을 그대로 초기화하면 기대값과 다른 값을 가진다. + // 0.01000000000000000020816681711721685132943093776702880859375 + new BigDecimal(0.01); + + // 문자열로 초기화하면 정상 인식 + // 0.01 + new BigDecimal("0.01"); + + // 위와 동일한 결과, double#toString을 이용하여 문자열로 초기화 + // 0.01 + BigDecimal.valueOf(0.01); + ``` + +- 비교연산 + - 기본 타입이 아닌 오브젝트 ( double 비교 연산자 ‘==’ 안됨 ) + + ```java + // 값의 비교를 위해 사용, 소수점 맨 끝의 0까지 완전히 값이 동일해야 true 반환 + // false + a.equals(b); + + // 값의 비교를 위해 사용, 소수점 맨 끝의 0을 무시하고 값이 동일하면 0, 적으면 -1, 많으면 1을 반환 + // 0 + a.compareTo(b); + ``` + +- 사칙연산 + + ```java + // 더하기 + a.add(b); + + // 빼기 + a.subtract(b); + + // 곱하기 + a.multiply(b); + + // 나누기 + // java.lang.ArithmeticException: Non-terminating decimal expansion; no exact representable decimal result. + a.divide(b); + + // 나누기 + //소수점 아래 3자리까지만 출력하고 그 아래 자리수는 반올 + a.divide(b, 3, RoundingMode.HALF_EVEN); + + // 나누기 후 나머지 + // 전체 자리수를 34개로 제한 + a.remainder(b, MathContext.DECIMAL128); + + // 절대값 + new BigDecimal("#").abs(); + + // 두 수 중 최소값 + a.min(b); + + // 두 수 중 최대값 + a.max(b); + ``` + +- 소수점 처리 + - RoundingMode.HALF_EVEN은 기본 반올림을 사용하는 알고리즘 사용 + - 반올림 정책을 명확히 명시하여 개발 + + ```java + // 소수점 이하를 절사한다. + // 1 + new BigDecimal("1.1234567890").setScale(0, RoundingMode.FLOOR); + + // 소수점 이하를 절사하고 1을 증가시킨다. ( 올림 ) + // 2 + new BigDecimal("1.1234567890").setScale(0, RoundingMode.CEILING); + + // 음수에서는 소수점 이하만 절사한다. ( 내림 ) + // -1 + new BigDecimal("-1.1234567890").setScale(0, RoundingMode.CEILING); + + // 소수점 자리수에서 오른쪽의 0 부분을 제거한 값을 반환한다. + // 0.9999 + new BigDecimal("0.99990").stripTrailingZeros(); + + // 소수점 자리수를 재정의한다. + // 원래 소수점 자리수보다 작은 자리수의 소수점을 설정하면 예외가 발생한다. + // java.lang.ArithmeticException: Rounding necessary + new BigDecimal("0.1234").setScale(3); + + // 반올림 정책을 명시하면 예외가 발생하지 않는다. + // 0.123 + new BigDecimal("0.1234").setScale(3, RoundingMode.HALF_EVEN); + + // 소수점을 남기지 않고 반올림한다. + // 0 + new BigDecimal("0.1234").setScale(0, RoundingMode.HALF_EVEN); + // 1 + new BigDecimal("0.9876").setScale(0, RoundingMode.HALF_EVEN); + ``` + + +## HashMap + +--- + +- Hashmap은 데이터를 저장할 때에 Key와 Value를 짝을 이루어 저장. +- Key 값으로 Hash함수를 실행한 결과를 통해 저장위치 결정 +- 데이터의 저장 위치를 해시 함수를 통해 알 수 있어 추가, 삭제, 검색이 빠르다. + +값 추가 + +```java +HashMap map = new HashMap<>();//new에서 타입 파라미터 생략가능 +map.put(1,"사과"); key : 1 // Value : 사과 +``` + +값 삭제 + +```java +map.remove(1); //key값 1 제거 +map.clear(); //모든 값 제거 +``` + +값 출력 + +```java +map.get(1) //key값 1의 value얻기 // 특정 값 반환 + +getKey(); // 현재 Hashmap의 Key값 출력 +getValue() // 현재 Hashmap의 value값 출력 + +map.entrySet() // HashMap의 전체 반환 // Key && Value +map.keySet() // HashMap의 전체 Key값 반환 // Only Key +map.values() // HashMap의 전체 Value값 반환 // Only Value +``` + +값 변환 + +```java +map.replace(1, "바나나"); // 해당 key값에 해당하는 Value값 변환 +``` + +값 존재여부 확인 + +```java +map.containsKey(1); // HashMap에 해당 key 값 존재히면 true 반환, else false 반환 +map.comtainsValue("사과"); // HashMap에 해당 Value 값 존재히면 true 반환, else false 반환 +``` + +## 정규표현식 ( Regular Expressiong) + +--- + +특정 문자열의 규칙을 가지는 문자열의 집합을 표현하는데 사용되는 언어 + +| 기호 | 설명 | 예제 | +|-----------|:------------------------------------|------------------------------------------------------------------| +| . | 임의의 문자 1개 | | +| ^ | 시작을 의미, [ ] 안에 있으면 부정의 의미 | ^a : a로 시작하는 단어, [^a] : a가 아닌 철자 문자 1개 | +| $ | $앞의 문자열로 문자가 끝나는지를 의미 | a$ : a로 끝나는 단어 | +| ? | 앞의 표현식이 없거나 or 최대 한개만 | a1? : 1이 최대 한개만 있거나 없을수도 있다. → a(o), a1(o), a11(x), a111(x) | +| * | 앞의 표현식이 없거나 or 있거나 (여러개) | a1* : 1이 있을수도 없을수도 있다. → a(o), a1(o), a11(o), a111(o) | +| + | 앞의 표현식이 1개 이상 or 여러개 | a1* : 1이 1개 이상있다. → a(x), a1(o), a11(o), a111(o) | +| [ ] | [ ] 안의 문자가 존재하는지를 의미 | [ab][cd] : a,b 중 한 문자와 c,d 중 한 문자 | +| [^] | [] 대괄호 안에 ^ 문자가 있으면, 제외를 뜻함 | [^a-z] : 알파벳 소문자 a부터 z까지를 제외한 모든 문자 | +| - | 사이의 문자 혹은 숫자를 의미한다 | [a-z] : 알파벳 소문자 a부터 z까지 하나, [a-z0-9] : 알파벳 소문자 전체,0~9 중 한 문자 | +| shift + \ | 또는 | [a |b] : a 혹은 b | +| ( ) | 그룹 | 01(0 |1) : 01뒤에 0 또는 1이 들어간다→ 010(o), 011(o), 012(x) | +| (?:) | 찾지만 그룹에 포함 안됨 | | +| (?=) | =앞 문자를 기준으로 전방 탐색 | | +| (?<=) | =뒤 문자를 기준으로 후방 탐색 | | +| { n } | 딱 n 개 존재 | a{3}b : a가 3번 온 후 b가 온다. → aab(x), aaab(o), aaaab(o) | +| { n, m} | n개 이상 m개 이하 | a{3,5} : a가 3개 이상 5개 이하 있다. → aa(x), aaa(o), aaaa(o), aaaaaaa(x) | +| { n, } | n개 이상 존재 | a{3,} : a가 3개 이상 있다. → aa(x), aaa(o), aaaa(o), aaaaaaa(o) | +| \b | 공백, 탭, ",", "/" 등을 의미한다 | apple\b : apple뒤에 공백 탭등이 있다. → apple juice (o), apple.com (x) | +| \B | \b의 부정, 공백 탭등이 아닌 문자인 경우 매치한다 | apple\B → apple.com (o) | +| \d | 0~9 사이의 숫자 // [0-9]와 동일 | | +| \D | \d의 부정숫자가 아닌 어떤 문자 // [^0-9]와 동일 | | +| \s | 공백, 탭 | | +| \S | 공백, 탭이 아닌 문자 | | +| \w | 알파벳 대소문자+숫자+"_" // [a-zA-Z_0-9]와 동일 | | +| \W | \w의 부정 // [^a-zA-Z_0-9] | | + +자주 사용하는 정규식 + +| 정규 표현식 | 설명 | +|----------------------------|--------| +| ^[0-9]*$ | 숫자 | +| ^[a-zA-Z]*$ | 영문자 | +| ^[가-힣]*$ | 한글 | +| \\w+@\\w+\\.\\w+(\\.\\w+)? | E-Mail | +| ^\d{2,3}-\d{3,4}-\d{4}$ | 전화번호 | +| \d{6} \- [1-4]\d{6} | 주민등록번호 | +| ^\d{3}-\d{2}$ | 우편번호 | + +### String 클래스의 정규식 문법 + +--- + +| String 정규식 메소드 | 설명 | +|-----------------------------------------------------|--------------------------------------------------------------| +| boolean matches(String regex) | 인자로 주어진 정규식에 매칭되는 값이 있는지 확인 | +| String replaceAll(String regex, String replacement) | 문자열내에 있는 정규식 regex와 매치되는 모든 문자열을 replacement 문자열로 바꾼 문자열을 반환 | +| String[] split(String regex) | 인자로 주어진 정규식과 매치되는 문자열을 구분자로 분할 | + +EX + +```java +// matches (일치하는지 확인) +String txt = "123456"; + +boolean result1 = txt.matches("[0-9]+"); // 숫자로 이루어져 있는지 + +System.out.println(result1); // true +``` + +```java +// replaceAll (정규표현식과 일치하는 모든 값 치환) +String txt2 = "power987*-;"; + +// 영문자와 숫자를 제외한 문자를 모두 0으로 치환 +String result2 = txt2.replaceAll("[^a-z0-9]","0"); + +System.out.println(result2); // power987000 +``` + +```java +// split (정규표현식과 일치하는 값 기준으로 나누기) +String txt3 = "power987*-;"; + +String[] txts = txt3.split("[0-9]+"); // 숫자부분을 기준으로 분할 + +System.out.println(txts[0]); // power +System.out.println(txts[1]); // *-; +``` + +### Pattern 클래스 + +--- +문자열을 정규 표현식 패턴 객체로 변환 + +| Pattern 클래스 메소드 | 설명 | +|------------------------------------------------------|--------------------------------------| +| compile(String regex) | 정규표현식의 패턴을 작성 | +| matches(String regex, CharSequence input) | 정규표현식의 패턴과 문자열이 일치하는지 체크일치할 경우 true, | +| 일치하지 않는 경우 false를 리턴(일부 문자열이 아닌 전체 문자열과 완벽히 일치 해야한다) | | +| asPredicate() | 문자열을 일치시키는 데 사용할 수있는 술어를 작성 | +| pattern() | 컴파일된 정규표현식을 String 형태로 반환 | +| split(CharSequence input) | 문자열을 주어진 인자값 CharSequence 패턴에 따라 분리 | + +```java +// 문자열 형태의 정규표현식 문법을 정규식 패턴으로 변환 +String patternString = "^[0-9]*$"; + +// Pattern 객체로 컴파일된 정규식은 뒤의 Matcher 클래스에서 사용된다 +Pattern pattern = Pattern.compile(patternString); +``` + +```java +// 샘플 문자열 +String txt1 = "123123"; +String txt2 = "123이것은숫자입니다00"; + +// 첫번째 매개값은 정규표현식이고 두번째 매개값은 검증 대상 문자열 +boolean result = Pattern.matches("^[0-9]*$", txt1); +System.out.println(result); // true +boolean result2 = Pattern.matches("^[0-9]*$", txt2); +System.out.println(result2);// false +``` + +### Matcher 클래스 + +--- +대상 문자열의 패턴을 해석하고 주어진 패턴과 일치하는지 판별하고 반환된 필터링된 결과값들을 가짐 + +| Matcher 클래스 메소드 | 설명 | +|------------------|------------------------------------------------------------| +| find(int start) | start 위치 이후부터 매칭검색, 패턴이 일치하는 경우 true를 반환, 불일치하는 경우 false반환 | +| start(int group) | 지정된 그룹이 매칭되는 시작위치 반환 | +| end(int group) | 지정된 그룹이 매칭되는 끝위치의 다음 문자위치 반환 | +| group(int group) | 그룹화되어 매칭된 패턴중 group 번째 부분 반환 | +| groupCount( ) | 괄호로 지정해서 그룹핑한 패턴의 전체 개수 반환 | +| matches( ) | 패턴이 전체 문자열과 일치할 경우 true반환 | \ No newline at end of file From 7228b7f670a3d49293302d8253d662655dd1d507 Mon Sep 17 00:00:00 2001 From: starshape77 <111961655+starshape7@users.noreply.github.com> Date: Sun, 31 Mar 2024 10:54:23 +0900 Subject: [PATCH 10/56] =?UTF-8?q?starshape77.md=ED=8C=8C=EC=9D=BC=20?= =?UTF-8?q?=EC=B6=94=EA=B0=80?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- week02/{starshape7.md => starshape77.md} | 0 1 file changed, 0 insertions(+), 0 deletions(-) rename week02/{starshape7.md => starshape77.md} (100%) diff --git a/week02/starshape7.md b/week02/starshape77.md similarity index 100% rename from week02/starshape7.md rename to week02/starshape77.md From e7e7c886ef7da492c0e9a1f66e7b858befc8c6f1 Mon Sep 17 00:00:00 2001 From: SeungGyu Date: Mon, 1 Apr 2024 09:42:00 +0900 Subject: [PATCH 11/56] =?UTF-8?q?2=EC=A3=BC=EC=B0=A8=20=ED=95=99=EC=8A=B5?= =?UTF-8?q?=20PR?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .../\355\225\234\354\212\271\352\267\234.md" | 160 ++++++++++++++++++ 1 file changed, 160 insertions(+) create mode 100644 "week02/\355\225\234\354\212\271\352\267\234.md" diff --git "a/week02/\355\225\234\354\212\271\352\267\234.md" "b/week02/\355\225\234\354\212\271\352\267\234.md" new file mode 100644 index 0000000..d81218d --- /dev/null +++ "b/week02/\355\225\234\354\212\271\352\267\234.md" @@ -0,0 +1,160 @@ +# Week2 + +작업자: 승규 한 +상태: 진행 중 +요약: Week1 +마감일: 2024년 3월 31일 + +# Practice-oop-banking + +## 구조 + +흐름 + +RunBanking → Person → BankingKiosk → BankServiceMediator → Clerk(CreateAccountClerk, DepositClerk, WithdrawClerk, RemittanceClerk, ChangeStatusClerk, GetAccountInfoClerk) → BankSystem ↔BankStorage + +Test + +패키지 +Account(계좌관련), Bank(은행관련), exception(예외), interest(이자관련), person(사람), validate(공통 검증) + +- RunBanking + + 프로그램 실행 클래스 + +- Person + + 뱅킹 서비스 이용자로 은행 업무를 볼지 안 볼지 의사결정을 한다. + +- BankingKiosk + + 은행서비스 중 어떤 서비스를 이용할지 결정한다. + +- BankServiceMediator + + 선택한 은행 서비스에 따라 적절한 은행원을 매칭 시켜준다 + +- Clerk(CreateAccountClerk, DepositClerk, WithdrawClerk, RemittanceClerk, ChangeStatusClerk, GetAccountInfoClerk) + + 은행원 클래스로 각각의 은행원 역할에 따라 서로 다른 입력을 받고 수행하며 수행 결과를 알려준다. + + +- BankSystem + + 은행 시스템으로 계좌번호 랜덤 생성, BankStorage에서 계좌 정보들을 가져오고 그에 따른 역할을 수행 등 여러 기능을 하는 은행 시스템이다. + + +- BankStorage + + 은행의 계좌 저장소로 등록된 모든 계좌들을 가지고 있는 저장소다. + +- Account(DepositAccount, SavingAccount) + + 계좌 도메인으로 입금, 출금, 송금, 상태 변경 계좌 정보 확인 로직이 있으며 계좌별 이자 정책을 가져 입금 시 이자를 계산해 준다. + + +--- + +## 과제 요구사항 변경점 + +1. 계좌 클래스의 속성 계좌 종류를 “N”, ” S”대신 “예금 계좌”, “적금 계좌로” 저장하였다 +2. 적금계좌를 예금 계좌에서 상속 받지않고 예금계좌, 적금계좌 모두 Account Interface를 상속받게 하였다. +3. 계좌 클래스에 상태 변경 메서드 추가 +4. 각 계좌 클래스마다 이자율을 알고 있다. +5. 중앙은행 클래스에서 다른 기능을 구현하지는 않았고 ArrayList가 아닌 Map으로 BankStorage에 모든 계좌가 저장될 때마다 중앙은행에도 같이 저장시켰다. (Test 클래스의 showCentralBankAccountList()메서드에서 확인) + +--- + +## 구현 기능 + +Person이 은행 업무를 처리할지 결정 후 + +- 계좌 생성 +- 입금 +- 출금 +- 송금 +- 계좌 상태 변경 +- 계좌 정보 조회 + +--- + +## 예외 처리 + +person의 행동 범위 내의 숫자 제외 예외 + +kiosk 값 입력 범위 내의 숫자 제외 예외 + +계좌 생성 : CreateAccountClerk에서 계좌 유형 입력 예외 처리 + +입금 : DepositClerk에서 계좌번호 형식, 금액 입력 형식 예외 처리 + + BankSystem에서 계좌 못 찾은 경우, 비활성화 계좌인 경우 + +출금 : WithdrawClerk에서 계좌번호 형식, 금액 입력 형식 예외 처리 + + BankSystem에서 계좌 못 찾은 경우, 비활성화 계좌인 경우 + + Account 클래스에서 예금의 경우 잔고 없으면 출금 불가 적금의 경우 잔고, 목표금액 부족하면 출금 불가 + +송금 : RemittanceClerk에서 계좌번호 형식, 금액 입력 형식 예외 처리 + + BankSystem에서 계좌 못 찾은 경우, 비활성화 계좌인 경우 + + Account 클래스에서 출금 계좌 잔고 또는 목표금액 부족 시 출금 불가 + +계좌상태 변경 : ChangeStatusClerk에서 계좌번호 형식 예외 처리 + + BankSystem에서 계좌 못 찾은 경우 + +계좌 정보 확인 : GetAccountInfoClerk에서 계좌번호 형식 + + BankSystem에서 계좌 못 찾은 경우 + +--- + +과제 작성 중 고민 내용 + +객체지향 코드를 작성하며 고민한 점들을 작성한다. + +1. 구조 + + 객체지향 Banking 코드를 작성하면서 처음부터 끝까지 구조를 많이 변경했다. 처음 설계 과정에서는 과제 요구사항에 나와있는 Class를 기반으로 MVC 구조를 통해 작성하면 될것 같다고 생각했다. 하지만 막상 내가 설계한 대로 MVC 구조를 작성하면서 내 방식의 설계가 과제의 요구사항과는 맞지 않는 것 같다는 생각이 들었다. (지금 드는 생각은 설계가 미흡했던 것 같다.) + + 그 이유는 서비스 클래스에서 담당하는 역할이 너무 많다고 느꼈고 은행, 계좌, 이자 간의 관계가 처음에 설계한 대로 짜이지 않고 의존관계가 엉켰기 때문이다. 이때 너무 MVC 구조에 얽매이지 말라는 조언을 듣고 익숙하지 않더라도 각각의 도메인을 세분화시켜 MVC 구조에 국한되지 않으며 도메인 중심 설계를 해봐야겠다는 생각이 들었다. + + 코드를 작성하는게 오랜만이기도 하고 설계 단계에서 각 도메인의 책임을 어떻게 분리할지 고민하는 데에 시간을 많이 쓰면서 이 기능은 어느 도메인에 포함되는게 적절할까? 같은 고민을 많이 했던 것 같다. ex) 처음에는 계좌번호를 한글로 작성하면 은행 시스템에서 예외를 처리하게 했는데 생각해 보니 은행 시스템보다는 은행원 차원에서 예외 메시지를 작성해 줘야 하는 게 적절하겠다는 생각을 함 + + 결과적으로 사람, 은행(키오스크, 은행원, 은행 저장소), 계좌, 이자 도메인을 중심으로 코드를 작성하게 되었다. + +2. 예외처리 + + 계좌에서 예외를 던지면 은행원(clerk) 차원에서 에러 메시지를 보여주게 작성하였다. + + 예외 처리를 하면서 고민이 있었는데 그냥 모두 하나의 예외로 처리할지 각각의 예외 상황마다 다른 예외로 처리할지 고민했다. 이 부분에 대한 결론은 exception 패키지에 각각의 예외 상황마다 클래스를 따로 만들어 주어 처리했다. 이 방법이 맞는 건지는 잘 모르겠다. + +3. 계좌의 출금가능여부 검증로직 + + 출금 가능 여부 검증 로직을 계좌 클래스에 둘 것인가 검증 클래스에 둘 것인가 고민을 했다. 계좌 클래스에 두면 계좌상태에 대한 책임이 객체 안에서 캡슐화되어 srp가 지켜진다 생각했고 접근성이 좋다는 장점이 있지만 재사용성이 떨어진다 생각했다. + + 검증 클래스에 두면 재사용성이 증가하고 검증을 계좌가 담당하지 않으니 이 또한 srp가 증가하는게 아닌가? 라는 생각을 했다 하지만 한편으론 검증 클래스에 의존성이 생기니까 안 좋은 방법인 것 같다는 생각도 했다. + + 결론적으로 나는 내가 설계한 계좌 도메인은 계좌에 관련된 기본적인 행위?를 제어하는게 주요 책임으로 생각했기 때문에 계좌에 검증 로직을 넣는게 맞다고 생각해 넣었다. + +4. 계좌의 메서드 리턴 값 + + 계좌 클래스의 메서드들을 boolean 으로하고 시스템에서 메시지를 은행원에게 넘겨주는게 String을 반환하는 것보다 좋지 않을까 생각했는데 3항연산자를 사용할 경우는 예외를 던지지도 못하고 그러므로 시스템 클래스에 if else 문이 많아져 가독성이 떨어질 것 같아 String을 반환하는게 낫겠다고 생각했다(.(이런 경우에는 어떤 것에 더 중점을 두어 구현해야 하는건지 잘 모르겠다.) + + +1. 코드 작성 + + 코드를 작성하면서 내가 적절한 상황에 적절한 것을 작성하고 있는 건지 의문이 들었다. 이러한 의문은 주로 if나 switch, Map을 사용하면서 들었던 것 같다. 최대한 코드를 간결하고 명확하게 작성하고 싶었고 그런 방향으로 작성하려고 노력했지만 분명 그렇지 않은 부분이 존재할 것이라고 생각한다. + + 의존관계나 각각의 클래스가 단일 책임 원칙을 잘 준수하고 있는가에 대한 의문도 존재했다. + + --- + + ## 느낀 점 + + 구조를 엎고 설계하는 과정이 반복되면서 시간적 여유는 점점 줄어들었다. + + 이번 과제를 통해 오랜만에 코드를 직접 작성하는 시간을 가졌는데 이 코드를 작성하면서 내가 몰랐거나 까먹었던 것을 찾아보고 공부하면서 알게 되었던 것이 많아서 좋았다. \ No newline at end of file From 259536afc3f899613b0077099341e8c63ac3e9f5 Mon Sep 17 00:00:00 2001 From: jinhyeon Date: Mon, 1 Apr 2024 19:55:20 +0900 Subject: [PATCH 12/56] =?UTF-8?q?docs:2=EC=A3=BC=EC=B0=A8=20=EA=B3=BC?= =?UTF-8?q?=EC=A0=9C=20=EC=A0=9C=EC=B6=9C?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .../\353\260\225\354\247\204\355\230\204.md" | 86 +++++++++++++++++++ 1 file changed, 86 insertions(+) create mode 100644 "week02/\353\260\225\354\247\204\355\230\204.md" diff --git "a/week02/\353\260\225\354\247\204\355\230\204.md" "b/week02/\353\260\225\354\247\204\355\230\204.md" new file mode 100644 index 0000000..a93e57c --- /dev/null +++ "b/week02/\353\260\225\354\247\204\355\230\204.md" @@ -0,0 +1,86 @@ + +pr링크: https://github.com/COW-edu/practice-oop-banking/pull/8 + +## 미션 구현과정 + +객체지향적으로 이번 미션 코드를 구현하기 위해 많은 고민을 한거 같습니다. 우선 기능 요구 사항을 이해하고 어떠한 요구기능이 있을지 고민하고 목록을 만들고 그것을 보며 과제를 만들어 나갔습니다. + +## 코드 구조 설명 + +- view(패키지) + + 사용자의 입력을 받거나 필요한 정보를 출력해주는 기능 + + InputView와 OutputView로 분리 + + +- controller(패키지) + + view와 service를 연결해준다. + +- Bank(패키지) + + 사용자의 계좌 정보를 저장하고 입금, 출금, 송금등을 하는 패키지 + +- interest(패키지) + + 이자율을 계산해 예상 이자율을 합친 금액을 반환 + + +## MVC구조 + +사용자 로직과 비즈니스 로직을 분리하기위해 기본적으로 mvc구조를 사용하려고 노력 하였습니다. + +Controller 를 통해서 view를 상황에 맞데 호출하여 사용자에게 값을 받아 서비스쪽으로 보내주는 역할을 하도록 만들었습니다. + +구현 중에 고민 사항은 mvc구조로 하면서 cotroller의 메서드에서 특정 사항에 맞게 값을 변경해서 넣어주는 메서드들이 있는데 이런식으로 구현하면 단일 책임 원칙을 어기는게 아닌가에 대한 고민을 하였습니다. + +## 객체 지향코드를 짜기위한 노력 + +1. **역할과 구현을 최대한 분리하려고 노력** + - 서비스와 실제 값이 저장되는 레파지토리를 분리하였습니다. +2. **인터페이스와 구현객체를 분리** + + 실제 구현 객체들이 인터페이스를 의존 하도록 만들었습니다. + +3. **AppConfig** + + 애플리케션의 동작을 구성하기 위한 구현 객체를 Appconfig가 생성하여 연결해줌으로 객체 인스턴스의 참조(레퍼런스)를 **“생성자를 통해서 주입(연결)”**해줍니다. + + - DIP: ‘MemberServiceImpl’은 ‘MemberRepostory’인 추상에만 의존, 구체클래스는 몰라야함 + - OCP: 수정에는 닫혀있고 확장에는 열려있도록 설계 + - 관심사의 분리: 객체를 생성하고 연결하는 역할과 실행하는 역할이 분리 +4. **단일 책임 원칙** + + 클래스가 하나의 기능을 하도록 만들려고 노력했습니다. + + 최대한 메서드가 15줄을 넘어가지 않도록하여 너무많은 역할을 가지지 않도록 했습니다. + + +## 그 밖의 노력들 + +1. View 를 인풋과 아웃풋으로 분리 +2. 메세지 상수 처리 +3. 연관된 상수는 enum처리 +4. 단위 테스트 작성 +5. stream을 사용하여 코드 간결하게 만들기 +6. 최대한 다중 중첩문 지양하기 +7. else, elseif 사용하지 않기 + +## 진행하면서 가장 크게 배운점 + +처음에는 일반계좌와 적금계좌 둘다 따로 다른 인터페이스를 받도록 했으나 이후 리팩토링 과정을 거쳐 다운캐스팅을 통해 상황에 맞게 사용하였다. + +## 아쉬운 점, 보완할 점 + +처음부터 너무 구조에 신경쓰다 보니 코드를 많이 작성했다고 지우고 리팩토링하고 하는 과정을 하는데 시간을 너무 많이 쓴것 같습니다. + +일단 기능에 집중을 했어야 하는데 그 부분을 잘 신경 못 쓴 것 같습니다. 가장 크게는 제대로 예외처리를 잘 하지못했다는 점과 계좌 비활성화기능을 제대로 구현하지 못했다는 점입니다. + +또한 테스트 코드를 기능별로 한기능을 만들때마다 만들었어야 하는데 단위테스트가 부족하다는 생각이 들었습니다. + +그것 말고도 구조상 컨트롤에서 너무 많은 책임을 가지고 있는 것 때문 mvc구조를 다시 한번 생각해 보는 계기가 되었고 이곳저곳에 고쳐야 할 코드들이 눈에 보이지만 시간상 체크만 해놓는 경우도 많았습니다. + +## 느낀점 + +하지만 이번에 이런 방식으로 코드를 짜면서 막히는 부분도 많았지만 하나하나 해결할때 마다 배워가는 내용이 많았고 여러가지를 시도해보며 전체 코드 구조들에 대해 고민하는 시간이 되었던것 같습니다. 다음 시간에는 피드백들과 제가 생각한 부족한점들을 추가하여 더 좋은 코드로 리팩토링하고싶습니다. \ No newline at end of file From 41f92e254d0ad573b9e38331c672ddd56c39b0e4 Mon Sep 17 00:00:00 2001 From: jaehyuk Date: Mon, 1 Apr 2024 21:36:31 +0900 Subject: [PATCH 13/56] =?UTF-8?q?:memo:=20WEEK2=20=ED=95=99=EC=8A=B5?= =?UTF-8?q?=EB=82=B4=EC=9A=A9=20=EC=9E=91=EC=84=B1?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- week02/BaekJaehyuk.md | 99 +++++++++++++++++++++++++++++++++++++++++++ 1 file changed, 99 insertions(+) create mode 100644 week02/BaekJaehyuk.md diff --git a/week02/BaekJaehyuk.md b/week02/BaekJaehyuk.md new file mode 100644 index 0000000..9f26542 --- /dev/null +++ b/week02/BaekJaehyuk.md @@ -0,0 +1,99 @@ +# 1. 구조 + +## 1.1 MVC 패턴 + +- `View` +- `Controller` +- `Service` +- `Repository` +- `Domain` + +이 외 `Exception`, `DTO`, `계좌별 이자 정책` 등 각각의 역할을 분리하여 기능을 구현하도록 설계. + +## 1.2 싱글톤 패턴 + +다음과 같이 의존관계를 생성 + +```java + private static final Service bankservice = new BankService(); + private Repository centralBankRepo = CentralBank.getInstance(); +``` +## 1.3 메시지 코드 + +메시지를 관리하는 클래스를 생성하여 유지보수 및 코드변경에 유리하도록 설계 + +```java + public static final String CHOICE = "아래 기능 중 하나를 선택하세요."; + public static final String MENU= "(1) : 계좌 생성 (2) : 입금 (3) : 출금 (4) : 송금 (5) 계좌조회 (6) 프로그램 종료" ; + public static final String ACCOUNT_TYPE= "(1) : 예금 계좌 , (2) : 적금 계좌"; + public static final String ACCOUNT_NUMBER = "계좌번호를 입력하세요. (8자리 입력)"; + public static final String ACCOUNT_OWNER = "이름을 입력하세요."; + public static final String BALANCE = "금액을 입력하세요."; +``` + +## 1.4 예외처리 + +`Checked Exception`이 아닌 `Unchecked Exception`을 사용한 예외처리 구현 + +--- + +# 2. 클래스 + + +View - `BankView` +: + +1. `AccountDTO` 을 통해 각각의 도메인에 값을 할당 +2. `DecimalFormat` 을 통해 계좌번호의 패턴을 설정. +3. 입력값을 받아 해당하는 기능을 실행시키도록 구현. + + +--- + +Repository (Interface) - `CentralBank(Impl)` +: +1. `ArrayList`를 사용하지 않고, 계좌를 배열에 관리하기 위한`HashMap` 활용하여 계좌를 관리 + +--- + +InterestCalculator (Interface) : `NormalInterestCalculator(Impl)`, `SavingInterestCalculator(Impl)` +: + +1. SavingInterestCalculator +: 삼항연산자를 사용하여 잔액에 따른 이자율 책정 + +2. NormalInterestCalculator +: 숫자 범위에 따른 값 할당을 할 경우 사용하면 좋은 `NavigableMap`을 사용하여 +금액에 따른 이자율 책정 로직을 구현 + (`floor.Entry()` 사용하여 범위 값 할당) + + +--- + +BasicAccount, SavingAccount +: + +1. 요구사항에 맞춰 적금 계좌 클래스(`SavingAccount`)는 예금 계좌 클래스(`BasicAccount`)에서 상속을 받는다. + +--- + +# 3. 기능 + +* 입금 +* 출금 (적금계좌일 경우,목표금액을 달성했을 경우에 출금 가능) +* 송금 +* 계좌 조회 + + +--- + +# 4. 고민 + +이번 `Banking Service` 구현을 MVC 패턴을 지키면서 구현하면서 MVC 패턴을 지키는 것이 좋을까라는 의문이 생겼다. 관련해서 서치를 해보니 서비스 규모에 따라 MVC 패턴을 적용할 것인지 아닌지 중요하다는 점을 알게 되었다. 이번 4월 1일까지 구현한 코드가 지저분하고 +관심사에 따른 역할이 완벽하게 구현이 되지 않아 크게 아쉬움을 가지고 있다. 해당 코드를 리팩토링을 통해 SOLID 원칙을 최대한 위반하지 않은 코드로 수정하고 싶다. 또한, 기능 요구사항 외의 예외처리를 다양하게 하고 싶다 + +또한, `View`에서 `switch-case` 문을 통해 기능을 선택하도록 구현하였다. HashMap을 사용하여 원하는 기능을 선택할까도 하였지만, 이 역시 관련하여 구글링을 하니 고정된 값일 경우 switch-case가 더 좋다고 알게 되었다. +추후에 `View` 관련 코드도 같이 수정할 예정이다. + +기능 요구사항을 구현하면서 해당 기능을 단위로 테스트를 진행하고자 했지만, 조금 급하게 짜는 경향이 있어 `TDD 방식`의 기반의 개발을 하지 못한 점이 아쉽게 생각한다. + + From 84b1018fe7e3d01857d02f52304644b758924234 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?=EC=9D=B4=EC=8A=B9=EC=A3=BC?= <129913026+Juuuu-power-e@users.noreply.github.com> Date: Mon, 1 Apr 2024 22:34:16 +0900 Subject: [PATCH 14/56] Update Juuuu-power-e.md --- week02/Juuuu-power-e.md | 35 ++++++++++++++++++++++++++++++++++- 1 file changed, 34 insertions(+), 1 deletion(-) diff --git a/week02/Juuuu-power-e.md b/week02/Juuuu-power-e.md index b17de0f..88cd84b 100644 --- a/week02/Juuuu-power-e.md +++ b/week02/Juuuu-power-e.md @@ -6,7 +6,7 @@ -> 코드가 간결해지고 예외 발생의 위치가 논리적으로 옳은방향인듯 하지만 추후 마이너스통장이 추가되거나 기타 상황들에서 문제가 발생할 수 있어 좋은구조는 아닌듯함 4. 입,출금 메서드는 데이터무결성이 중요한 파트임 -> 여러 은행 객체가 동시에 계좌에 접근하면 안되고, 입출금 과정중 문제가 발생한 부분이 생기면 실행 이전의 상태를 복구해놔야함. 1) 아직 쓰레드를 사용하지 않으므로 synchronized를 사용하진 않아도됨. 2) 입출금메서드가 boolean을 리턴해서 성공여부를 파악 가능하도록함. 5. 이자율 테이블을 변동가능하게 하고 싶은데, 어렴풋하게만 그려져서 일단 구현은 뒤로미룸. -6. +6. AccountNum을 객체로 만드는게 좋을거같음. => Branch ∵ 1) 앞의자리 0이 생략되지 않아야하고, 2) 각 부분이 의미를 가짐 3) 옳은지 검증하는 checkDigit (verifyNum)이 존재 --- @@ -32,3 +32,36 @@ - **체크 디지트**: 1자리 숫자로 구성됩니다. 이러한 경우, 계좌 번호는 총 11자리로 구성됩니다. 이 숫자는 각 은행에서 고유하게 할당됩니다. 각 은행은 자체적으로 이러한 계좌 번호를 생성하고 관리할 수 있습니다. + +2. 사용쿼리 : 계좌번호에 올바른 검증숫자(11번째 수)를 만들어주는 메소드 + private String createVerifyNum(String accountNum) { + + } + 를 완성해줘 + private String createVerifyNum(String accountNum) { + int[] weights = {2, 3, 4, 5, 6, 7, 8, 9, 2, 3, 4}; // 각 숫자에 곱해질 가중치 + + int sum = 0; + for (int i = 0; i < accountNum.length(); i++) { + char digit = accountNum.charAt(i); + if (Character.isDigit(digit)) { + int num = Character.getNumericValue(digit); + sum += num * weights[i]; + } else { + // 숫자가 아닌 경우 처리 + // 여기서는 예외처리 없이 그냥 패스하도록 함 + } + } + + int remainder = sum % 11; + int verifyNum; + if (remainder == 0) + verifyNum = 0; + else if (remainder == 10) + verifyNum = 'X'; + else + verifyNum = 11 - remainder; + + return String.valueOf(verifyNum); +} + From a728d05bd462605f5d349024f94135979c96f533 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?=EC=9D=B4=EC=8A=B9=EC=A3=BC?= <129913026+Juuuu-power-e@users.noreply.github.com> Date: Mon, 1 Apr 2024 22:35:56 +0900 Subject: [PATCH 15/56] Update Juuuu-power-e.md --- week02/Juuuu-power-e.md | 10 +++++----- 1 file changed, 5 insertions(+), 5 deletions(-) diff --git a/week02/Juuuu-power-e.md b/week02/Juuuu-power-e.md index 88cd84b..b5f4320 100644 --- a/week02/Juuuu-power-e.md +++ b/week02/Juuuu-power-e.md @@ -34,10 +34,9 @@ 이러한 경우, 계좌 번호는 총 11자리로 구성됩니다. 이 숫자는 각 은행에서 고유하게 할당됩니다. 각 은행은 자체적으로 이러한 계좌 번호를 생성하고 관리할 수 있습니다. 2. 사용쿼리 : 계좌번호에 올바른 검증숫자(11번째 수)를 만들어주는 메소드 - private String createVerifyNum(String accountNum) { - - } - 를 완성해줘 + String createVerifyNum(String accountNum)를 완성해줘 + + ``` private String createVerifyNum(String accountNum) { int[] weights = {2, 3, 4, 5, 6, 7, 8, 9, 2, 3, 4}; // 각 숫자에 곱해질 가중치 @@ -63,5 +62,6 @@ verifyNum = 11 - remainder; return String.valueOf(verifyNum); -} + } +``` From 2383e94540a94f951c87606863a747e4a999e0c0 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?=EC=9D=B4=EC=8A=B9=EC=A3=BC?= <129913026+Juuuu-power-e@users.noreply.github.com> Date: Mon, 1 Apr 2024 22:37:55 +0900 Subject: [PATCH 16/56] Update Juuuu-power-e.md --- week02/Juuuu-power-e.md | 9 +++++---- 1 file changed, 5 insertions(+), 4 deletions(-) diff --git a/week02/Juuuu-power-e.md b/week02/Juuuu-power-e.md index b5f4320..8cf6d01 100644 --- a/week02/Juuuu-power-e.md +++ b/week02/Juuuu-power-e.md @@ -2,11 +2,12 @@ 조건문으로 처리할 경우 가독성이 증가하고 빠름 / 예외발생은 구조적 통일성? 2. 생각해보니 1)의 내용을 판단하는 주체는 계좌가 아닌 은행이어야함. -> 이 경우를 생각해보니 예외처리가 맞는것 같음. ∵ 입금액을 한글로 입력한 것과 같이 입력값의 오류이므로, 또한 다시 입력기회를 줘야하므로 동일하게 처리해야할듯 -3. 아예 BigDecimal의 서브클래스를 만들어 subtract()를 재정의하고 compareTo<0인 경우 예외처리를 하면 어떤가? + -> 더 생각해보니 예외사항이 맞나..? 충분히 예상가능한값이므로 정규표현식으로 유효성검증을 해야하지않을까? +4. 아예 BigDecimal의 서브클래스를 만들어 subtract()를 재정의하고 compareTo<0인 경우 예외처리를 하면 어떤가? -> 코드가 간결해지고 예외 발생의 위치가 논리적으로 옳은방향인듯 하지만 추후 마이너스통장이 추가되거나 기타 상황들에서 문제가 발생할 수 있어 좋은구조는 아닌듯함 -4. 입,출금 메서드는 데이터무결성이 중요한 파트임 -> 여러 은행 객체가 동시에 계좌에 접근하면 안되고, 입출금 과정중 문제가 발생한 부분이 생기면 실행 이전의 상태를 복구해놔야함. 1) 아직 쓰레드를 사용하지 않으므로 synchronized를 사용하진 않아도됨. 2) 입출금메서드가 boolean을 리턴해서 성공여부를 파악 가능하도록함. -5. 이자율 테이블을 변동가능하게 하고 싶은데, 어렴풋하게만 그려져서 일단 구현은 뒤로미룸. -6. AccountNum을 객체로 만드는게 좋을거같음. => Branch ∵ 1) 앞의자리 0이 생략되지 않아야하고, 2) 각 부분이 의미를 가짐 3) 옳은지 검증하는 checkDigit (verifyNum)이 존재 +5. 입,출금 메서드는 데이터무결성이 중요한 파트임 -> 여러 은행 객체가 동시에 계좌에 접근하면 안되고, 입출금 과정중 문제가 발생한 부분이 생기면 실행 이전의 상태를 복구해놔야함. 1) 아직 쓰레드를 사용하지 않으므로 synchronized를 사용하진 않아도됨. 2) 입출금메서드가 boolean을 리턴해서 성공여부를 파악 가능하도록함. +6. 이자율 테이블을 변동가능하게 하고 싶은데, 어렴풋하게만 그려져서 일단 구현은 뒤로미룸. +7. AccountNum을 객체로 만드는게 좋을거같음. => Branch ∵ 1) 앞의자리 0이 생략되지 않아야하고, 2) 각 부분이 의미를 가짐 3) 옳은지 검증하는 checkDigit (verifyNum)이 존재 --- From 336eb180cdd725f8197733453d51c0aae115c1af Mon Sep 17 00:00:00 2001 From: 0711kc <81899652+0711kc@users.noreply.github.com> Date: Mon, 1 Apr 2024 23:24:49 +0900 Subject: [PATCH 17/56] Create 0711kc.md --- week02/0711kc.md | 89 ++++++++++++++++++++++++++++++++++++++++++++++++ 1 file changed, 89 insertions(+) create mode 100644 week02/0711kc.md diff --git a/week02/0711kc.md b/week02/0711kc.md new file mode 100644 index 0000000..7d11aa2 --- /dev/null +++ b/week02/0711kc.md @@ -0,0 +1,89 @@ +# Week02 + +### 1. 가장 먼저 요구사항을 보며 만들만한 클래스들을 먼저 정리하였다. + +### Account +Account는 인터페이스를 쓸 지 추상클래스를 쓸 지 고민을 하였다. 일단 인터페이스를 사용하기로 정하고 시작했다. +- 일반 계좌 : NormalAccount +- 적금 계좌 : SavingAccount -> Attributes + TargetAmount +> Attributes : Category(Enum), AccountNumber, AccountOwner, AccountBalance, AccountActivationStatus +> +> getAccountInfo() //적금 계좌는 Override해서 목표 금액 정보도 함께 +> +> withdrawal(BigDecimal value) //적금 계좌는 잔액이 목표 금액 이상이어야 출금 가능하도록 출금메서드 구현 +> +> deposit(BigDecimal value) + +### Banking +- 계좌 인터페이스의 계좌생성, 출금, 입금, 송금 메서드를 이용 +- 내부에 입력값 받기 가능 + +### CentralBank +- ArrayList +- HashMap - 계좌 종류 별 이자 정책 + +### InterestCalculator 인터페이스 +- BigDecimal getInterest(balance); + +> 클래스 종류 : Bank, CentralBank, Account, NormalAccount, SavingAccount, NormalInterestCalculator, SavingInterestCalculator +> 인터페이스 : InterestCalculator +> Enum : AccountType + +이렇게 미리 클래스를 생각해두고 할 수 있으니 확실히 요구사항을 처음에 미리 잘 정리하고 시작하는 것이 중요하단 것을 느꼈다. + +--- +### 2. 예외처리 +1. 입금할 금액을 적으라고 했는데 한글로 입력할 경우는 scanner의 nextInt와 NumberFormatException을 활용해서 처리했다. +```java +private int getInputInt(String printMsg) { + System.out.println(printMsg); + boolean validData = false; + int inputInt = 0; + do { + try { + String input = scanner.next(); + inputInt = Integer.parseInt(input); + if(inputInt < 0) System.out.println("0보다 큰 숫자를 입력해주세요."); + else validData = true; + } catch (NumberFormatException e) { + System.out.println("숫자를 입력해주세요."); + } + } while(!validData); + return inputInt; +} +``` + +2. 없는 계좌로 송금, 입금, 출금을 시도할 경우는 따로 Exception을 만들지 않고 메소드를 이용해서 boolean값을 반환하게 만들었다. +```java +public boolean checkAccountNumber(String accountNumber) { + for(Account account : accountList) { + if(account.checkNumber(accountNumber)) + return true; + } + return false; + } +``` +> Stream의 filter를 이용할까 생각해봤지만, 그렇게 되면 항상 n개의 ArrayList를 모두 돌아봐야되고, 결과는 항상 최대 1개의 Account만 나오는데도 불구하고 List로 만들어야 되는 것이 불편해서 for문과 if문을 사용하였다. + +3. 계좌 생성 시 계좌 형식에 맞지 않는 경우 +사용자로부터 입력받는 것은 어떤 종류의 계좌인지와 사용자의 이름뿐이다. + +이름은 숫자가 아닌 문자라면 어떠한 값이 들어와도 문제가 되지 않을 것 같아서 matches()를 이용해서 처리했고, 계좌의 종류는 입금 금액을 입력받을 때 사용했던 getInputInt를 재사용해서 숫자만 입력받게 만들었다. + +4. 계정이 비활성화되어 있는 경우 +이는 CentralBank에서 계정 삭제랑 계정 활성화를 제외한 요청을 받았을 때, 활성화 상태를 확인하고 비활성화상태라면 DeactivatedAccountException을 발생시키게 만들었다. + +이를 확인한 BankingApplication에서는 해당 계정이 비활성화된 계정이라고 전달해준다. + +### 3. 새로 알게된 것 + +1. BigDecimal +BigDecimal, BigInteger라는 클래스에 대해 처음 알게 되었습니다. + +지금까지는 double, int가 모두 정상적으로 계산이 이루어진다고 생각했었는데 약간씩의 오차가 있었다는 것을 알게 되었고, BigDecimal 사용법도 그렇게 어렵지 않고 은근 편했던 것 같습니다. + +2. StringBuilder +지금은 append 밖에 사용해보지 못했지만, StringBuilder로 String을 다양하게 수정할 수 있고, + 연산보다 append가 더 성능이 좋단 것을 알 수 있게 되었습니다. + +3. 깃허브.. +지금까지는 깃허브에 그냥 코드를 올려두고 저장하는 용도로만 사용했었는데, 사용하지 않았던 다양한 방법으로 깃허브를 활용해볼 수 있었던 것 같습니다. From 0da9a91785a88ee1e7fdf32d695a7800b2d6e6aa Mon Sep 17 00:00:00 2001 From: 0711kc <81899652+0711kc@users.noreply.github.com> Date: Mon, 1 Apr 2024 23:25:44 +0900 Subject: [PATCH 18/56] Update 0711kc.md --- week02/0711kc.md | 2 ++ 1 file changed, 2 insertions(+) diff --git a/week02/0711kc.md b/week02/0711kc.md index 7d11aa2..7fe1e1e 100644 --- a/week02/0711kc.md +++ b/week02/0711kc.md @@ -1,5 +1,7 @@ # Week02 +PR 링크 : https://github.com/COW-edu/practice-oop-banking/pull/13 + ### 1. 가장 먼저 요구사항을 보며 만들만한 클래스들을 먼저 정리하였다. ### Account From 2ae3d5b4665a9122246706cd80db9db2e66ee3d1 Mon Sep 17 00:00:00 2001 From: 0711kc <81899652+0711kc@users.noreply.github.com> Date: Mon, 8 Apr 2024 19:45:57 +0900 Subject: [PATCH 19/56] docs : Add 0711kc.md --- week03/0711kc.md | 1 + 1 file changed, 1 insertion(+) create mode 100644 week03/0711kc.md diff --git a/week03/0711kc.md b/week03/0711kc.md new file mode 100644 index 0000000..8b13789 --- /dev/null +++ b/week03/0711kc.md @@ -0,0 +1 @@ + From 7fff273a2b7562fbbad992cccedb06a56e1b3720 Mon Sep 17 00:00:00 2001 From: 0711kc <81899652+0711kc@users.noreply.github.com> Date: Mon, 8 Apr 2024 22:32:05 +0900 Subject: [PATCH 20/56] docs : Update 0711kc.md --- week03/0711kc.md | 106 +++++++++++++++++++++++++++++++++++++++++++++++ 1 file changed, 106 insertions(+) diff --git a/week03/0711kc.md b/week03/0711kc.md index 8b13789..428989a 100644 --- a/week03/0711kc.md +++ b/week03/0711kc.md @@ -1 +1,107 @@ +# Week03 +## 목차 +### 1. 기존의 코드 +### 2. 변경된 것 +### 3. 고민했던 점 +### 4. 앞으로 해야될 것 + +--- + +## 1. 기존의 코드 + +기존의 코드에서는 다음과 같은 문제점이 있었다. +> - 컨벤션이 제대로 지켜지지 않았다. +> - 객체 분리가 제대로 분리되지 않았다. + +#### 컨벤션 + +[코드 컨벤션](https://naver.github.io/hackday-conventions-java/#1-line-package-import) +: 코드를 읽고 이해하기 편할 수 있도록 가독성을 높히는 코드 작성 규칙 + +[커밋 컨벤션](https://github.com/gyoogle/tech-interview-for-developer/blob/master/ETC/Git%20Commit%20Message%20Convention.md) +: 해당 커밋에서 무슨 변화가 있었는지 알아보기 쉽게 만드는 커밋 작성 규칙 + +#### 객체 분리 + +- BankingApplication + +> BankingApplication은 프로그램을 시작하고, CentralBank 객체를 만들었다. 그리고 Client의 요구에 맞춰 입출력을 담당하며 CentralBank에게 요청하였다. + +- CentralBank + +> CentralBank 안에서 Account 목록과 Interest 정보를 다 담아두고, 요청이 들어오면 데이터를 꺼내고, 가공하고, 클라이언트에게 돌려보내기까지 모든 과정을 혼자 처리한다. + +모든 클래스(객체)는 각각의 역할에 맞게 나눠져있어야 코드를 재사용하기 좋고 확장과 수정이 쉬워진다. 그렇지 않으면 코드의 변화가 다른 코드에게 영향을 줘서 추가적인 수정이 필요할 수도 있다. 따라서 확장성, 유연성에 좋지 않다. + +## 2. 변경된 것 + +1. 컨벤션을 따르도록 코드를 수정하였다. + +2. 구조를 다시 설계하여 각각의 역할을 나눠주었다. + +- Applicaiton + - 프로그램의 실행을 담당하며, AppConfig을 통해 의존성을 주입한 BankingManager를 받아서 실행한다. + +- BankingManager + - 메뉴 목록인 EMenu와 BankingFunction을 매핑시킨 HashMap을 만들고 관리한다. + +- BankingFunction + - 각각의 메뉴에 필요한 입출력을 하고 Controller에게 결과를 요청한다. + +- BankingController + - 클라이언트로부터 들어온 파라메터를 Account 객체로 만들어서 필요한 비즈니스 로직을 거치며 Service에게 전달하고 결과를 돌려준다. + +- AccountService / InterestService + - Account 객체를 Repository로부터 받아오거나 Account에 변경을 가하고 Repository에게 전달하여 결과를 저장한다. + +- AccountRepository / InterestRepository + - Account 또는 HashMap을 저장하고 있다. 데이터를 찾아오거나 저장, 삭제만한다. + +## 3. 고민했던 점 + +1. View와 Controller의 책임 + +> 어디까지가 View의 책임이고, 어디까지가 Controller의 책임인지가 고민되었다. +> +> 계좌를 생성할 때 필요한 정보를 입력받아야 되는데, 만약 적금 계좌라면 목표 금액이라는 예금 계좌와 다르게 추가적인 입출력이 필요하므로 View를 사용해야 한다. +> +> Account Type이 SAVING_ACOUNT인지 확인하는 부분은 비즈니스 로직같아서 Controller에 있어야 될 것 같다는 느낌이 들었다. +> +> 하지만 Controller에서 해야되는 것이라면, 어떻게 Controller에서 View에게 추가적인 입출력을 요구해야되는지 생각이 나지 않았다. +> +> 일단은 InputView와 OutputView를 가지고 있는 BankingFunction이라는 클래스를 만들어서 그 안에서 AccountType에 맞는 데이터를 입출력하고 Controller에게 요청을 하게 만들었다. +> +2. Controller의 기능 별 분리 +> +> 현재는 BankingController가 모든 Banking 기능을 수행해주도록 만들었다. +> +> 왜냐하면 FrontController에서 BankingFunction에 Controller를 넣어주는데, FrontController는 각 BankingFunction마다 필요한 Controller가 무엇인지 알 수 없다. +> +> 그래서 각 기능마다 Controller를 만들어줘도 어떻게 주입해줘야될 지 잘 모르겠어서 일단은 BankingController로 모두 해결할 수 있게 만들었다. +> +3. Input의 중간에서 Exception 처리 +> +> 각 메서드를 실행하면서 문제가 발생하면 각 상황에 맞는 Exception을 던지게 만들었다. +> +> 그런데 송금을 할 때, 출금 계좌, 입금 계좌, 송금 금액을 입력받는다. 지금은 모든 파라미터를 입력받고 Controller에게 요청을 한 다음에 받은 결과 또는 Exception을 처리한다. +> +> 원래는 계좌 번호를 입력받을 때마다 Controller에게 요청해서 존재하는 계좌인지 확인하는 방법을 생각했었다. +> +> 하지만 하나의 기능을 수행하면서 Controller를 여러번 호출하는 것이 좋은 방법이 아닐 것 같았다. + +4. 싱글톤 패턴 +> +> 만들다보니 싱글톤 패턴을 자주 사용하게 되었는데, 이것이 용도에 맞게 올바르게 쓰여지고 있는 것인지 헷갈릴 때가 많았다. +> +> 일단은 View, Repository처럼 외부와 직접 연결하는 곳과 데이터에 접근할 수 있는 Service만 싱글톤 패턴을 적용해두었다. +> +> 굳이 싱글톤 패턴으로 하지 않아도 되는 부분에 적용했다던가, 싱글톤 패턴으로 적용해야 되는 부분을 적용하지 않은 부분이 있을 지 고민하였다. + +## 4. 앞으로 해야될 것 + +1. BankFunction에 기능 별로 분리한 Controller를 주입할 수 있는 방법 찾기 + +2. BankingFunction에서 비즈니스 로직을 넣어놔서 InputView와 OutputView로 받아내지 않고, Controller에 의해 각 기능에 필요한 요소를 동적으로 받아내는 방법 찾기 + +3. 객체의 역할, 책임 생각해보며 클래스 다시 합치거나 분리하기 From d1152c9daee41c2d359c0ed7796bf34e81dc511f Mon Sep 17 00:00:00 2001 From: 0711kc <81899652+0711kc@users.noreply.github.com> Date: Mon, 15 Apr 2024 19:57:05 +0900 Subject: [PATCH 21/56] docs : Add 0711kc.md --- week04/0711kc.md | 1 + 1 file changed, 1 insertion(+) create mode 100644 week04/0711kc.md diff --git a/week04/0711kc.md b/week04/0711kc.md new file mode 100644 index 0000000..8b13789 --- /dev/null +++ b/week04/0711kc.md @@ -0,0 +1 @@ + From 0eba874a1f141587d3a60fa643a29aafc8d98293 Mon Sep 17 00:00:00 2001 From: 0711kc <81899652+0711kc@users.noreply.github.com> Date: Mon, 15 Apr 2024 21:56:45 +0900 Subject: [PATCH 22/56] docs : Update 0711kc.md --- week04/0711kc.md | 86 ++++++++++++++++++++++++++++++++++++++++++++++++ 1 file changed, 86 insertions(+) diff --git a/week04/0711kc.md b/week04/0711kc.md index 8b13789..cfd6a5c 100644 --- a/week04/0711kc.md +++ b/week04/0711kc.md @@ -1 +1,87 @@ +# Week04 +## 목차 +### 1. 변경된 것 +### 2. 고민했던 점 + +--- + +## 1. 변경된 것 + +#### View - Controller 부분 재설계 + +기존에는 FrontController와 BankingController 사이에 BankingFunction 클래스가 존재했었다. + +BankingFunction에서는 입출력을 할 수 있는 InputView와 OutputView를 주입받는다. + +이를 이용하여 BankingController에게 필요한 데이터를 입력받아 전달하거나 전달받은 데이터를 출력한다. + +이렇게 만든 이유는 BankingManager에서는 프로세스를 유지하면서 메뉴 선택만 하도록 만들고 싶었기 때문이다. + +그래서 뱅킹 매니저에서는 메뉴 출력과 입력을 받아서 선택된 메뉴 데이터를 FrontController에게 전달해주고, 이에 맞는 Banking 기능을 수행하도록 만들고 싶었다. + +그런데 기능을 실행시키기 위해서는 계좌번호와 같은 추가적인 정보가 필요했고, 이를 해결하기 위해 BankingFunction 클래스를 만들었다. + +FrontController가 메뉴에 맞는 기능을 BankingFunction을 실행시키면, BankingFunction 안에서 추가적인 정보를 입력받거나 결과를 보여주는 것을 하게 만들었다. + +하지만 이렇게 만들고보니 InputView와 OutputView를 BankingManager와 BankingFunction 둘 다 사용하기 때문에 View를 하나에서 관리하지 못하고 흩어져있는 느낌이 들었다. + +그래서 모든 입출력을 BankingManager에서 관리하도록 했고, BankingFunction과 BankingController는 BankingController 인터페이스와 각각 기능들의 Controller 클래스로 만들었다. + +#### Request와 Response 사용 + +FrontController에서는 모든 Controller를 가지고 있고, 선택된 메뉴에 맞는 Contorller를 호출한다. + +이 때 FrontController에서 Request를 만들어서 Controller에게 전달하고, 결과로 전달받은 Response를 돌려준다. + +Request는 Request를 구분할 수 있도록 EMenu enum을 RequestName으로 가지며, HashMap으로 각각의 Param은 어떤 Type인지를 의미하는 EParamType enum값과 실제 값인 Object를 가진다. + +Controller는 Request를 이용하여 View로부터 데이터를 전달받고, 결과를 Response로 돌려준다. + +Response에는 Message가 존재하고, 그 안에 Message나 Account, BigDecimal을 저장해서 돌려준다. + +Response는 BankingManager에서 확인하고 OutputView를 이용하여 결과를 출력한다. + +이러면 모든 입출력은 BankingManager에서 관리하고, 요청은 FrontController를 통해서 각 기능에 맞는 Controller에게 전달된다. + +## 2. 고민했던 점 + +1. Exception을 발생시키는 기준 + +이번에는 Exception을 어떻게 처리해야 될 지에 대해 고민했던 것 같다. + +가장 먼저 어느 범위부터 발생시켜야되고, 어느 정도부터는 그냥 Response로 실패한 것만 전송해야 되는지를 생각하였다. + +지금 만들어져있는 Exception은 NotExistAccountException, DeactivatedAccountException, IndexOutOfRangeException이다. + +IndexOutOfRangeException은 View에서 입력을 받고 Util 클래스를 이용해서 값을 만들 때, 비정상적인 값이라면 발생시키도록 만들었다. + +NotExistAccountException과 DeactivatedAccountException은 가장 우선순위로 확인해야되는 부분이기 때문에 만들었다. + +Banking의 모든 기능은 AccountNumber를 필요로하기 때문에, AccountNumber가 실제 존재하는 계좌의 번호인지 확인하는 과정이 제일 중요하다 생각했다. + +따라서 가장 먼저 입력받은 계좌 번호가 실제로 존재하는지 확인하고, 존재하지 않다면 Exception을 발생시켜서 흐름을 끊어내야 될 것 같았다. + +그리고 계좌가 존재한다면 그 다음으로 확인해야될 것은 계좌가 비활성화상태인지 확인하는 것이기 때문에 DeactivateAccountException을 사용했다. + +그런데 만들고보니 이것도 Response로 그냥 끝낼 수 있는다고 볼 수 있을 것 같아서 그대로 두는게 맞을 지 혹은 없애도되는 부분인지 고민했었다. + +2. 요청 실패시 다시 입력받아서 재요청 + +inputView를 통해서 입력이 다 끝나면 Controller로 Request를 보내준다. + +예시로 송금을 할 때에는 출금, 입금 계좌번호를 입력하고 송금 금액을 입력하고 결과를 받는다. + +만약 다 입력하고 결과를 보냈는데 출금 계좌번호만 정상이고 입금 계좌번호가 존재하지 않다면 Exception으로 빠져나가고 끝난다. + +이걸 다시 요청하려면 무슨 값이 잘못되었는지 Controller로부터 전달받아야되고, 그 값만 수정해서 다시 보낼 수 있어야된다. + +그러기 위해서는 Response가 지금처럼 하나의 Object만 있으면 안될 것 같다. + +View 계층에서 Response를 이용해서 결과를 확인하고, 만약 실패라면 실패의 원인, 그리고 다시 입력받아서 이를 다시 요청할 수 있어야한다. + +하지만 이런 과정에서 비즈니스 로직이 들어가게 되고, 결국 재사용성이 떨어질 것 가탕ㅆ다. + +결국 이 부분은 포기하고 원래대로 요청이 실패하면 메뉴로 돌아가게 만들었다. + +## 3. From 22c6c538ee90584bb5f89eeb01d9c5bdb38fab54 Mon Sep 17 00:00:00 2001 From: 0711kc <81899652+0711kc@users.noreply.github.com> Date: Mon, 15 Apr 2024 21:59:39 +0900 Subject: [PATCH 23/56] Update 0711kc.md --- week04/0711kc.md | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/week04/0711kc.md b/week04/0711kc.md index cfd6a5c..847b7f0 100644 --- a/week04/0711kc.md +++ b/week04/0711kc.md @@ -80,8 +80,8 @@ inputView를 통해서 입력이 다 끝나면 Controller로 Request를 보내 View 계층에서 Response를 이용해서 결과를 확인하고, 만약 실패라면 실패의 원인, 그리고 다시 입력받아서 이를 다시 요청할 수 있어야한다. -하지만 이런 과정에서 비즈니스 로직이 들어가게 되고, 결국 재사용성이 떨어질 것 가탕ㅆ다. +하지만 이런 과정에서 비즈니스 로직이 들어가게 되고, 결국 재사용성이 떨어질 것 같았다. -결국 이 부분은 포기하고 원래대로 요청이 실패하면 메뉴로 돌아가게 만들었다. +좋은 방법이 떠오르지않아서 일단은 요청이 실패하면 바로 메뉴로 돌아가는 원래 방식으로 돌아왔다. ## 3. From 29f3b97006aff610bea2b58c817e0f60d3edbb76 Mon Sep 17 00:00:00 2001 From: Gopistol <104254012+Gopistol@users.noreply.github.com> Date: Wed, 1 May 2024 14:58:30 +0900 Subject: [PATCH 24/56] Create README.md --- week03/README.md | 9 +++++++++ 1 file changed, 9 insertions(+) create mode 100644 week03/README.md diff --git a/week03/README.md b/week03/README.md new file mode 100644 index 0000000..fc44f10 --- /dev/null +++ b/week03/README.md @@ -0,0 +1,9 @@ +# 6주차 과제 - Spring 사전 조사 + +5/7 화요일 23:59 까지 제출해주시면 되겠습니다. + +## 스프링의 장점 / 사용 이유 +## 싱글톤, 싱글톤 컨테이너 +## 레이어드 아키텍쳐 패턴 +## 스프링 어노테이션 10개 이상 정리 +## Postman 설치해오기 From 90ccd10a439eea0d3d183b4a6423193db9fcad93 Mon Sep 17 00:00:00 2001 From: Gopistol <104254012+Gopistol@users.noreply.github.com> Date: Wed, 1 May 2024 14:59:32 +0900 Subject: [PATCH 25/56] Rename README.md to README.md --- {week03 => week06}/README.md | 0 1 file changed, 0 insertions(+), 0 deletions(-) rename {week03 => week06}/README.md (100%) diff --git a/week03/README.md b/week06/README.md similarity index 100% rename from week03/README.md rename to week06/README.md From 71c364b3a45b880933b204b650e6b1fad874951f Mon Sep 17 00:00:00 2001 From: Gopistol <104254012+Gopistol@users.noreply.github.com> Date: Wed, 1 May 2024 20:38:53 +0900 Subject: [PATCH 26/56] Rename README.md to README.md --- {week06 => week07}/README.md | 0 1 file changed, 0 insertions(+), 0 deletions(-) rename {week06 => week07}/README.md (100%) diff --git a/week06/README.md b/week07/README.md similarity index 100% rename from week06/README.md rename to week07/README.md From d86043d77cf3eaa21915918b62b142770e709ed5 Mon Sep 17 00:00:00 2001 From: Gopistol <104254012+Gopistol@users.noreply.github.com> Date: Wed, 1 May 2024 20:39:09 +0900 Subject: [PATCH 27/56] Update README.md --- week07/README.md | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/week07/README.md b/week07/README.md index fc44f10..a993b14 100644 --- a/week07/README.md +++ b/week07/README.md @@ -1,4 +1,4 @@ -# 6주차 과제 - Spring 사전 조사 +# 7주차 과제 - Spring 사전 조사 5/7 화요일 23:59 까지 제출해주시면 되겠습니다. From a718432bbcae4f278c652669bbcbac4085bcfb01 Mon Sep 17 00:00:00 2001 From: BuildTools Date: Wed, 1 May 2024 23:41:26 +0900 Subject: [PATCH 28/56] docs : Add 0711kc.md --- week07/0711kc.md | 9 +++++++++ 1 file changed, 9 insertions(+) create mode 100644 week07/0711kc.md diff --git a/week07/0711kc.md b/week07/0711kc.md new file mode 100644 index 0000000..a993b14 --- /dev/null +++ b/week07/0711kc.md @@ -0,0 +1,9 @@ +# 7주차 과제 - Spring 사전 조사 + +5/7 화요일 23:59 까지 제출해주시면 되겠습니다. + +## 스프링의 장점 / 사용 이유 +## 싱글톤, 싱글톤 컨테이너 +## 레이어드 아키텍쳐 패턴 +## 스프링 어노테이션 10개 이상 정리 +## Postman 설치해오기 From cac59867ccecbcaf732736de427df5febceb2de1 Mon Sep 17 00:00:00 2001 From: 0711kc <81899652+0711kc@users.noreply.github.com> Date: Fri, 3 May 2024 02:31:31 +0900 Subject: [PATCH 29/56] docs : Update 0711kc.md --- week07/0711kc.md | 149 ++++++++++++++++++++++++++++++++++++++++++++++- 1 file changed, 146 insertions(+), 3 deletions(-) diff --git a/week07/0711kc.md b/week07/0711kc.md index a993b14..ae23acd 100644 --- a/week07/0711kc.md +++ b/week07/0711kc.md @@ -1,9 +1,152 @@ # 7주차 과제 - Spring 사전 조사 -5/7 화요일 23:59 까지 제출해주시면 되겠습니다. - ## 스프링의 장점 / 사용 이유 +### 1. POJO 기반이다. +> 환경, 기술에 종속되지 않고 어떤 환경에서라도 작동할 수 있으며, 필요에 따라 재활용될 수 있다. +### 2. IoC를 통한 DI로 객체 관계가 만들어진다. +> 의존성을 주입하지 않고 직접 생성하게 되면 강한 결합 관계가 된다. 이러한 경우 추가적인 클래스가 더 필요한 경우에 유지보수가 힘들어진다. +> +> IoC에 의해서 스프링에 의해 의존성을 주입할 수 있다. +### 3. AOP를 지원한다. +> 비즈니스 로직이 아닌 보안, 로그와 같이 반드시 처리해야 되는 부분을 공통 관심사항이라고 한다. 그리고 이러한 공통 관심사항을 따로 객체로 분리해두고 이를 적용할 객체를 지정해줄 수 있다. +### 4. MVC 패턴에 최적화되어있다. + +### 5. 확장성이 좋다. +> 기존 라이브러리를 간단하게 스프링 프레임워크에 통합시켜서 사용할 수 있으며, 사용되는 라이브러리를 분리하기도 용이하다. +사용 이유 + > 1. 정형화되어있기 떄문에 일정 수준의 품질을 기대할 수 있다. + > + > 2. 개발 후에도 유지 보수 및 기능의 확장성의 품질을 보장할 수 있다 + > + > 3. 전자표준 프레임워크이기 때문에 한국에서의 수요가 크다. + ## 싱글톤, 싱글톤 컨테이너 +### 싱글톤 패턴 +> 클래스의 인스턴스가 1개만 생성되는 것을 보장하는 디자인 패턴 +> +> 생성자를 private으로 사용하여 외부에서 new 키워드를 사용하지 못하게 막는다. +> +> 그리고 getInstance() 메소드를 통해 생성된 인스턴스를 받아온다. + + +### 단점 +> 구체 클래스에 있는 getInstance 메소드를 사용해야 되기 때문에 대상의 상위 요소를 참조해야된다는 DIP 원칙을 위반한다. +> +> 결국 구체 클래스에 의존하기 때문에 구체클래스가 바뀌면 클라이언트 코드가 바뀔 수도 있다. 따라서 확장에 열려있고 수정에 닫혀있어야된다는 OCP 원칙을 위반할 가능성이 있다. +> +> Private 생성자를 사용하기 떄문에 자식 클래스를 만들기 어렵다. +> +> 구체 클래스로부터 getInstance를 해야되기 떄문에 의존성을 주입하기가 어렵다. + +### 싱글톤 컨테이너 +> 스프링 컨테이너는 싱글톤 패턴을 적용하지 않아도 인스턴스를 싱글톤으로 관리한다. +> +> 싱글톤 레지스트리 : 싱글톤 객체를 생성하고 관리하는 기능 +> +> 스프링 컨테이너는 DIP, OCP, private 생성자로부터 자유롭게 싱글톤을 사용할 수 있다. +> +> 기본 빈 등록방식은 싱글톤이지만, 싱글톤만 있는 것이 아니라 요청할 때마다 새로운 객체를 생성해서 반환하는 것도 가능하다. + +### 주의점 +> 싱글톤 객체는 전역에서 공유하기 때문에 멀티쓰레드 환경에서 동시성 문제가 있을 수 있다. +> +> 둘 이상의 쓰레드가 접근할 때 발생하는 문제가 생기지 않도록 상호배제를 보장해주거나 아예 상태를 유지하지 않는 객체로 설계해야된다. +> +> 상태가 없는 객체는 특정 클라이언트에 의존적이거나 값을 변경할 수 있는 필드가 있으면 안되고 읽기만 가능해야한다. + ## 레이어드 아키텍쳐 패턴 +### 레이어드 아키텍쳐 패턴 +> 레이어를 분리하여 각각의 레이어가 해야 할 역할을 정의해놓은 구조이다. +> +> 하위 계층은 상위 계층에 대한 정보가 없어야된다. +> +> 상위 계층은 자신의 책임 외에는 하위 계층의 추상화된 인터페이스에 의존한다. + +### 레이어의 종류 +#### 1. Presentation 레이어 +> 인터페이스와 애플리케이션을 연결한다. +> +> 웹 통신 프레임워크, 인터페이스, 입출력의 변환 등 외부와의 통신을 담당한다. +#### 2. Business 레이어 +> Presentation으로부터 요청을 전달받아 해당 요청을 실질적으로 처리한다. +> +> 시스템이 구현해야할 비즈니스 로직만 들어가있다. +#### 3. Persistance레이어 +> 실질적으로 데이터를 관리하기 위해 DB와 연결되며, DB와 관련된 기술은 모두 이 안에 들어있다. +#### 4. DB 레이어 +> 데이터를 저장한 데이터베이스이다. + ## 스프링 어노테이션 10개 이상 정리 -## Postman 설치해오기 +### 1. @Bean +> Bean을 등록하려는 메소드에 붙이는 어노테이션이다. +> +> Bean은 인스턴스화된 객체이며 재사용될 수 있다. +> +> 스프링 컨테이너에 의해 관리되는 Bean을 스프링 Bean이라고 부른다. +### 2. @Component +> Bean이 등록될 수 있는 후보 클래스를 명시하는 어노테이션이다. +### 3. @Controller +> 스프링에서 컨트롤러로 이용될 클래스를 명시하는 어노테이션이다. +> +> 매핑할 URL을 통해 요청을 받는다. +### 4. @RestController +> @Controller + @ResponseBody +### 5. @ControllerAdvice +> Controller 클래스에 선언된 @ExceptionHandler, @ModelAttribute, @InitBinder를 공유한다. +> +> 주로 ExceptionHandler와 관련된 처리를 한다. +### 6. @RestControllerAdvice +> @ControllerAdvice + @ResponseBody +### 7. @InitBinder +> Controller에 들어오는 요청에 대한 추가 설정을 한다. +### 8. @Service +> 비즈니스 로직을 처리하는 Buisness 레이어에 붙이는 어노테이션이다. +### 9. @Repository +> DB관련 로직을 처리하는 Infrastructure 레이어에 붙이는 어노테이션이다. +### 10. @Configuration +> @Bean을 붙인 메서드들을 Bean으로 등록하는 어노테이션이다. +### 11. @RequestMapping +> 요청에 대한 URL을 매핑하는 어노테이션이다. HTTP 메서드를 지정해서 특정 메서드에 대한 응답만 받을 수 있다. +> +> 메서드 뿐만 아니라 클래스에도 붙일 수 있다. 그리고 메서드에 @GetMapping으로 메서드의 특정 URL을 매핑할 수 있다. +> +> @GetMapping, @PostMapping, @PutMapping, @PatchMapping, @DeleteMapping은 HTTP 메서드 명시 부분을 미리 선언한 어노테이션이다. +### 12. @RequestParm +> 파라미터 이름을 바인딩 시켜주는 어노테이션이다. +> +> 오직 1개의 요청 파라미터를 받을 때 사용하며, 반드시 해당 파라미터가 전송되어야한다. +> +> QueryString과 x-www-form-urlencoded에 관한 요청을 처리한다. + +#### QueryString +> URL 주소에 데이터를 파라미터로 전송하는 방식이다. +#### x-www-form-urlencoded +> x-www-form-urlencoded는 데이터를 URL 인코딩을 하고 URL로 전송하는 방식이다. +### 13. @RequestBody +> Request 안의 JSON 형태의 HTTP Body를 Java 객체로 변환시켜주는 어노테이션이다. +### 14. @RequestHeader +> Request의 Header를 저장하는 어노테이션이다. +### 15. @PathVariable +> URL에 변수를 이용할 수 있게 해주는 어노테이션이다. +### 16. @RequestPart +> Multipart/form-data의 데이터를 받는데 특화된 어노테이션이다. +> +> 여러 개의 데이터가 서로 다른 타입으로 들어올 떄 이용할 수 있다. +### 17. @ModelAttribute +> Reuqest 안의 Form 형태의 HTTP Body나 요청 파라미터들을 생성자나 Setter로 바인딩시켜 하나의 모델로 사용하는 어노테이션이다. +> +> 해당 모델은 그 안에 생성자나 Setter가 있어야한다. +### 18. @ResponseBody +> Body에 자바 객체가 담긴다는 것을 명시하는 어노테이션이다. +> +> 자바 객체를 HTTP 요청의 body로 매핑하여 클라이언트로 전송한다. +### 19. @ResponseStatus +> 응답 코드를 설정하는 어노테이션이다. +### 20. @AutoWired +> 의존성을 주입해주는 어노테이션이다. +> +> 필드 주입, Setter 주입, 생성자 주입으로 3가지 방법이 있다. +### 21. @ExceptionHandler +> 명시해둔 예외가 들어오면 해당 메서드를 실행시켜주는 어노테이션이다. +### 22. @Value +> 설정 파일에 입력된 값을 변수에 담는 어노테이션이다. From 2a843a8f21c97edae12b948ff56c23c584275310 Mon Sep 17 00:00:00 2001 From: SeungGyu Date: Fri, 3 May 2024 15:11:05 +0900 Subject: [PATCH 30/56] =?UTF-8?q?7=EC=A3=BC=EC=B0=A8=20=ED=95=99=EC=8A=B5?= =?UTF-8?q?=20PR?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .../\355\225\234\354\212\271\352\267\234.md" | 115 ++++++++++++++++++ 1 file changed, 115 insertions(+) create mode 100644 "week07/\355\225\234\354\212\271\352\267\234.md" diff --git "a/week07/\355\225\234\354\212\271\352\267\234.md" "b/week07/\355\225\234\354\212\271\352\267\234.md" new file mode 100644 index 0000000..0214d7c --- /dev/null +++ "b/week07/\355\225\234\354\212\271\352\267\234.md" @@ -0,0 +1,115 @@ +# Week7 + +작업자: 승규 한 +상태: 시작 전 +요약: Week1 +마감일: 2024년 5월 5일 + +## 스프링 장점/사용이유 + +스프링을 사용하면 스프링에서 제공하는 여러 핵심 요소들을 사용하여 개발 과정에서 비즈니스 로직에 집중하여 개발할 수 있게 도와준다. + +### 핵심요소 + +1. 의존성 주입 + + 의존성 주입은 컴포넌트 간의 의존성을 외부에서 제어하고 관리해 주는 것으로 이러한 의존성 주입을 통해 코드 간의 결합도를 낮추어 유지 보수성, 테스트 용이성을 높일 수 있다. + + + +2. 데이터 액세스 지원 + + JDBC, JPA 같은 데이터 액세스 기술을 추상화여 제공해 준다. 이를 통해 데이터베이스 작업을 간단하고 쉽게 할수있다. + +3. AOP + + AOP는 비즈니스 로직으로부터 부가적인 기능 (공통관심사)를 분리함으로 코드의 재사용을 증가시키고 유지 보수를 용이하게 해준다. + 대표적으로 트랜잭션 관리, 로깅, 보안 등이 있다. + + +이외에도 트랜잭션관리, 모듈러 아키텍쳐와 같은 여러 장점들이 존재하고 이러한 장점들이 개발과정을 효율적으로 만들어주기 때문에 개발자들이 핵심 비즈니스 로직에 더 많은 시간을 들일 수 있다는 장점이 존재한다. + +## 싱글톤, 싱글톤 컨테이너 + +### 싱글톤 + +싱글톤은 프로그램에서 특정 클래스의 인스턴스가 하나만 존재하는 개념이다. 이러한 싱글톤은 클래스의 인스턴스를 프로그램 전체에서 공유하여 사용해야 할 때 유용하다. 이러한 싱글톤 개념을 사용하기 위해 객체 인스턴스를 2개 이상 생성하지 못하게 막아주는 싱글톤 패턴을 디자인 패턴으로 사용하기도 한다. + +### 싱글톤 컨테이너 + +싱글톤 컨테이너는 클래스의 인스턴스를 하나만 생성하고 관리해 주는 컨테이너를 말한다. +싱글톤 컨테이너는 인스턴스의 유일성을 보장하고 해당 인스턴스를 전역적으로 접근할 수 있게 해주며 인스턴스가 생성부터 소멸까지 생명주기를 관리해 준다. + +스프링 컨테이너는 이러한 싱글톤 스코프의 특성을 기본적으로 사용하며 싱글톤 외에도 프로토타입, 리퀘스트, 세션 등의 스코프를 사용한다. + +## 레이어드 아키텍쳐 패턴 + +레이어드 아키틱쳐는 소프트웨어를 여러 개의 계층으로 분리해서 설계하는 방법을 말한다. + +이러한 레이어드 아키텍쳐는 애플리케이션, 복잡도, 요구사항 등 여러 요소에 따라 그 구성이 달라지므로 각각의 계층을 외우기보다 계층의 분리를 통해 서로의 의존성을 줄여 유지 보수와 확장성을 높이기 위한 설계법이라는 것을 아는 것이 좋다. + +레이어드 아키텍쳐의 주요 계층에는 3가지가 존재한다. + +1. 표현 계층 **(Presentation Layer)** + + 표현 계층은 사용자 인터페이스와 입력 처리를 담당한다. → 사용자의 요청과 응답을 담당한다. + +2. 비즈니스 로직 계층 **(Presentation Layer)** + + 비즈니스 로직 계층은 애플리케이션 핵심 기능과 비즈니스 로직을 담당한다. + +3. 데이터 액세스 계층 **(Data Access Layer)** + + 데이터 액세스 계층은 데이터베이스와 같은 저장소와의 통신을 담당하는 게층이다. + + +이러한 방식으로 계층을 세부적으로 분리하는 레이어드 아케텍쳐 패턴을 사용하면 각 계층의 변경이 다른 계층에 미치는 영향을 최소화하면서 요구사항에 따라 계층을 유연하게 추가, 제거할 수 있다. + +## 스프링 어노테이션 10개 이상 정리 + +`@ResponseBody` + +http응답에 JSON, XML같은 형식의 메서드 데이터 반환값을 http 응답 본문으로 전송하게 해주는 어노테이션. + +`@controller` + +컨트롤러 레이어를 정의해주며 웹 페이지를 반환해준 어노테이션. + +`@RestController` + +컨트롤러 레이어를 정의해준다는 점에서 `@controller` 어노테이션과 유사한 역할을 하지만 모든 메서드에`@ResponseBody` 가 자동으로 적용되어 JSON or XML같은 형식으로 데이터를 http 응답 반환해주는 어노테이션. + +`@RequestMapping` + +Http 요청이 들어왔을때 설정해놓은 경로에 따라 메서드를 매핑시켜주는 어노테이션. +구체적인 매핑 메서드가 존재할 때는 구체적인 어노테이션이 붙은 메서드가 실행된다. + +`@PostMapping` + +http Post 요청이 들어온 경우 설정해놓은 경로와 맞을때 매핑시켜주는 어노테이션 + +`@GetMapping` + +http Get 요청이 들어온 경우 설정해놓은 경로와 맞을때 매핑시켜주는 어노테이션 + +`@Configuration` + +스프링 IoC 컨테이너에 의해 빈 정의를 제공하는 설정 클래스임을 나타내주는 어노테이션. + +`@Transactional` + +메서드의 실행을 하나의 트랜잭션으로 처리하게 해줌으로 트렌잭션 경계를 정의해주는 어노테이션 + +성공 시 트랜잭션을 커밋하고 실패시 롤백해준다. + +`@Autowired` + +스프링 컨테이너에서 의존관계 주입을 자동으로 해주기 위해 사용되는 어노테이션. + +`@ModelAttribute` + +메서드의 파라미터가 http요청 파라미터에서 값을 바인딩 받거나 Model 객체에 데이터 추가를 할 때 사용되는 어노테이션. + +`@PathVaribale` + +url의 경로변수를 메서드의 파라미터로 바인딩할 때 사용되는 어노테이션. \ No newline at end of file From 3ea91779f83d876e5885b7359203b39cd15c5c52 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?=EA=B9=80=EC=A7=80=EC=9B=85?= Date: Sun, 5 May 2024 23:43:53 +0900 Subject: [PATCH 31/56] =?UTF-8?q?7=EC=A3=BC=EC=B0=A8?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .../\352\271\200\354\247\200\354\233\205.md" | 108 ++++++++++++++++++ 1 file changed, 108 insertions(+) create mode 100644 "week07/\352\271\200\354\247\200\354\233\205.md" diff --git "a/week07/\352\271\200\354\247\200\354\233\205.md" "b/week07/\352\271\200\354\247\200\354\233\205.md" new file mode 100644 index 0000000..12890e1 --- /dev/null +++ "b/week07/\352\271\200\354\247\200\354\233\205.md" @@ -0,0 +1,108 @@ +# 7주차 과제 - Spring 사전 조사 + +## Spring 정의 +- 엔터프라이즈용 Java 애플리케이션 개발을 편하게 할 수 있게 해주는 오픈소스 경량급 애플리케이션 프레임워크 +- 프레임워크란, 어떠한 목적을 쉽게 달성할 수 있도록 해당 목적과 관련된 코드의 뼈대를 미리 만들어둔 것을 의미 +- 애플리케이션 프레임워크는 애플리케이션을 개발하는 데에 있어 필요한 모든 업무 분야 및 모든 기술과 관련된 코드들의 뼈대를 제공 + + + +## Spring 장점 / 사용이유 +- 스프링을 사용함으로써 기존 기술을 사용할 때에 불가피하게 작성해야만 했던 불필요하게 복잡한 코드를 제거하여 코드의 복잡성을 낮출 수 있음 +- POJO 프로그래밍을 지향 + + + +### POJO란 +- POJO란, Plain Old Java Object, 즉 순수 Java만을 통해서 생성한 객체를 의미 +- POJO는 말 그대로, 다른 기술을 사용하지 않는 순수한 Java만을 사용하여 만든 객체 +- 외부 라이브러리를 import하여 라이브러리의 메서드를 사용하고 있는 객체는 POJO가 아님. 이 객체에 사용되는 기술을 대체해야하는 상황이 발생하면 관련된 모든 객체들의 코드를 전부 바꿔야함. +- POJO를 사용하면 객체지향 설계를 제한없이 적용할 수 있으며, 코드가 단순해져 테스트와 디버깅 또한 쉬워짐 +- POJO 프로그래밍을 위해 스프링이 지원하는 기술에는 IoC/DI, AOP, PSA가 있다 + +### IoC / DI +- Inversion of Control 제어의 역전 / Dependency Injection 의존성 주입 +- A class가 B class의 메소드를 호출하면 A가 B에 의존하는 관계 + + + +- 만약 기존에 B를 사용하던 객체가 A 뿐만 아니라, 수십 또는 수백개가 있다면 모든 객체의 코드를 수정해주어야함 +- 아래 사진처럼 변경가능 + + + +- A는 자신이 사용할 객체를 스스로 생성하지 않고, 생성자를 통해 외부로부터 받아오고 있음 +- 개발자가 아닌 스프링이 A가 사용할 객체를 생성하여 의존 관계를 맺어주는 것을 IoC라고 하며, 그 과정에서 C를 A의 생성자를 통해 주입해주는 것을 DI라고 함 + +### AOP (Aspect Oriented Programming, 관심 지향 프로그래밍) +- 애플리케이션의 핵심 기능에 공통적으로 쓰이는 로깅이나 보안 등과 같은 공통 관심 사항이 들어있어 중복으로 인한 에러사항을 해결하기 위해 공통 관심 사항과 관련된 기능을 분리하여 구현하는 것을 AOP라 함 + +### PSA (Portable Service Abstraction, 일관된 서비스 추상화) +- 만약 MySQL을 사용하여 개발을 완료했는데, Oracle로 바꿔야 하는 상황에서 Spring을 사용하면 동일한 사용방법으로 바꿀 수 있음 +- Spring은 Java를 사용하여 데이터베이스에 접근하는 방법을 규정한 인터페이스를 제공하고 있으며, 이를 JDBC(Java DataBase Connectivity)함 +- 각 데이터베이스를 만든 회사들은 자신의 데이터베이스에 접근하는 드라이버를 Java 코드의 형태로 배포하는데, 이 드라이버에 해당하는 Java 코드의 클래스가 JDBC를 구현 +- 이러한 JDBC처럼 특정 기술과 관련된 서비스를 추상화하여 일관된 방식으로 사용될 수 있도록 한 것을 PSA라 함 + + + + + +## 싱글톤, 싱글톤 컨테이너 + +### 싱글톤 패턴 +- 서비스를 운영할 때, 동일한 요청에 대해서 각각 서로 다른 객체들을 만들어서 응답을 하면 메모리 공간을 많이 사용한다는 단점을 해결 +1. static 객체를 통해서 해당 객체를 1개만 생성할 수 있도록 지정한다. +2. static 메소드를 통해서 외부에서 생성할 수 있도록 제한한다. +3. new 연산자를 통해서 객체를 만드는 것을 private 생성자를 통해서 제한한다. +- 단점도 많지만 Spring에서 대부분 해결해준다. + +### 싱글톤 컨테이너 +- 스프링 컨테이너는 싱글턴 패턴을 적용하지 않아도 객체 인스턴스를 싱글톤으로 관리한다. 이러한 기능 덕분에 싱글톤 패턴의 모든 단점을 해결하고 객체를 싱글톤으로 유지할 수 있다. +1. 스프링에서 싱글턴 관련 코드는 작성하지 않아도 스프링의 기능으로 빈에다가 객체를 1개 설정한다. +2. 객체를 새롭게 생성했지만 같은 객체를 생성한 결과를 볼 수 있음 + + + + + +## 레이어드 아키텍쳐 패턴 +- 각 구성 요소들이 관심사의 분리(Separation of Concerns)를 달성하기 위해 책임을 가진 계층으로 분리한 아키텍쳐 + +- 각 계층들을 관심사 기준으로 분리함으로써 계층의 응집도를 높이고 결합도를 낮출 수 있음. 이를 통해 재사용성과 유지보수성을 높일 수 있음 + +-각 시스템 마다 경우가 다를 수 있으나 일반적으로 보통 다음과 같은 3개의 레이어가 존재함. +* presentation layer + - 해당 시스템을 사용하는 사용자 혹은 클라이언트 시스템과 직접적으로 연결되는 부분 + - +* business layer + - 실제 시스템이 구현해야하는 로직을 구현하는 부분 + - Presentation layer에서 전송된 요청을 읽어들여 요청에 맞게 동작하는 로직을 구현 +* persistence + - 데이터베이스와 관련된 로직을 구현하는 부분 + - Business layer에서 필요한 데이터를 생성, 수정, 읽기 등을 처리하여 실제로 데이터베이스에서 데이터를 저장, 수정, 읽어 들이기를 하는 역할 + +- 단방향 의존성으로 각각의 레이어는 오직 자기보다 하위에 있는 레이어에만 의존한다. presenstation layer는 business layer에게 의존하고, business layer는 persistence layer에게만 의존하게 됨. + +- 각 레이어가 독립적이고 역할이 분명하므로 코드의 확장성이 높아지고 코드의 구조를 파악하기 쉬울 뿐만 아니라 재사용 가능성도 높아짐. 또 테스트 코드 작성도 쉬움 + + + + + + +## 스프링 어노테이션 10개 이상 정리 + +* @Configuration : 스프링 IoC Container에게 해당 클래스가 Bean 구성 Class임을 알려주는 어노테이션 +* @EnableAutoConfiguration : Spring Application Context를 만들 때 자동으로 설정하는 기능을 켠다. classpath의 내용에 기반해서 자동 생성 +* @ComponentScan : @Component, @Service, @Repository, @Controller, @Configuration이 붙은 빈들을 찾아서 Context에 빈을 등록해 주는 어노테이션 +* @Component : 개발자가 직접 작성한 Class를 Bean으로 등록하기 위한 어노테이션 +* @Bean : @Bean은 개발자가 직접 제어가 불가능한 외부 라이브러리 등을 Bean으로 만드려할 때 사용되는 어노테이션 +* @Autowired : 필드, setter 메소드, 생성자에 사용하며 Type에 따라 알아서 Bean을 주입해주는 역할, 객체에 대한 의존성을 주입, @Autowired을 사용하면 스프링이 자동적으로 값을 할당 +* @Controller : Spring MVC의 Controller로 사용되는, 클래스 선언을 단순화 시켜주는 어노테이션 +* @RestController : Spring에서 Controller 중 View로 응답하지 않는 Controller를 의미, method의 반환 결과를 JSON 형태로 반환 +* @Service : Service class에서 쓰이는 어노테이션으로, 비즈니스 로직을 수행하는 Class라는 것을 나타내는 용도 +* @Repository : DAO class에서 쓰이는 어노테이션으로 DB에 접근하는 method를 가지고 있는 Class에서 쓰임 +* @Lookup : 이 어노테이션이 선언된 메소드는 리턴 타입을 가진 스프링 빈을 뱉음 +* @Value : 로 application.properties 및 스프링이나 자바 property 값을 가져올 때 씀, propertis에서 값을 가져와 적용할 때 사용 +* @Scope : 빈의 생명주기를 설정 + From 5305a9d4e02898f77dc84dfcd7a5e7bec661669d Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?=EA=B9=80=EC=A7=80=EC=9B=85?= Date: Sun, 5 May 2024 23:50:35 +0900 Subject: [PATCH 32/56] readme --- week07/README.md | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/week07/README.md b/week07/README.md index a993b14..8de8e53 100644 --- a/week07/README.md +++ b/week07/README.md @@ -1,4 +1,4 @@ -# 7주차 과제 - Spring 사전 조사 +# 7주차 과제 - Spring 사전 조사 5/7 화요일 23:59 까지 제출해주시면 되겠습니다. From 21ef80955a516d6a226f08977b2871ca9f279425 Mon Sep 17 00:00:00 2001 From: qwejiung <136984070+qwejiung@users.noreply.github.com> Date: Sun, 5 May 2024 23:54:20 +0900 Subject: [PATCH 33/56] =?UTF-8?q?=EC=82=AC=EC=A7=84=EC=B6=94=EA=B0=80?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- "week07/\352\271\200\354\247\200\354\233\205.md" | 8 +++++--- 1 file changed, 5 insertions(+), 3 deletions(-) diff --git "a/week07/\352\271\200\354\247\200\354\233\205.md" "b/week07/\352\271\200\354\247\200\354\233\205.md" index 12890e1..3c765c1 100644 --- "a/week07/\352\271\200\354\247\200\354\233\205.md" +++ "b/week07/\352\271\200\354\247\200\354\233\205.md" @@ -1,4 +1,4 @@ -# 7주차 과제 - Spring 사전 조사 +![loc1](https://github.com/qwejiung/COW-Spring-3/assets/136984070/4b9bb2b0-a81d-4701-8d43-c64ca0ed9889)# 7주차 과제 - Spring 사전 조사 ## Spring 정의 - 엔터프라이즈용 Java 애플리케이션 개발을 편하게 할 수 있게 해주는 오픈소스 경량급 애플리케이션 프레임워크 @@ -24,12 +24,14 @@ - Inversion of Control 제어의 역전 / Dependency Injection 의존성 주입 - A class가 B class의 메소드를 호출하면 A가 B에 의존하는 관계 - +![loc1](https://github.com/qwejiung/COW-Spring-3/assets/136984070/5ba90623-318f-453b-a5fd-20808c33c06e) + - 만약 기존에 B를 사용하던 객체가 A 뿐만 아니라, 수십 또는 수백개가 있다면 모든 객체의 코드를 수정해주어야함 - 아래 사진처럼 변경가능 - +![loc2](https://github.com/qwejiung/COW-Spring-3/assets/136984070/b4333a61-7787-475c-809e-b859256f38d1) + - A는 자신이 사용할 객체를 스스로 생성하지 않고, 생성자를 통해 외부로부터 받아오고 있음 - 개발자가 아닌 스프링이 A가 사용할 객체를 생성하여 의존 관계를 맺어주는 것을 IoC라고 하며, 그 과정에서 C를 A의 생성자를 통해 주입해주는 것을 DI라고 함 From 176a2e8859aaf0f6552ad22c71761784c5d3453b Mon Sep 17 00:00:00 2001 From: qwejiung <136984070+qwejiung@users.noreply.github.com> Date: Sun, 5 May 2024 23:54:52 +0900 Subject: [PATCH 34/56] =?UTF-8?q?Update=20=EA=B9=80=EC=A7=80=EC=9B=85.md?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- "week07/\352\271\200\354\247\200\354\233\205.md" | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git "a/week07/\352\271\200\354\247\200\354\233\205.md" "b/week07/\352\271\200\354\247\200\354\233\205.md" index 3c765c1..42f79f9 100644 --- "a/week07/\352\271\200\354\247\200\354\233\205.md" +++ "b/week07/\352\271\200\354\247\200\354\233\205.md" @@ -1,4 +1,4 @@ -![loc1](https://github.com/qwejiung/COW-Spring-3/assets/136984070/4b9bb2b0-a81d-4701-8d43-c64ca0ed9889)# 7주차 과제 - Spring 사전 조사 +# 7주차 과제 - Spring 사전 조사 ## Spring 정의 - 엔터프라이즈용 Java 애플리케이션 개발을 편하게 할 수 있게 해주는 오픈소스 경량급 애플리케이션 프레임워크 From 067de431a924df5088c9733401f2a493afa6b9fc Mon Sep 17 00:00:00 2001 From: qwejiung <136984070+qwejiung@users.noreply.github.com> Date: Sun, 5 May 2024 23:56:50 +0900 Subject: [PATCH 35/56] Delete week07/README.md --- week07/README.md | 9 --------- 1 file changed, 9 deletions(-) delete mode 100644 week07/README.md diff --git a/week07/README.md b/week07/README.md deleted file mode 100644 index 8de8e53..0000000 --- a/week07/README.md +++ /dev/null @@ -1,9 +0,0 @@ -# 7주차 과제 - Spring 사전 조사 - -5/7 화요일 23:59 까지 제출해주시면 되겠습니다. - -## 스프링의 장점 / 사용 이유 -## 싱글톤, 싱글톤 컨테이너 -## 레이어드 아키텍쳐 패턴 -## 스프링 어노테이션 10개 이상 정리 -## Postman 설치해오기 From 7e0d0ec8153c4013aab9317e5c2aaa2cd76ba7b7 Mon Sep 17 00:00:00 2001 From: qwejiung <136984070+qwejiung@users.noreply.github.com> Date: Sun, 5 May 2024 23:58:28 +0900 Subject: [PATCH 36/56] =?UTF-8?q?=EA=B9=80=EC=A7=80=EC=9B=85.md?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- "week07/\352\271\200\354\247\200\354\233\205.md" | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git "a/week07/\352\271\200\354\247\200\354\233\205.md" "b/week07/\352\271\200\354\247\200\354\233\205.md" index 42f79f9..9a19f0a 100644 --- "a/week07/\352\271\200\354\247\200\354\233\205.md" +++ "b/week07/\352\271\200\354\247\200\354\233\205.md" @@ -1,4 +1,4 @@ -# 7주차 과제 - Spring 사전 조사 +# 7주차 과제 - Spring 사전 조사 ## Spring 정의 - 엔터프라이즈용 Java 애플리케이션 개발을 편하게 할 수 있게 해주는 오픈소스 경량급 애플리케이션 프레임워크 From 342a61c3c55e63a6683ed31b869722db3b765ad9 Mon Sep 17 00:00:00 2001 From: jaehyuk Date: Mon, 6 May 2024 17:43:14 +0900 Subject: [PATCH 37/56] =?UTF-8?q?:memo:=20WEEK7=20=ED=95=99=EC=8A=B5?= =?UTF-8?q?=EB=82=B4=EC=9A=A9=20=EC=9E=91=EC=84=B1?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .../\353\260\261\354\236\254\355\230\201.md" | 105 ++++++++++++++++++ 1 file changed, 105 insertions(+) create mode 100644 "week07/\353\260\261\354\236\254\355\230\201.md" diff --git "a/week07/\353\260\261\354\236\254\355\230\201.md" "b/week07/\353\260\261\354\236\254\355\230\201.md" new file mode 100644 index 0000000..1e61eef --- /dev/null +++ "b/week07/\353\260\261\354\236\254\355\230\201.md" @@ -0,0 +1,105 @@ +# 7주차 과제 - Spring 사전 조사 + +5/7 화요일 23:59 까지 제출해주시면 되겠습니다. + +## 스프링의 장점 / 사용 이유 + +Spring은 자바 플랫폼을 위한 오픈 소스 애플리케이션이다. 이를 사용함으로 얻을 수 있는 장점은 다음과 같이 알아볼 수 있었다. +Java 엔터프라이즈 개발을 보다 편리하게 가능하게 하는데 이는 결국 기술적은 문제보다 애플리케이션의 비즈니스 로직 자체에 집중할 수 있다는 것과 같다. +또한, Spring은 POJO 프로그래밍을 지향하는데 이는 저번 세션에서도 언급되었던 내용 중 하나이다. 스프링의 기본 구조는 `IoC`, `DI`, `AOP`, `PSA`라는 주요 기술 +을 통해 애플리케이션을 POJO로 개발할 수 있게 해준다. (여기서 POJO는 오래된 방식의 간단한 자바 오브젝트로, 무거운 객체를 만들게 된 것에 반발해서 사용하게 된 +용어이다.) + +* `DI(Dependency Injection)` +: 객체 간의 의존관계를 직접 설정하는 것이 아닌 외부에서 생성하여 주입시키는 개념의 디자인 패턴 + +* `Ioc(Inversion of Control)` +: 이는 원칙의 개념으로, DI는 IoC라는 원칙을 지키기 위한 다양한 디자인 패턴 중 하나이다. 이는 유연하고 확정성이 뛰어난 코드를 작성하기 위한 +목표를 가지기 위함이다. + + +## 싱글톤, 싱글톤 컨테이너 + +싱글톤 패턴은 클래스의 인스턴스가 딱 1개만 생성된느 것을 보장하는 디자인 패턴으로 객체 인스턴스 2개 이상을 생성하지 못하도록 한다. +이는 private 생성자를 사용해서 외부에서 임의로 new 키워드를 사용하지 못하도록 막아야 한다. 해당 싱글톤 패턴을 구현하는 코드를 구현하면서 지켜야할 것은 `static` 필드로 인스턴스를 미리 생성해두고, +만들어둔 인스턴스의 참조를 반환하는 메서드를 정의하며 private 생성자를 만들게 된다. 이러한 싱글톤 패턴의 문제는 테스트하기가 어려운 점이 있고, 내부 속성을 변경하거나 초기화하기 어렵다는 점이 존재한다, +또한, private 생성자로 자식 클래스를 만들기 어렵다는 단점 역시 가진다. + +이러한 단점을 해결해 줄 수 있는 것이 싱글톤 컨테이너이다. +스프링 컨테이너는 싱글턴 패턴의 문제점을 해결하면서, 객체 인스턴스를 싱글톤(1개만 생성)으로 관리한다. 스프링 빈이 바로 싱글톤으로 관리되는 빈이다. +스프링 컨테이너는 싱글톤 패턴을 적용하지 않아도, 객체 인스턴스를 싱글톤으로 관리하며, 스프링 컨테이너는 싱글톤 컨테이너 역할을 한다. 이렇게 싱글톤 객체를 생성하고 관리하는 기능을 싱글톤 레지스트리라고 한다. +스프링 컨테이너의 이러한 기능 덕분에 싱글톤 패턴의 모든 단점을 해결하면서 객체를 싱글톤으로 유지할 수 있다. +싱글톤 패턴을 위한 지저분한 코드가 들어가지 않아도된다. +DIP, OCP, 테스트, private 생성자로부터 자유롭게 싱글톤을 사용할 수 있다. + +## 레이어드 아키텍쳐 패턴 +코드 아키텍처를 구상할 때는 확장성(extensibility), 재사용성(reusability), 유지 보수 가능성(maintainabiliy), 가독성(readability)를 염두해야 한다. 이러한 염두를 둔 백엔드 API 패턴인 `레이어드 아키텍쳐 패턴`이 존재한다. +`Multi-tier 아키텍처 패턴`이라고도 하는 레이어드 아키텍처는 코드를 논리적인 부분 혹은 역할에 따라 독립된 모듈로 나누어서 구성하는 패턴이다. 그리고 각 모듈이 서로의 의존도에 따라 층층히 쌓듯이 연결되어서 전체의 시스템을 구현하는 구조이며, +마치 레이어(layer)를 쌓아 놓은 것 같은 형태의 구조가 된다. +보통 다음과 같은 레이어가 존재한다. + +1. Presentation Layer +: Presentation layer는 해당 시스템을 사용하는 사용자 혹은 클라이언트 시스템과 직접적으로 연결되는 부분이다.. 웹사이트에서는 UI 부분에 해당하고 백엔드 API에서는 엔드포인트 부분에 해당하며, +presentation layer에서 API의 엔드포인트들을 정의하고 전송된 HTTP 요청(request)를 읽어 들이는 로직을 구현한다. +하지만 그 이상의 역할은 담당하지 않습니다. 실제 시스템이 구현하는 비즈니스 로직은 다음 레이어로 넘기게 됩니다. + 다음과 같은 역할을 담당합니다. + + - EndPoint + - Authentication + - JSON Translation + +2. Business Layer +: Business layer라는 이름 그대로 비즈니스 로직을 구현하는 부분이다. 실제 시스템이 구현해야하는 로직을 이 레이어에서 구현하게 됩니다. 백엔드 API에서는  Presentation layer에서 전송된 요청을 읽어들여 요청에 맞게 동작하는 로직을 구현하면 됩니다. 예를 들어 회원가입 요청 시 필수적인 요소들이 다 포함되어 있지 않으면 거부한다던가 하는 로직 등이 비즈니스 로직이며, buisiness layer에서 구현하게 됩니다. + 다음과 같은 역할을 담당합니다. + + - Business Logic + - Validation + - Authorisation + + +3. Persistence Layer +: Persistence layer는 데이터베이스와 관련된 로직을 구현하는 부분입니다. Business layer에서 필요한 데이터를 생성, 수정, 읽기 등을 처리하여 실제로 데이터베이스에서 데이터를 저장, 수정, 읽어 들이기를 하는 역할을 합니다. + 다음과 같은 역할을 담당합니다. + + - Storage Logic + + + + +## 스프링 어노테이션 10개 이상 정리 + +1. `@SpringBootApplication` +: 스프링 부트 애플리케이션의 메인 클래스에 사용되며, 스프링의 가장 기본적인 설정을 자동으로 구성해주는 어노테이션으로, +`@Configuration`, `@EnableAutoConfiguration`, `@ComponentScan`을 포함한다. + +2. `@RestController` +: 트롤러 클래스를 RESTful 웹 서비스 컨트롤러로 지정합니다. `@Controller`와 `@ResponseBody`를 합친 어노테이션으로, JSON이나 XML 형태로 객체 데이터를 HTTP 응답 본문에 바로 매핑할 수 있게 해준다. + +3. `@RequestMapping` +: 요청 URL을 컨트롤러의 메서드와 매핑할 때 사용합니다. `@GetMapping`, `@PostMapping`, `@PutMapping`, `@DeleteMapping` 등의 구체적인 HTTP 메서드를 위한 어노테이션도 존재한다. + +4. `@Autowired` +: 스프링의 의존성 주입(Dependency Injection) 기능을 구현할 때 사용합니다. 스프링 컨테이너가 자동으로 선언된 빈(Bean)을 찾아서 주입해준다. + +5. `@Service` +: 서비스 클래스를 나타내며, 비즈니스 로직을 처리하는 클래스에 붙여 사용하고, 이 어노테이션은 주로 비즈니스 로직을 처리하는 서비스 클래스를 스프링 컨테이너에 빈으로 등록하는 데 사용한다. + +6. `@Repository` +: 데이터 접근 계층(DAO)의 클래스에 사용되며, 이 어노테이션을 사용함으로써 클래스가 데이터 접근 계층의 역할을 한다는 것을 스프링에게 알린다. 또한 데이터베이스 예외를 스프링의 데이터 접근 예외로 변환해준다. + +7. `@Entity` +: JPA(Java Persistence API)에서 엔티티 클래스를 나타내기 위해 사용되며, 데이터베이스 테이블과 매핑됩니다. + +8. `@Transactional` +: 메서드 또는 클래스에 트랜잭션 관리를 적용할 때 사용합니다. 선언적 트랜잭션 관리에 사용되며, 해당 어노테이션이 붙은 메서드나 클래스에서 데이터베이스 트랜잭션이 자동으로 관리한다. + +9. `@NoArgsConstructor` +: 파라미터가 없는 디폴트 생성자를 자동으로 생성하고, 이 어노테이션을 사용하면, 클래스에 명시적으로 선언된 생성자가 없더라도 인스턴스를 생성할 수 있다. + +10. `@AllArgsConstructor` +: 클래스의 모든 필드 값을 파라미터로 받는 생성자를 자동으로 생성한다. 이 어노테이션을 사용하면, 클래스의 모든 필드를 한 번에 초기화할 수 있다. + + +## Postman 설치해오기 + +네. 확인했습니다. From 3f06d27274da78beb2a8bcddcb7f6fc6066fb598 Mon Sep 17 00:00:00 2001 From: starshape77 <111961655+starshape7@users.noreply.github.com> Date: Tue, 7 May 2024 15:44:00 +0900 Subject: [PATCH 38/56] =?UTF-8?q?7=EC=A3=BC=EC=B0=A8=20=EA=B3=BC=EC=A0=9C?= =?UTF-8?q?=20=EC=A0=9C=EC=B6=9C?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- week02/starshape77.md | 29 +---- .../\354\266\224\354\227\260\354\232\260.md" | 123 ++++++++++++++++++ 2 files changed, 125 insertions(+), 27 deletions(-) create mode 100644 "week07/\354\266\224\354\227\260\354\232\260.md" diff --git a/week02/starshape77.md b/week02/starshape77.md index 9f588f0..0752116 100644 --- a/week02/starshape77.md +++ b/week02/starshape77.md @@ -8,37 +8,12 @@ → 다형성을 이용하여 구현 -구현기능 : 계좌 생성, 출금, 입금, 송금 ( BigDecimal 데이터 타입 ) - -**계좌 클래스 설계와 구현** - -1. 계좌(일반 예금 계좌)에는 일반 예금 계좌와 적금 계좌가 있습니다. 계좌 클래스의 속성은 계좌종류(N: 예금계좌, S:적금계좌), 계좌번호, 소유자, 잔액, 활성화 여부 다섯 가지 입니다. -2. 적금 계좌 클래스는 일반 예금 계좌 클래스에서 상속을 받고 목표 금액 속성이 추가 됩니다. -3. 일반 예금 계좌 클래스의 각 속성에 getter/setter를 제공하고, 계좌 정보를 보여주는 getAccountInfo() 메서드를 구현합니다. 적금 계좌 클래스는 이 메서드를 재정의 하여 목표 금액 정보도 보여주도록 합니다. -4. 뱅크 클래스에서 호출할 출금, 입금 기본 메서드를 생성합니다. - -**뱅크 클래스 설계와 구현** - -1. 계좌 클래스에서 구현한 기본 클래스를 이용하여 계좌생성, 출금, 입금, 송금 메서드를 구현합니다. 메서드 내부적으로 입력값을 받는 액션이 있습니다. -2. 적금 계좌는 적금 계좌는 잔액이 목표 금액(%s원) 이상이어야 출금 가능하도록 상속받은 출금 메서드를 조금 다르게 구현해줍니다. - -**인터페이스 설계와 구현** - -1. 일반 예금 계좌와 적금 계좌의 이자율 정책은 다릅니다. (여기서의 이자 계산은 잔액의 x%를 추가로 제공해주는 것으로 한정합니다. 현실세계의 포인트 개념과 비슷합니다.) 일반 예금 계좌인 경우 1000만원 이상은 이자율이 50%, 500만원 이상은 7%, 100만원 이상은 4%, 1만원 이상은 2%, 그 외에는 1% 이자를 제공해줍니다. 적금 계좌의 경우 100만원 이상은 이자율이 50%, 그 외에는 1% 이자를 제공해줍니다. -2. 각 할인 정책을 구현하기 위해 InterestCalculator 인터페이스에 계좌 잔액에 대한 이자금액을 반환하는 메서드(BigDecimal getInterest(balance))를 선언하고, 이를 구현한 일반 예금 계좌 이자 계산 정책과 적금 계좌에 대한 이자 계산 정책 클래스를 만듭니다. - -**계좌 관리를 위한 컬렉션 프레임 워크 사용하기** - -1. 모든 계좌를 관리하기 위한 중앙은행 클래스를 만듭니다. 계좌를 배열에 관리하기 위해 ArrayList를 활용합니다. -2. 계좌별 이자 정책을 관리하기 위해 HashMap을 활용하고, key에 category, value에 각 category의 InterestCalculator 인스턴스 를 담습니다. - -**예외 처리** +구현기능 : 계좌 생성, 출금, 입금, 송금, 전체 계좌정보 출력, 해당 계좌 이자율 출력, 각각의 계좌에 이자 넣기 1. 입금할 금액을 적으라고 했는데 한글로 입력할 경우 2. 없는 계좌로 송금, 입금, 출금을 시도할 경우 3. 계좌 생성 시 계좌 형식에 알맞지 않는 경우 -> 계좌 번호 형식 ( 00000-00-00000 ) // 정규표현식 사용 -4. 계좌 생성 시 목표 금액을 현재 금액보다 낮게 설정하는 경우 -4. +4. 적금 계좌 생성 시 목표 금액을 현재 금액보다 낮게 설정하는 경우 ## BigDecimal diff --git "a/week07/\354\266\224\354\227\260\354\232\260.md" "b/week07/\354\266\224\354\227\260\354\232\260.md" new file mode 100644 index 0000000..187866d --- /dev/null +++ "b/week07/\354\266\224\354\227\260\354\232\260.md" @@ -0,0 +1,123 @@ +# 7주차 과제 - Spring 사전 조사 + +--- + +## 스프링의 장점 / 사용 이유 + +- POJO(Plain Old Java Object) 기반의 구성 + - 개발을 할 때에 개발자가 특정한 라이브러리나 컨테이너의 기술에 종속적이지 않고 개발이 가능하다. + - Java 코드를 이용해서 객체를 구성하는 방식 그대로 스프링에서 이용 가능 +- DI(Dependency Indection, 의존성 주입)를 통한 객체 관계 구성 + - 의존성 주입은 필요한 객체를 외부에서 결정하여 연결시키는 것을 말함 + - Java에서는 인터페이스를 사용하여 이를 처리 + - 의존성 주입의 특징으로 인해 개발자가 POJO 개발이 가능해짐 + - 의존성 주입 방식 + - 필드 주입 + - setter 주입 + - 생성자 주입 (권장) + - 권장 이유 + - 순환 의존성 확인 : 필드 주입으로는 순환 의존성 파악 어려움 + - 불변성 : 필드 주입은 Final 선언이 불가하지만, 생성자 주입은 Final 선언이 가능하여 불변성을 보장할 수 있다. + - 단일 책임 원칙 확인 +- AOP(Aspect Oriented Programming, 관점 지향 프로그래밍) 지원 + - AOP를 통해 반복적인 코드를 줄이고 개발자가 핵심 기능 구현에만 집중할 수 있도록 지원 + +- 위처럼 프로그래밍하면 시간 측정 로직을 수정해야하면 모든 로직을 찾아가서 일일이 수정해야하는 번거로움이 생긴다. + +- 이렇게 AOP를 사용하여 공통으로 들어가는 로직을 분리하면 해당 로직만 수정하면 됨 + +- IoC(Inversion of Control) 지원 + - IoC는 객체의 생성과 생명 주기를 관리해주기 때문에 개발자는 의존성 관리에 신경 쓸 필요 없이 핵심 기능 구현에만 집중 가능 +- MVC(Model - View - Controller) 구조 + - Model : 프로그램의 데이터이며 모든 데이터를 가공하여 가지고 있는 컴포넌트 + - View : 시각적인 UI 요소를 지칭하는 용어 + - Controller : Model과 View를 연결하는 역할을 수행 +- WAS(Web Application Server)에 독립적인 개발 환경 + - 일반 웹 서버는 정적인 데이터를 처리하는 서버로 단순 이미지 HTML을 처리하는 서버이지만 WAS는 동적인 데이터를 처리하는 서버로, DB연동 데이터 조작 등과 같은 처리가 가능 + +## 싱글톤, 싱글톤 컨테이너 + +- 싱글톤 : Class의 인스턴스가 딱 1개만 생성되는 것을 보장하는 디자인 패턴 +- 싱글톤 필요 이유 + - 웹 애플리케이션의 이용량이 많아지면 스프링 컨테이너에서는 객체들이 이용량 횟수 만큼 생성되어야함. → 굉장히 비효율적, 메모리낭비 + - 이러한 문제를 해결하기 위해 싱글톤 패턴을 사용하여 하나의 객체를 재사용하여 메모리 낭비를 줄임 +- 문제점 + - 구현해야할 코드의 양이 늘어남 + - DIP를 위반하게 됨 → 클라이언트가 구현체에 의존 + - 내부 속성을 변경하거나 초기화하기 어렵다 + - Private 생성자이기 때문에 자식 클래스를 만들기 어렵다 +- 싱글톤 컨테이너 : 스프링의 컨테이너는 객체 인스턴스를 싱글톤으로 관리하는 싱글톤 컨테이너의 역할 수행 → 싱글톤의 단점 해결하고 장점만 가져감. + - 스프링 컨테이너는 싱글톤 패턴을 적용하지 않아도 싱글톤으로 객체들을 관리 + - 스프링 컨테이너는 싱글톤 컨테이너의 역할을 수행 → 싱글톤 레지스트 + - 각각의 Bean들은 싱글톤 패턴 적용을 위한 코드 작성 필요 X +- 주의점 + - 싱글톤 패턴에서는 객체의 인스턴스를 하나만 생성하여 공유하기 때문에 여러 클라이언트에서 해당 인스턴스를 공유 + - 위의 이류로 객체가 상태를 유지하는 stateful 상태이면 문제가 발생 → stateless 상태로 객체 설계 필요 + - 방법 + - 특정 클라이언트에 의존적인 필드가 없어야함 + - 특정 클라이언트가 값을 변경할 수 있는 필드가 존재하면 안됨 + - 가급적 읽기만 가능해야함 + +## 레이어드 아키텍쳐 패턴 + +- 정의 + - 소프트웨어 시스템을 관심사 별로 여러 개의 계층으로 분리한 아키택처를 의미 + - 각 계층은 애플리케이션 내에서 특정 역할과 책임 존재 → 각자의 역할에만 집중해야함 && 구성 요소간의 관심사 분리 +- 구성 요소들은 추상화된 인터페이스로만 소통함 → 자신보다 하위 계층에만 요청 가능(상위 계층이나 인접하지 않는 계층에는 요청 X) → 단방향 의존성 +- 가장 일반적인 레이어드 아키텍쳐 + - 4 - tier 아키텍쳐 + + + - Presentation Layer + → 사용자 혹은 클라이언트 시스템과 직접적으로 연결되는 부분 + - Business Layer + → 비즈니스 로직을 구현하는 부분. 실제로 시스템이 구현해야하는 핵심 로직 담당 + - Persistence Layer + →데이터의 영구 저장과 관리를 담당하는 부분 + - Database Layer + → 실제 DB + + +- 레이어드 아키텍처 Close + - 계층간 요청이 이동할 때 인접한 계층을 통과하는 것 → 계층을 뛰어넘어서 접근 불가 + - 관심사의 분리를 위해서 → 한 계층에서 변경이 발생했을 때 다른 계층에 영향 최소화 +- 레이어드 아키텍처 Open + - 특정 요청에만 추가적인 계층이 필요한 경우 이 계층을 Open하여 필요한 경우에 사용하고 아닌 경우에는 우회할 수 있도록 함. +- 레이어드 아키텍처 장단점 + - 장점 + - 계층별로 분리되어 코드의 재사용성과 유지보수성 증가 + - 각 계층이 독립적으로 개발, 확정, 변경 가능 + - 테스트에 용이하다 + - 단점 + - 계층간 통신을 통해 동작하여 데이터의 전달 및 변환 과정에서 일부 오버헤드가 발생 + - 계층 간 통신을 위한 인터페이스와 로직을 추가해야하므로 복잡성이 증가함 + +## 스프링 어노테이션 10개 이상 정리 + +- @Component + - 생성한 class를 Spring의 Bean으로 등록할 때 사용 +- @Controller + - Spring에서 해당 Class가 Controller의 역할을 한다고 명시하기 위해 사용 +- @RequestMapping(value = “”) + - 요청 들어온 URL의 요청과 Annotaion value값이 일치하면 해당 클래스나 메소드를 실행 + - Controller 객체 안의 메소드와 클래스에 적용 가능 +- @RequestParam + - URL에 전달되는 파라미터를 메소드의 인자와 매칭시켜 파라미터를 받아서 처리할 수 있게 만들어줌 + - JSON 형식의 Body를 MessageConverter를 통해 Java 객체로 변환 +- @RequestBody + - 클라이언트가 보내는 HTTP 요청 본문을 Java 오브젝트로 변환 + - 클라이언트가 Body에 JSON이나 XML과 같은 형태로 값을 전송하면 이를 Java Object로 변환 +- @Autowired + - Spring Framework에서 Bean 객체를 주입받기 위해 사용 + - 주입 방식 + - @Autowired + - 생성자 주입 + - setter 사용 +- @GetMapping + - RequestMapping(Method=RequestMethod.GET)과 똑같은 역할 +- @PostMapping + - RequestMapping(Method=RequestMethod.POST)과 똑같은 역할 +- @Setter + - Class 모든 필드의 Setter Method 생성 +- @Getter + - Class 모든 필드의 Getter Method 생성 \ No newline at end of file From 7eb101fd2e13ab46497b89b03e80bf2bc184d94f Mon Sep 17 00:00:00 2001 From: starshape77 <111961655+starshape7@users.noreply.github.com> Date: Tue, 7 May 2024 15:50:22 +0900 Subject: [PATCH 39/56] =?UTF-8?q?7=EC=A3=BC=EC=B0=A8=20=EA=B3=BC=EC=A0=9C?= =?UTF-8?q?=20=EC=88=98=EC=A0=95=5F=EC=9D=B4=EB=AF=B8=EC=A7=80=20=EC=B6=94?= =?UTF-8?q?=EA=B0=80?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- "week07/\354\266\224\354\227\260\354\232\260.md" | 10 +++++----- 1 file changed, 5 insertions(+), 5 deletions(-) diff --git "a/week07/\354\266\224\354\227\260\354\232\260.md" "b/week07/\354\266\224\354\227\260\354\232\260.md" index 187866d..c00b061 100644 --- "a/week07/\354\266\224\354\227\260\354\232\260.md" +++ "b/week07/\354\266\224\354\227\260\354\232\260.md" @@ -21,10 +21,10 @@ - 단일 책임 원칙 확인 - AOP(Aspect Oriented Programming, 관점 지향 프로그래밍) 지원 - AOP를 통해 반복적인 코드를 줄이고 개발자가 핵심 기능 구현에만 집중할 수 있도록 지원 - -- 위처럼 프로그래밍하면 시간 측정 로직을 수정해야하면 모든 로직을 찾아가서 일일이 수정해야하는 번거로움이 생긴다. - -- 이렇게 AOP를 사용하여 공통으로 들어가는 로직을 분리하면 해당 로직만 수정하면 됨 + ![스크린샷 2024-05-07 145836](https://github.com/COW-edu/COW-Spring-3/assets/111961655/566c411f-0b62-4b98-8260-146802492c08) + - 위처럼 프로그래밍하면 시간 측정 로직을 수정해야하면 모든 로직을 찾아가서 일일이 수정해야하는 번거로움이 생긴다. + ![스크린샷 2024-05-07 145946](https://github.com/COW-edu/COW-Spring-3/assets/111961655/23ab95ff-986e-4d3c-b16d-92ce303ccf7f) + - 이렇게 AOP를 사용하여 공통으로 들어가는 로직을 분리하면 해당 로직만 수정하면 됨 - IoC(Inversion of Control) 지원 - IoC는 객체의 생성과 생명 주기를 관리해주기 때문에 개발자는 의존성 관리에 신경 쓸 필요 없이 핵심 기능 구현에만 집중 가능 @@ -67,7 +67,7 @@ - 가장 일반적인 레이어드 아키텍쳐 - 4 - tier 아키텍쳐 - +![스크린샷 2024-05-07 152753](https://github.com/COW-edu/COW-Spring-3/assets/111961655/44ec3406-adb6-4343-a0cc-662466384f78) - Presentation Layer → 사용자 혹은 클라이언트 시스템과 직접적으로 연결되는 부분 - Business Layer From 40f1c1df3ab55305fd4bc2f0b948719d644c9169 Mon Sep 17 00:00:00 2001 From: fuirian Date: Tue, 7 May 2024 18:19:35 +0900 Subject: [PATCH 40/56] =?UTF-8?q?=EA=B9=80=EB=AF=BC=EC=A7=84.md?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .../\352\271\200\353\257\274\354\247\204.md" | 199 ++++++++++++++++++ 1 file changed, 199 insertions(+) create mode 100644 "week07/\352\271\200\353\257\274\354\247\204.md" diff --git "a/week07/\352\271\200\353\257\274\354\247\204.md" "b/week07/\352\271\200\353\257\274\354\247\204.md" new file mode 100644 index 0000000..e5895b3 --- /dev/null +++ "b/week07/\352\271\200\353\257\274\354\247\204.md" @@ -0,0 +1,199 @@ +# 7주차 과제-Spirng 사전 조사 + +## 스프링의 장점/사용 이유 + +### 스프링 + +- JAVA의 웹 프레임워크로 JAVA 언어를 기반으로 사용한다. JAVA로 다양한 어플리케이션을 만들기 위한 프로그래밍 틀이며, JAVA 기술들을 더 쉽게 사용할 수 있게 해주는 오픈소스 프레임워크이다. +- 엔터프라이즈용 JAVA 애플리케이션 개발을 편하게 할 수 있게 해주는 오픈소스 경량급 애플리케이션 프레임워크이다. + +### 사용 이유 + +- POJO기반의 구성 + - 코드를 개발할 때, 개발자가 특정한 라이브러리나 컨테이너의 기술에 종속적이지 않음을 의미한다. JAVA 코드를 이용해서 객체를 구성하는 방식 그대로 스프링에서 사용할 수 있다. + - 개발자는 가장 일반적인 형태로 코드를 작성하고 실행할 수 있다. 때문에 높은 생산성과 유연한 테스트를 할 수 있다는 장점을 가지고 있다. +- DI를 통한 객체 관계 구성 + - 메소드나 객체의 호출 작업은 제어의 역전을 통해 외부에서 이루어진다. + - 제어의 역행을 전제 조건으로 의존성 주입이 일어난다. + - 의존성을 가진 객체에 대해 스프링에서 의존성 주입이 발생하도록 한다. + - 의존성 주입 특징으로 인해 개발자가 POJO 개발이 가능하게 된다. + - 의존성 주입 방법 + - 필드 주입 + - setter 주입 + - 생성자 주입(권장) + - 생성자 주입을 권장하는 이유 + - 순환 의존성 확인: 필드 주입으로는 순환 의존성을 파악하기 어렵다. 생성자 주입을 하게 되면 서버 기동 시 순환 의존성을 가지는 요소들을 파악하게 할 수 있게 에러메시지를 표시하면서 서버 기동이 되지 않는다. + - 불변성: 필드 주입은 final을 선언할 수 없지만 생성자 주입은 final을 선언함으로써 객체가 변하지 않도록 방지해준다. + - 단일 책임 원칙 위반 확인 +- AOP 지원 + - 코드의 관심사를 분리하고 모듈화하는 프로그래밍 기법이다. + - 로깅, 보안, 트랜잭션과 같은 코드의 횡단 관심사를 따로 분리하여 관리한다. + - 각 관심사를 독립적으로 개발하고 유지보수할 수 있어 코드의 가독성과 유지 보수성을 향상시킨다. + +### 장점 + +- 웹 시스템, 웹 서비스를 비롯해 클라우드 애플리케이션, 모바일 시스템 등 다양한 개발에 적합하다. 기능 확장성이 뛰어난 SPRING은 대규모 개발이나 세부 사양 변경에도 유연하게 대응이 가능하다. +- 프레임워크이기 때문에, 개발자의 수준과 실력에 상관없이 일정 수준의 품질을 기대할 수 있다. 담당자 혹은 개발자가 도중에 바뀌더라도, 유지보수에 관한 리스크를 줄일 수 있다. + +## **싱글톤, 싱글톤 컨테이너** + +### 싱글톤 + +- 싱글톤 패턴은 특정 클래스의 인스턴스를 1개만 생성되는 것을 보장하는 디자인 패턴이다. 즉, 생성자를 통해서 여러 번 호출이 되더라도 인스턴스를 새로 생성하지 않고 최초 호출 시에 만들어두었던 인스턴스를 재활용하는 패턴이다. +- 싱글톤 패턴을 사용함으로써 얻을 수 있는 이점 중 하나는 메모리 낭비를 방지할 수 있다. +- 사용자가 1초에 10번 똑같은 요청을 보내면 요청을 처리하기 위한 똑같은 객체를 1초에 10번 생성하고 소멸되는 메모리 낭비 문제가 발생하게 된다. 하지만 싱글톤 패턴을 사용하면 최초 한 번 `new`로 객체를 생성하고 해당 객체를 이후에도 사용하도록 공유하면 메모리 낭비를 방지할 수 있다. + +### 싱글톤 컨테이너 + +- 스프링 컨테이너는 싱글톤 패턴을 적용하지 않아도, 객체 인스턴스를 싱글톤으로 관리한다. +- 스프링 컨테이너는 싱글톤 컨테이너 역할을 한다. 이렇게 싱글톤 객체를 생성하고 관리하는 기능을 **싱글톤 레지스트리**라고 한다. +- 스프링 컨테이너의 이러한 기능 덕분에 싱글톤 패턴의 모든 단점을 해결하면서 객체를 싱글톤으로 유지할 수 있다. + - 싱글톤 패턴을 위한 지저분한 코드가 들어가지 않아도된다. + - DIP, OCP, 테스트, private 생성자로부터 자유롭게 싱글톤을 사용할 수 있다. +- 스프링 컨테이너 덕분에 고객의 요청이 올 때마다 객체를 생성하는 것이 아니라, 이미 만들어진 객체를 공유해서 효율적으로 재사용할 수 있다. + +## **레이어드 아키텍쳐 패턴** + +- 레이어드 아키텍처는 많은 분야에서 사용되는 아키텍처이다. +- 이름 그대로 여러 레이어를 분리하여 레이어마다 해야 할 역할을 정의해놓은 구조이다. + +![https://user-images.githubusercontent.com/79494088/175446442-f3998d69-2e77-4b08-a9b7-8deacb6bd2ff.png](https://user-images.githubusercontent.com/79494088/175446442-f3998d69-2e77-4b08-a9b7-8deacb6bd2ff.png) + +- 대표적인 레이어드 아키텍처인 4 계층(4 Layered) 아키텍처의 각 레이어를 정리하면 아래와 같다. +- 프레젠테이션 레이어 + - 인터페이스와 애플리케이션이 연결되는 곳이다. + - 웹 통신 프레임워크, CLI 등 인터페이스, 입출력의 변환 등 외부와의 통신을 담당한다. +- 애플리케이션 레이어 + - 소프트웨어가 제공하는 주요 기능(비즈니스 로직)을 구현하는 코드가 모이는 곳이다. + - 로직을 오케스트레이션하고, 트랜잭션의 시작과 끝을 담당한다. +- 도메인 레이어 + - 도메인과 관련된 객체들이 모이는 곳이다. + - 도메인 모델(엔티티, 값 객체), 도메인 서비스 등 도메인 문제를 코드로 풀어내는 일을 담당한다. +- 인프라스트럭처 레이어 + - 다른 레이어을 지탱하는 기술적 기반을 담은 객체들이 모이는 곳이다. + - DB와의 연결, ORM 객체, 메시지 큐 등 애플리케이션 외적인 인프라들과의 어댑터 역할을 담당한다. +- 레이어드 아키텍처는 의존성의 방향이 다음처럼 흐른다. + - 프레젠테이션 레이어 -> 애플리케이션 레이어 -> 도메인 레이어 -> 인프라스트럭처 레이어 +- 즉 프레젠테이션 레이어에 있는 코드는 애플리케이션 레이어에 있는 코드에 의존해야 한다. +- 그 반대인 애플리케이션 레이어 코드가 프레젠테이션 레이어에 있는 코드에 의존하면 안된다. +- 이처럼 의존성의 흐름은 항상 프레젠테이션 레이어에서 인프라스트럭쳐 레이어로 흘러야한다. +- 위는 4개의 레이어로 구성한 예이고, 3개의 레이어로 구성할 수도 있다. +- 3 레이어의 경우 보통 다음처럼 구성한다. + - 프레젠테이션 레이어 -> 애플리케이션 레이어 -> 데이터 접근 레이어 + +## **스프링 어노테이션 10개 이상 정리** + +### @SpringBootApplication + +- Srping Boot를 자동으로 실행시켜주는 어노테이션으로 Bean 등록은 두 단계로 진행된다. + - `@ComponentScan`을 통해 Component들을 Bean으로 등록한다. + - `@EnableAutoConfiguration`을 통해 미리 정의해둔 자바 설정 파일들을 Bean으로 등록한다.(Bean은 스프링 IoC 컨테이너에 의해 인스턴스화되어 조립되거나 관리되는 객체) + +### @Configuration + +- 스프링 IoC Container에게 해당 클래스가 Bean 구성 Class임을 알려주는 어노테이션이다. +- `@Bean`을 해당 클래스의 메소드에 적용하면 `@Autowired`로 빈을 부를 수 있다. + +### @EnableAutoConfiguration + +- Spring Application Context를 만들 때 자동으로 설정하는 기능을 켠다. +- classpath의 내용에 기반해서 자동 생성해 준다. +- 만약 tomcat-embed-core.jar가 존재하면 톰캣 서버가 setting된다. + +### @ComponentScan + +- `@Component`, `@Service`, `@Repository`, `@Controller`, `@Configuration`이 붙은 빈들을 찾아서 +- Context에 빈을 등록해 주는 어노테이션이다. +- `@Component` 어노테이션이 있는 클래스에 대하여 bean 인스턴스를 생성한다. +- Spring에서 `@Component`로 다 쓰지 않고 `@Repository`, `@Service`, `@Controller`등을 사용하는 이유는, 예를들어 `@Repository`는 DAO의 메소드에서 발생할 수 있는 unchecked exception들을 스프링의 DataAccessException으로 처리할 수 있기 때문이다. +- 또한 가독성에서도 해당 애노테이션을 갖는 클래스가 무엇을 하는지 단 번에 알 수 있다. + +### @Component + +- 개발자가 직접 작성한 Class를 Bean으로 등록하기 위한 어노테이션이다. +- `@ComponentScan`선언에 의해 특정 패키지 안의 클래스들을 자동 스캔하여 `@Component` 어노테이션이 있는 클래스들에 대하여 Bean 인스턴스를 생성한다. + +```java +@Component +public class Student { + public Stdudent() { + System.out.println("hello"); + } +} + +@Component(value="mystudent") +public class Student { + public Stdudent() { + System.out.println("hello"); + } +} +``` + +- Component에 대한 추가 정보가 없다면 Class의 이름을 camelCase로 변경한 것이 Bean id로 사용된다. 하지만 `@Bean`과 다르게 `@Component`는 name이 아닌 value를 이용해 Bean의 이름을 지정한다. + +### @Bean + +- `@Bean`은 개발자가 직접 제어가 불가능한 외부 라이브러리 등을 Bean으로 만들 때 사용되는 어노테이션이다. + +```java +@Configuration +public class ApplicationConfig { + @Bean + public ArrayList array() { + return new ArrayList(); + } +} +``` + +- ArrayList같은 라이브러리등을 Bean으로 등록하기 위해서는 별도로 해당 라이브러리 객체를 반환하는 Method를 만들고 `@Bean`을 사용하면 된다. 위의 경우 `@Bean`에 아무런 값을 지정하지 않았으므로 Method 이름을 camelCase로 변경한 것이 Bean id로 등록된다. +- 메소드가 `arrayList()`인 경우 arrayList가 Bean id가 된다. +- `@Bean`에 name이라는 값을 이용하면 원하는 id로 Bean을 등록할 수 있다. + +### @Autowired + +- 필드, setter 메소드, 생성자에 사용하며 Type에 따라 알아서 Bean을 주입해주는 역할을 한다. +- 객체에 대한 의존성을 주입시킨다. +- `@Autowired`을 사용하면 스프링이 자동적으로 값을 할당한다. +- Controller 클래스에서 DAO나 Service에 관한 객체들을 주입 시킬 때 많이 사용한다. + +### Bean을 주입받는 방식(3가지) + +1. `@Autowired` +2. setter +3. 생성자: `@AllArgsConstructor` 사용, 스프링에서는 생성자를 통한 방식을 권장한다. + +### @Controller + +- Spring MVC의 Controller로 사용되는, 클래스 선언을 단순화 시켜주는 어노테이션이다. + +### @RestController + +- Spring에서 Controller 중 View로 응답하지 않는 Controller를 의미한다. +- method의 반환 결과를 JSON 형태로 반환한다. +- `@RestController`가 적혀있는 Controller의 method는 HttpResponse로 바로 응답이 가능하다. +- `@ResponseBody` 역할을 자동적으로 해주는 어노테이션이다. +- @Controller와 @RestController의 차이점 + - @Controller + - API와 view를 동시에 사용하는 경우에 사용한다. + - 대신 API 서비스로 사용하는 경우는 `@ResponseBody`를 사용하여 객체를 반환한다. + - `view` return이 주목적이다. + - @RestController + - view가 필요없는 API만 지원하는 서비스에서 사용한다. + - `@RequestMapping` 메서드가 기본적으로 `@ResponseBody` 의미를 가정한다. + - @RestController  =  @Controller  +  @ResponseBody + +### @Service + +- Service class에서 쓰이는 어노테이션으로, 비즈니스 로직을 수행하는 Class라는 것을 나타내는 용도이다. + +### @Repository + +- DAO class에서 쓰이는 어노테이션이다. +- DB에 접근하는 method를 가지고 있는 Class에서 쓰인다. + +### @Resource + +- `@Autowired`와 마찬가지로 Bean 객체를 주입해주는데 차이점은 Autowired는 타입으로, Resource는 이름으로 연결해준다. +- 어노테이션 사용으로 인해 특정 Framework에 종속적인 어플리케이션을 구성하지 않기 위해서는 `@Resource`를 사용할 것을 권장한다. +- `@Resource`를 사용하기 위해서는 class path 내에 jsr250-api.jar 파일을 추가해야 한다. +- 필드, 입력 파라미터가 1개인 bean property setter method에 적용 가능하다. \ No newline at end of file From dbdf932cdc141f3efaeebe117ddaa3b8afc125a5 Mon Sep 17 00:00:00 2001 From: jinhyeon Date: Tue, 7 May 2024 18:24:00 +0900 Subject: [PATCH 41/56] =?UTF-8?q?docs:7=EC=A3=BC=EC=B0=A8=20=EA=B3=BC?= =?UTF-8?q?=EC=A0=9C=20=EC=A0=9C=EC=B6=9C?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .../\353\260\225\354\247\204\355\230\204.md" | 65 +++++++++++++++++++ 1 file changed, 65 insertions(+) create mode 100644 "week07/\353\260\225\354\247\204\355\230\204.md" diff --git "a/week07/\353\260\225\354\247\204\355\230\204.md" "b/week07/\353\260\225\354\247\204\355\230\204.md" new file mode 100644 index 0000000..78f4964 --- /dev/null +++ "b/week07/\353\260\225\354\247\204\355\230\204.md" @@ -0,0 +1,65 @@ +### **스프링의 장점 / 사용 이유** + +스프링은 자바를 기반으로 하는 프레임 워크로 다음과 같은 특징을 통해 더욱 편한 개발이 가능하도록 한다. + +1. **POJO(Plain Old Java Object)기반의 구성** + - 특정 라이브러리나 컨테이너의 환경과 기술에 종속되지 않고 자바 코드를 이용하여 객체를 구성하는 방식 그대로 스프링에서 사용할 수 있기에 객체지향적 원리에 충실 할 수 있다. +2. **DI(의존성 주입)** + - 제어의 역전이 일어나는 것을 전제로 스프링 내부의 객체들 간의 관계를 관리할때 사용 + - 객체간의 결합도를 낮춰 개발자는 코드의 재사용성을 높일 수 있다. +3. AOP 지원 + - 스프링은 AOP를 통해 반복적인 코드를 줄이고 핵심적 비즈니스 로직에 집중할 수 있도록 해준다. + + --- + + +### **싱글톤, 싱글톤 컨테이너** + +1. **싱글톤 패턴** + - 객체 지향 프로그램밍에서 하나의 클래스에 대해 전역에서 단 하나의 인스턴스만 생성되도록 제한하는 디자인 패턴 + - 해당 클래스의 인스턴스가 프로그램에 전반에 걸쳐 사용되어야 할 경우 사용 + - 어디서든 접근 가능하고, 인스턴스가 한번만 생성되기에 메모리 낭비를 방지하고 성능이 향상된다. +2. **싱글톤 컨테이너** + - 싱글톤 컨테이너는 싱글톤 인스턴스의 생성과 관리를 담당한다. + - 스프링 프레임워크에서는 스프링 컨테이너가 이 역할을 수행한다 + - 직접 싱글톤 패턴을 구현할 필요없이 스프링 컨테이너가 빈(Bean)으로 등록된 클래스에 대해 싱글톤 인스턴스를 자동으로 생성하고 관리한다. + + +--- + +### 레이어드 아키텍쳐 패턴 + +- 애플리케이션을 관심사별 계층(layer)으로 분리하여 계층마다 해야 할 책임과 역할을 정의해놓은 구조이다. +- 구성 요소간 관심사가 분리 되어 있으며 추상화된 인터페이스로만 소통한다. +- 소프트웨어의 유지 보수성, 확장성 및 재사용성을 향상시킨다. + +**주요 계층** + +- **프레젠테이션 계층 (Presentation Layer)** + - 인터페이스와 애플리케이션이 연결 되는 곳 + - 사용자 인터페이스(UI)와 사용자 경험(UX)을 관리 +- **비즈니스 로직 계층 (Business Logic Layer)** + - **애플리케이션의 핵심 기능과 규칙을 구현** + - **데이터의 가공, 계산 및 결정을 담당** +- **퍼시스턴스 계층(Persistence Layer)** + - 데이터의 영구 저장과 관리를 담당 + - 웹 어플리케이션의 데이터베이스와의 상호작용을 처리 + - 데이터 베이스와의 상호작용을 추상화 +- **데이터베이스 계층(Database Layer)** + - 데이터 관리와 접근을 담당하는 부분 + + +--- + +### 스프링 어노테이션 10개이상 정리 + +- **@Autowired**: 의존성 주입을 위해 사용. 생성자, 필드, 메서드에 사용 할 수 있으면, 스프링이 자동으로 의존성 주입 +- **@SpringBootTest:** Spring Boot Test에 필요한 의존성을 제공 +- **@Component**: 작접 작성한 클래스를 스프링 빈으로 등록할 때 사용 +- **@Configuration**: 해당 클래스가 스프링 설정 정보를 담고 있는 클래스임을 나타냄. 이 클래스 내부에서 @Bean 어노테이션을 사용하여 스프링 컨테이너에 빈을 등록할 수 있다. +- **@Bean**: @Configuration 어노테이션이 붙은 클래스 내 메서드에 사용되며, 해당 메서드가 반환하는 객체를 스프링 컨테이너에 빈으로 등록 +- **@Service**: 비즈니스 로직을 처리하는 서비스 계층 클래스에 붙임 +- **@Controller**: 프링 프레임워크의 웹 애플리케이션에서 컨트롤러 역할을 하는 클래스에 붙임 +- **@Repository:** 영속성 계층, 특히 데이터베이스 작업을 수행하는 클래스에 사용 +- **@RequestMapping:** 요청 URL을 컨트롤러의 메서드와 매핑 +- **@RequestParam**: URL에 전달되는 파라미터를 메소드의 인자와 매칭시켜, 파라미터를 받아서 처리 \ No newline at end of file From edd5ca6547aafd89799c6ac2f0a84877bd8e2309 Mon Sep 17 00:00:00 2001 From: jinhyeon Date: Tue, 7 May 2024 18:26:27 +0900 Subject: [PATCH 42/56] =?UTF-8?q?docs:7=EC=A3=BC=EC=B0=A8=20=EA=B3=BC?= =?UTF-8?q?=EC=A0=9C=20=EC=A0=9C=EC=B6=9C?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- "week07/\353\260\225\354\247\204\355\230\204.md" | 3 +++ 1 file changed, 3 insertions(+) diff --git "a/week07/\353\260\225\354\247\204\355\230\204.md" "b/week07/\353\260\225\354\247\204\355\230\204.md" index 78f4964..b6a9d22 100644 --- "a/week07/\353\260\225\354\247\204\355\230\204.md" +++ "b/week07/\353\260\225\354\247\204\355\230\204.md" @@ -1,3 +1,6 @@ +# 7주차 과제 - Spring 사전 조사 + +--- ### **스프링의 장점 / 사용 이유** 스프링은 자바를 기반으로 하는 프레임 워크로 다음과 같은 특징을 통해 더욱 편한 개발이 가능하도록 한다. From 5080855227aa07289412594852a3386e882cbf3b Mon Sep 17 00:00:00 2001 From: fuirian Date: Tue, 7 May 2024 18:28:55 +0900 Subject: [PATCH 43/56] =?UTF-8?q?=EC=B6=94=EA=B0=80=20=EC=88=98=EC=A0=95?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .../\352\271\200\353\257\274\354\247\204.md" | 30 ++++++++++++++----- 1 file changed, 23 insertions(+), 7 deletions(-) diff --git "a/week07/\352\271\200\353\257\274\354\247\204.md" "b/week07/\352\271\200\353\257\274\354\247\204.md" index e5895b3..ac3313b 100644 --- "a/week07/\352\271\200\353\257\274\354\247\204.md" +++ "b/week07/\352\271\200\353\257\274\354\247\204.md" @@ -155,12 +155,10 @@ public class ApplicationConfig { - 객체에 대한 의존성을 주입시킨다. - `@Autowired`을 사용하면 스프링이 자동적으로 값을 할당한다. - Controller 클래스에서 DAO나 Service에 관한 객체들을 주입 시킬 때 많이 사용한다. - -### Bean을 주입받는 방식(3가지) - -1. `@Autowired` -2. setter -3. 생성자: `@AllArgsConstructor` 사용, 스프링에서는 생성자를 통한 방식을 권장한다. +- Bean을 주입받는 방식(3가지) + 1. `@Autowired` + 2. setter + 3. 생성자: `@AllArgsConstructor` 사용, 스프링에서는 생성자를 통한 방식을 권장한다. ### @Controller @@ -196,4 +194,22 @@ public class ApplicationConfig { - `@Autowired`와 마찬가지로 Bean 객체를 주입해주는데 차이점은 Autowired는 타입으로, Resource는 이름으로 연결해준다. - 어노테이션 사용으로 인해 특정 Framework에 종속적인 어플리케이션을 구성하지 않기 위해서는 `@Resource`를 사용할 것을 권장한다. - `@Resource`를 사용하기 위해서는 class path 내에 jsr250-api.jar 파일을 추가해야 한다. -- 필드, 입력 파라미터가 1개인 bean property setter method에 적용 가능하다. \ No newline at end of file +- 필드, 입력 파라미터가 1개인 bean property setter method에 적용 가능하다. + +### @Getter + +- 자동으로 생성된 접근자와 설정자 메소드를 사용할 수 있어 매우 편리하다. +- 필드 레벨이 아닌 클래스 레벨에 @Getter 또는 @Setter를 선언해줄 경우, 모든 필드에 접근자와 설정자가 자동으로 생성된다. +- 자바 언어에서 속성의 값을 가져오는 메서드를 자동으로 생성하는 어노테이션이다. +- 클래스의 필드에 대한 getter 메서드를 명시적으로 작성하지 않고도 해당 필드의 값을 가져올 수 있다. + +### @AllArgsConstructor + +- 클래스의 모든 필드에 대한 생성자를 자동으로 생성한다. +- 클래스의 모든 멤버 변수를 매개변수로 받는 생성자를 자동으로 만들어 준다. +- 생성된 생성자를 통해 객체를 생성할 때, 각 필드에 대한 값을 인자로 전달할 수 있다. + +### @RequiredArgsConstructor + +- 클래스의 final 필드에 대한 생성자를 자동으로 생성한다. +- final 필드는 클래스에서 초기화를 하던지 객체 생성 시 생성자를 이용해 꼭 초기화해줘야한다. \ No newline at end of file From 15d16c575d5f4fac64068d13d1a3b97d8776574c Mon Sep 17 00:00:00 2001 From: ChoiTheCreator <147716165+ChoiTheCreator@users.noreply.github.com> Date: Tue, 7 May 2024 21:36:44 +0900 Subject: [PATCH 44/56] =?UTF-8?q?Delete=20=EC=B5=9C=EC=9B=90=EB=B9=88.md?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- "\354\265\234\354\233\220\353\271\210.md" | 4 ---- 1 file changed, 4 deletions(-) delete mode 100644 "\354\265\234\354\233\220\353\271\210.md" diff --git "a/\354\265\234\354\233\220\353\271\210.md" "b/\354\265\234\354\233\220\353\271\210.md" deleted file mode 100644 index c54bc9a..0000000 --- "a/\354\265\234\354\233\220\353\271\210.md" +++ /dev/null @@ -1,4 +0,0 @@ -멘토 형님의 조언을 듣고 주어진 문제형식이 아닌 제 스스로의 코드를 다시 짜봤습니다. 아직 부족한게 많아서 차차해 나갈 생각입니다. -일단 메인과 연동하여, 실행하면 로그인과 로그아웃을 할 수 있는 기능을 추가했습니다. -로그인이 성공한다면 그제야 입금 출금과 같은 기능을 사용 할 수 있게 했습니다. -아직 새 코드에는 예외처리하는 기능을 추가하지는 않았습니다. 그래서 따로 패키지에만 넣어놨습니다. From 6660840fb0538400618ad693187d9c64ba44eee9 Mon Sep 17 00:00:00 2001 From: ChoiTheCreator <147716165+ChoiTheCreator@users.noreply.github.com> Date: Tue, 7 May 2024 21:40:32 +0900 Subject: [PATCH 45/56] =?UTF-8?q?Delete=20=EC=B5=9C=EC=9B=90=EB=B9=88.md?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- "\354\265\234\354\233\220\353\271\210.md" | 4 ---- 1 file changed, 4 deletions(-) delete mode 100644 "\354\265\234\354\233\220\353\271\210.md" diff --git "a/\354\265\234\354\233\220\353\271\210.md" "b/\354\265\234\354\233\220\353\271\210.md" deleted file mode 100644 index c54bc9a..0000000 --- "a/\354\265\234\354\233\220\353\271\210.md" +++ /dev/null @@ -1,4 +0,0 @@ -멘토 형님의 조언을 듣고 주어진 문제형식이 아닌 제 스스로의 코드를 다시 짜봤습니다. 아직 부족한게 많아서 차차해 나갈 생각입니다. -일단 메인과 연동하여, 실행하면 로그인과 로그아웃을 할 수 있는 기능을 추가했습니다. -로그인이 성공한다면 그제야 입금 출금과 같은 기능을 사용 할 수 있게 했습니다. -아직 새 코드에는 예외처리하는 기능을 추가하지는 않았습니다. 그래서 따로 패키지에만 넣어놨습니다. From 3f4b93dc3e155de20b8015cb0a2db2011fcc348b Mon Sep 17 00:00:00 2001 From: ChoiTheCreator <147716165+ChoiTheCreator@users.noreply.github.com> Date: Tue, 7 May 2024 21:42:56 +0900 Subject: [PATCH 46/56] =?UTF-8?q?Create=20=EC=B5=9C=EC=9B=90=EB=B9=88.md?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit 7주차 학습 PR --- .../\354\265\234\354\233\220\353\271\210.md" | 43 +++++++++++++++++++ 1 file changed, 43 insertions(+) create mode 100644 "week07/\354\265\234\354\233\220\353\271\210.md" diff --git "a/week07/\354\265\234\354\233\220\353\271\210.md" "b/week07/\354\265\234\354\233\220\353\271\210.md" new file mode 100644 index 0000000..ff4dcc5 --- /dev/null +++ "b/week07/\354\265\234\354\233\220\353\271\210.md" @@ -0,0 +1,43 @@ +# 7주차 과제 - Spring 사전 조사 + +5/7 화요일 23:59 까지 제출해주시면 되겠습니다. + +## 스프링의 장점 / 사용 이유 +스프링의 장점으로는 첫번째로는 의존성 주입입니다. 이는 객체 간의 의존 관계를 외부에서 결정하고 주입해주는 방식으로, 코드의 결합도를 낮추고 유닛 테스트를 용이하게 합니다. 이로 인해 더 유지보수가 쉽고, 재사용 가능한 코드를 작성할 수 있습니다. 여기서 의존성이란 소프트웨어 개발에서 특정 객체가 다른 객체의 기능을 사용하거나 필요로 할 때 그 관계를 의미합니다. 한 클래스가 다른 클래스의 메소드나 데이터를 사용할 때, 첫 번째 클래스는 두 번째 클래스에 의존하고 있다고 말합니다. 실제적으로 예를 들어, 계좌 클래스가 특정 데이터베이스 클래스의 인스턴스를 직접 생성하는 대신, 생성자나 세터 메소드를 통해 데이터베이스 인스턴스를 받게 함으로써, 다른 종류의 데이터베이스로 쉽게 교체할 수 있게 됩니다. + 두번째로는 포괄적인 프레임 워크를 사용할수 있습니다. 스프링은 웹 개발, 보안, 데이터 접근, 메시징, 트랜잭션 관리 등 다양한 기능을 제공하는 포괄적인 프레임워크입니다. 이는 개발자가 필요한 모든 기능을 하나의 프레임워크 안에서 해결할 수 있게 해줍니다. + 세번째로는 AOP를 지원한다는 것입니다. AOP는 관점 지향 프로그래밍을 의미하며, 스프링은 AOP를 지원합니다. 이를 통해 트랜잭션 관리, 로깅, 보안 등의 공통적인 관심사를 핵심 비즈니스 로직에서 분리하여 관리할 수 있습니다. 이는 코드의 재사용성을 높이고, 유지보수를 쉽게 합니다. + 네번째로는 매우 유연한 프로그래밍 도구라는 것입니다. 데이터를 접근하거나 뷰에 접근할때 특히 유용하게 쓰입니다. + 다섯번째로 Pojo 기반 설정을 지원한다는 것입니다. pojo는 plain old java object의 줄임말로, 간단한 자바 코드로 애플리케이션을 구성할수 있다는 것입니다. 이로 최소한의 코드변경으로 높은 품질의 결과를 얻을 수 있다는 장점이 있습니다. + 마지막으로 강력한 보안성을 지니고 있습니다. 스프링 시큐리티는 인증 및 권한 부여에 대한 포괄적인 지원을 제공하여 애플리케이션의 보안을 강화합니다. + + +## 싱글톤, 싱글톤 컨테이너 +싱글톤은 디자인 패턴의 하나로, 특정 클래스의 인스턴스가 하나만 생성되도록 보장하는 패턴을 의미합니다. 이러한 싱글톤 패턴의 장점은 메모리 낭비를 방지한다는 것이며, 전역 접근성을 가지고 있어 싱글톤 객체는 전역적으로 접근할 수 있습니다. 하지만 상속의 여럽고, 객체지향의 다형성과 상속과 같은 중요한 객제지향 특성의 사용에 제한된다는 것이 단점입니다. +싱글톤 컨테이너는 스프링 컨테이너는 일단 기본적으로 빈을 싱글톤으로 관리합니다. 이를 통해 메모리 낭비를 방지하며 서버의 부하를 감당 할 수 있습니다. +싱글톤 컨테이너의 장점으로는 객체 생성,삭제의 최소화로 효율적인 생성/삭제가 가능하며, 싱글톤 패턴의 한계를 극복하여 상속, 다형성 등 객체 지향의 특성을 보장합니다. + +## 레이어드 아키텍쳐 패턴 +소프트웨어 시스템을 여러 개의 독립적인 모듈로 나누어 설계하는 패턴입니다. 각 레이어는 특정한 역할과 책임을 가지며, 추상화된 인터페이스를 통해서만 상호작용합니다. +장점으로는 관심사 분리 즉 독립적으로 레이어들이 존재하므로 재사용성과 유지보수성, 한 곳에 역할이 집중되는 것을 방지합니다. 또한 낮은 결합도를 가지고 있어 레이어 간 의존성이 낮아 변경에 유연합니다. 각 레이어가 특정한 역할과 책임을 가지므로 응집도가 높습니다. +구조로는 4 Layered 아키텍쳐 구조가 있습니다. 이는 첫째로 프리젠테이션 레이어. 즉 사용자 인터페이스와 관련된 기능을 담당합니다. 두번째로 애플리케이션 레이어, 비즈니스 로직을 처리하는 기능을 담당합니다. 세번째로는 도메인 레이어, 이는 핵심 비즈니스 개념과 규칙을 정의합니다. 마지막으로 인프라스트럭처 레이어, 이는 데이터페이스, 파일 시스템과 같은 기술적인 구현을 담당합니다. +의존성의 흐름 또한 중요한데, 항상 프레젠테이션 레이어에서 인프라스트럭처 레이어로 향합니다. 상위 레이어는 하위레이어에 의존하지만, 하위레이어는 상위 레이어에 대해 알지 못합니다 +## 스프링 어노테이션 10개 이상 정리 +1. @Autowired -> 의존성 주입을 위해 사용됩니다. 타입 기반 의존성 주입을 수행합니다. +2. @Component -> 스프링 빈으로 등록하기 위해 사용되는 어노테이션입니다. 이 어노테이션이 붙은 클래스는 스프링 컨테이너에 의해 관리됩니다 +3. @Configuration -> 자바 기반 설정 클래스를 정의되기 위해 사용되며, 이 어노테이션이 붙은 클래스는 스프링 빈 설정을 담당합니다. +4. @Bean -> 메서드 레벨에서 사용되며, 해당 메서드가 반환하는 객체를 스프링 빈으로 등록합니다. +5. @Controller -> 웹 애플리케이션의 컨트롤러 역할을 하는 클래스에 사용되는 어노테이션입니다 +6. @Service -> 비즈니스 로직을 담당하는 서비스 계층의 클래스에 사용되는 어노테이션입니다. +7. @Repository -> 데이터 엑세스 계층의 클래스에 사용되는 어노테이션입니다. +8. @RequestMapping -> HTTP 요청을 처리할 메서드를 매핑하기 위해 사용되는 어노테이션입니다. +9. @ResponseBody -> 메서드가 반환하는 값을 HTTP 응답 본문으로 직접 렌더링 하도록 지지정하는 어노테이션입니다. +10. @Value -> 외부 설정 파일에서 값을 읽어오기 위해 사용되는 어노테이션입니다. +11. @PostConstruct -> 빈 초기화 시 실행되는 메서드에 사용되는 어노테이션입니다. +12. @PreDestory -> 빈 소멸 전 실행되는 메서드에 사용되는 어노테이션입니다. +13. @Qualifer -> 동일한 타입의 빈이 여러개 존재할때 특정 빈을 선택하기 위해 사용되는 어노테이션입니다. +14. @Scope -> 스프링의 빈의 범위를 지정하기 위해 사용되는 어노테이션입니다. +15. @Transactional -> 트랜잭션 처리를 위해 사용되는 어노테이션입니다. + + + +## Postman 설치해오기 From 00392d191ea64c045434b619cfd28c60fbe74a0a Mon Sep 17 00:00:00 2001 From: baaamk <136908616+baaamk@users.noreply.github.com> Date: Tue, 7 May 2024 23:24:27 +0900 Subject: [PATCH 47/56] Update README.md --- week07/README.md | 144 +++++++++++++++++++++++++++++++++++++++++++++++ 1 file changed, 144 insertions(+) diff --git a/week07/README.md b/week07/README.md index a993b14..c17202f 100644 --- a/week07/README.md +++ b/week07/README.md @@ -3,7 +3,151 @@ 5/7 화요일 23:59 까지 제출해주시면 되겠습니다. ## 스프링의 장점 / 사용 이유 +1. POJO기반의 구성(Plain Old Java Object) +- 코드개발시 개발자가 특정한 라이브러리나 컨테이너의 기술에 종속되지 않고 java코드를 이용해 객체를 구성하는 방식 그대로 스프링에서 사용 가능하다 +따라서 자유럽게 객체지향적 설계를 구현할 수 있다. 높은 생산성과 유연한 테스트를 할 수 있는 장점을 가지게 된다. + +2. DI(Dependency Injection, 의존성 주입)을 통한 객체 관계 구성 +제어의 역전이 일어나는 것을 전제로 스프링 내부의 객체들 간의 관계를 관리할 때 사용. 자바에서는 인터페이스를 사용해 의존적 관계를 처리 +-메소드나 객체(bean)의 호출 작업은 제어의 역전을 통해 외부에서 이루어진다 +-제어의 역행을 전제조건으로 의존성 주입이 일어난다. +-의존성을 가진 객체에 대해 스프링에서 의존성 주입이 발생하도록 한다. +-의존성 주입 특징으로 인해 개발자가 POJO개발이 가능하게 된다. + +컴포넌트 스캔과 자동 의존관계 설정 +생성자에 @Autowired가 있으면 스프링이 연관된 객체를 스프링 컨테이너에서 찾아서 넣어준다 +스프링이 시작될 때 @Controller, @Service, @Repository와 같은 컴포넌트들을 스캔하고 스플링에 빈으로 등록한다. 기본적으로 @Component가 있으면 스프링 빈으로 자동 등록 되며, 위의 세 어노테이션도 포함아고 있기에 스프링 빈으로 자동 등록 된다. 스프링 빈으로 등록된다면 "스프링 컨테이너에서 빈이 관리된다" 라고 말한다 이후에 @Autowired 어노테이ㅣ션으로 등록된 빈들의 의존관계 연결한다 + +의존성 주입의 방법 +1. 필드주입 +2. setter 주입 +3. 생성자 주입 (권장) + +생성자 주입 권장 이유 +1. 순환 의존성 확인: 필드 주입으로는 순환 의존성을 파악하기 어렵다. 생성자 주입하게되면 에러메세지가 뜨면서 서버 기동이 되지 않는다 +2.부렵ㄴ성: 필드 주입은 final을 선언할 수 없지만 생성자 주입은 final을 선언함으로써 객체가 변하지 않도록 방지해준다 +3. 단일 책임 원칙 위반 확인 +@TrequriedArgsConstrusctor라는 어노테이션을 붙이면 final 필드나 @NonNull이 붙은 필드에 대해 생성자를 생성해 준다. 주로 의존성 주입의 편의성을 위해 사용된다 + +3.AOP(관점지향 프로그래밍) 지원 +유지보수를 쉽게 하고 반복적인 코드를 줄이고 개발자가 핵심 비즈니스 로직에만 집중할 수 있도록 지원 + +4. 편리한 MVC구조 + +5. WAS에 독립적인 개발 환경 + ## 싱글톤, 싱글톤 컨테이너 +싱글톤 이란 클래스의 인스턴스가 딱 `1개만 생성되는 것을 보장하는 디자인 패턴이다 +따라서 객체 인스턴스가 1개여야하고 private 생성자를 사용해서 외부에서 임의로 new키워드를 사용하지 못하게 막아야 한다. +싱글톤 문제로는 구현 코드가 많이들어간다는 점. DIP위반, OCP위반, 테스트 어려움, 내부속성 변경or 초기화 어려움, private생성자로 자식 클래스 만들기 어려움, 결론적으로 유연성 떨어짐. + + +싱글톤 컨테이너 +스프릥 컨테이너는 싱글톤의 문제점 해결, 객체 인스턴스를 싱글톤(1개만 생성)으로 관리한다. 지금까지 우리가 학습한 스프링 빈이 바로 싱글톤으로 관리되는 빈이다. + +스프링 컨테이너는 싱글톤 패전 적용 하지 않아도 객체 인스턴스 싱글톤으로 관리 +싱글톤 관리하는 기능= 싱글톤 레지스트리 +모든 단점을 해결하면서 객체를 싱글톤으로 유지할 수 있다. +스프링 컨테이너 덕분에 고객의 요청이 올 때마다 객체를 생성하는 것이 아니라, 이미 만들어진 객체를 공유해서 효율적으로 재사용할 수 있다. + +주의점으로는 멀티쓰레드 환경에서의 동시성 문제 해결해야 함. +따라서 +1.상태를 유지하게 설계하면 안되고 무상태로 설계해야한다. +2. 의존적 필드가 있으면 안됨 +3. 값을 변경할 수 잇는 필드가 있으면 안됨 +4. 공유필드 대신 지역변수, 파라미터, ThreadLocal등을 사용해야한다 +5. 스프링 빈의 필드에 공유 값을 설정하면 정말 큰 장애 발생 가능. + ## 레이어드 아키텍쳐 패턴 +백엔드 API를 구현할때 널리 쓰이는 패턴 +레이어드 아키텍쳐로 API를 구현할때는 역할에 따라 독립된 모듈로 나누어서 코드를 구현한다. +일반적으로 presentation layer, business layer, persistence layer 이렇게 3개의 레이어가 있으며, 3개의 레이어가 층층히 의존도에 따라 연결되어 전체 시스템을 구성한다. + +presentation layer +-클라이언트와 직접적으로 연결되는 부분, 웹사이트에서는 UI에 해단, 백엔드 API에서는 엔드포인트에 해당한다 +-API의 엔드포인트를 정의하고 전송된 HTTP요청들을 읽어 들이는 로직 구현 + +business layer +-실제 시스템이 구형해야 하는 로직들 구현 +- 필요한 데이터 생성, 수정, 읽기, 삭제 처리 + +persistence layer +- 데이터베이스와 관련된 로직 구현 +- business layer에서 필요한 데이터의 생성, 수정, 읽기, 삭제를 처리하고 실제 데이터베이스에서 데이터 저장, 수정 읽어 들이는 역할. + +레이어드 아키텍쳐 패턴 핵심 요소 +1. 단방향적 의존성 +presentation layer - business layer에만 의존 +business layer- persistence layer에만 의존 + +같은 의미로 +business layer - presentation layer에 독립적 +persistence layer - business layer에 독립적 + +2.레이어드 역할의 분리 +presentation layer에는 비즈니스 로직이 전혀 구현 되어있지 않으며, +비즈니스 로직을 처리하기 위해서는 presentation layer에서 business layer를 호출해야 한다. + ## 스프링 어노테이션 10개 이상 정리 +@SpringBootApplication +Srping Boot를 자동으로 실행시켜주는 어노테이션으로 Bean 등록은 두 단계로 진행된다. + +@ComponentScan을 통해 Component들을 Bean으로 등록한다. +@EnableAutoConfiguration을 통해 미리 정의해둔 자바 설정 파일들을 Bean으로 등록한다. +(Bean은 스프링 IoC 컨테이너에 의해 인스턴스화되어 조립되거나 관리되는 객체) +@Configuration +스프링 IoC Container에게 해당 클래스가 Bean 구성 Class임을 알려주는 어노테이션이다. +@Bean을 해당 클래스의 메소드에 적용하면 @Autowired로 빈을 부를 수 있다. + + +@EnableAutoConfiguration +Spring Application Context를 만들 때 자동으로 설정하는 기능을 켠다. +classpath의 내용에 기반해서 자동 생성해 준다. +만약 tomcat-embed-core.jar가 존재하면 톰캣 서버가 setting된다. + + +@ComponentScan +@Component, @Service, @Repository, @Controller, @Configuration이 붙은 빈들을 찾아서 +Context에 빈을 등록해 주는 어노테이션이다. +@Component 어노테이션이 있는 클래스에 대하여 bean 인스턴스를 생성한다. + +Spring에서 @Component로 다 쓰지 않고 @Repository, @Service, @Controller등을 사용하는 이유는, 예를들어 @Repository는 DAO의 메소드에서 발생할 수 있는 unchecked exception들을 스프링의 DataAccessException으로 처리할 수 있기 때문이다. + +또한 가독성에서도 해당 애노테이션을 갖는 클래스가 무엇을 하는지 단 번에 알 수 있다. + + +@Component +개발자가 직접 작성한 Class를 Bean으로 등록하기 위한 어노테이션이다. +@ComponentScan선언에 의해 특정 패키지 안의 클래스들을 자동 스캔하여 @Component 어노테이션이 있는 클래스들에 대하여 Bean 인스턴스를 생성한다. + +@Bean +@Bean은 개발자가 직접 제어가 불가능한 외부 라이브러리 등을 Bean으로 만드려할 때 사용되는 어노테이션이다. + +@Autowired +필드, setter 메소드, 생성자에 사용하며 Type에 따라 알아서 Bean을 주입해주는 역할을 한다. +객체에 대한 의존성을 주입시킨다. +@Autowired을 사용하면 스프링이 자동적으로 값을 할당한다. +Controller 클래스에서 DAO나 Service에 관한 객체들을 주입 시킬 때 많이 사용한다. + +Bean을 주입받는 방식(3가지) +@Autowired +setter +생성자: @AllArgsConstructor 사용, 스프링에서는 생성자를 통한 방식을 권장한다. + +@Controller +Spring MVC의 Controller로 사용되는, 클래스 선언을 단순화 시켜주는 어노테이션이다. + + +@RestController +Spring에서 Controller 중 View로 응답하지 않는 Controller를 의미한다. +method의 반환 결과를 JSON 형태로 반환한다. + +@RestController가 적혀있는 Controller의 method는 HttpResponse로 바로 응답이 가능하다. +@ResponseBody 역할을 자동적으로 해주는 어노테이션이다. +@RestController = @Controller + @ResponseBody + +@Service +Service class에서 쓰이는 어노테이션으로, 비즈니스 로직을 수행하는 Class라는 것을 나타내는 용도이다. + ## Postman 설치해오기 +완료 From 41152b6b72be5249cc52fd7dedbc2d287256ff3a Mon Sep 17 00:00:00 2001 From: baaamk <136908616+baaamk@users.noreply.github.com> Date: Tue, 7 May 2024 23:26:12 +0900 Subject: [PATCH 48/56] =?UTF-8?q?Rename=20README.md=20to=20=EB=B0=A9?= =?UTF-8?q?=ED=98=84=EC=9A=B0.md?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .../README.md => "week07/\353\260\251\355\230\204\354\232\260.md" | 0 1 file changed, 0 insertions(+), 0 deletions(-) rename week07/README.md => "week07/\353\260\251\355\230\204\354\232\260.md" (100%) diff --git a/week07/README.md "b/week07/\353\260\251\355\230\204\354\232\260.md" similarity index 100% rename from week07/README.md rename to "week07/\353\260\251\355\230\204\354\232\260.md" From 541cc9458cae9c8e8740f291942d70c3659df898 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?=EC=9D=B4=EC=8A=B9=EC=A3=BC?= <129913026+Juuuu-power-e@users.noreply.github.com> Date: Tue, 7 May 2024 23:50:43 +0900 Subject: [PATCH 49/56] =?UTF-8?q?Create=20=EC=9D=B4=EC=8A=B9=EC=A3=BC.md?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .../\354\235\264\354\212\271\354\243\274.md" | 50 +++++++++++++++++++ 1 file changed, 50 insertions(+) create mode 100644 "week07/\354\235\264\354\212\271\354\243\274.md" diff --git "a/week07/\354\235\264\354\212\271\354\243\274.md" "b/week07/\354\235\264\354\212\271\354\243\274.md" new file mode 100644 index 0000000..31cd94d --- /dev/null +++ "b/week07/\354\235\264\354\212\271\354\243\274.md" @@ -0,0 +1,50 @@ +# 7주차 과제 - Spring 사전 조사 + +## 스프링의 장점 / 사용 이유 + +- **POJO 기반 구성** + + Plain Old Java Object : 오래된 방식의 간단한 자바 객체, 즉 필드와 getter, setter 등의 기본적인 기능만을 가지는 기본 객체를 의미한다. + + POJO개념을 잘 따른 코드의 경우 결합을 느슨하게 하여 낮은 종속성을 가진다. 직접적으로 프레임워크 클래스나 인터페이스를 상속/구현하게 되면 필연적으로 리팩토링의 과정을 거치게 되고 특정 기술에 종속적이게 된다. 스프링에서는 이러한 문제를 @Autowired를 사용함으로써 의존성을 주입하여 메서드를 직접 override하지 않아 부모클래스 코드의 변경이 생겨도 같이 변하게 된다. + +- **DI** + + Dependency Injection : 의존성 주입은 클래스간의 결합도를 느슨하게 하기 위한 프로그래밍 패턴으로 사용할 객체를 직접 생성하는 것이 아닌 생성자나 setter 또는 인터페이스를 통해 주입받아 사용하는 것이다. 의존성이 주되는 객체를 외부에서 관리하고 전달함으로써, 클래스 간의 결합도를 낮추고 코드의 유연성과 재사용성을 향상시킬 수 있다. + +- **IoC** + + Inversion of Control : 제어의 역전은 소프트웨어 설계 원칙 중 하나로 프로그래밍에 있어 객체의 생성 및 관리 책임을 개발자에서 전체 애플리케이션 또는 프레임워크에 위임하는 디자인 원칙이다. 라이브러리를 사용하는 애플리케이션 코드는 애플리케이션 흐름을 직접 제어한다. 즉, 동작하는 중에 필요한 기능이 있을 때 능동적으로 라이브러리를 사용하게 된다. 그러나 프레임워크는 애플리케이션 코드가 프레임워크에 의해 사용된다. 프레임워크 위에 개발한 클래스를 등록해두고, 프레임워크가 흐름을 주도하는 중에 개발자가 만든 애플리케이션 코드를 사용하도록 만드는 방식이다. + +- **AOP의 지원** + + Aspect-Oriented Programming: 관점 지향 프로그래밍은 핵심로직과 흩어진 관심사를 분리하여 모듈화하는 프로그래밍 기법으로 공통적으로 사용되는 관심사를 하나의 Ascpect로 모듈화 하여 재사용과 유지보수가 용이하도록 하는 기법이다. 스프링에서는 **``** XML태그를 사용하여 AOP를 구현하거나 **`@Aspect`** 어노테이션을 통해 AOP를 구현할 수 있다. + + +## 싱글톤, 싱글톤 컨테이너 + +- **싱글톤** + + Singleton은 디자인 패턴 중 하나로, 애플리케이션 전체에서 인스턴스가 단 하나만 생성되어 사용되는 객체를 한다. 스프링에서는 기본적으로 빈)들을 싱글톤으로 관리하기 때문에 스프링 컨테이너에서 빈을 요청하면 항상 동일한 인스턴스를 반환하게 된다. + +- **싱글톤 컨테이너** + + Singleton Container는 스프링에서 싱글톤 객체들을 생성하고 관리하는 컨테이너를 의미한다. 스프링에서는 기본적으로 빈 컨테이너가 싱글톤 객체를 생성하고 관리한다. + + +## 레이어드 아키텍쳐 패턴 + +- 레이어드 아키텍처 패턴은 소프트웨어 시스템을 레이어로 나누어 각 계층의 역할을 명확히 정의하고 관리하는 디자인 패턴으로 단일 책임 원칙을 적용하고 각 개층을 나누어 독립적으로 테스트 할 수 있도록 한다. + +## 스프링 어노테이션 10개 이상 정리 + +- `@Autowired` : 필드, 메서드 , 생성자에 추가하여 해당 클래스에 맞는 빈을 찾아 의존성을 주입한다. +- `@Component` : 빈을 선언하는 클래스에 추가하여 `@ComponentScan`의 주요 스캔대상이 되도록 한다. +- `@Service` : `@Component` 어노테이션과 유사한 기능을 하지만 ‘비즈니스 레이어’로직에 맞도록 구성하는 클래스로 직접적인 처리는 다른 빈에서 이뤄지고 결과를 제공하는 역할을 한다. +- `@Configuration` : 빈 설정을 담당하는 클래스에 추가하는 어노테이션으로 이 클래스 내에서 `@Bean` 어노테이션을 추가한 메서드를 선언하면 해당 메서드를 통해 빈을 정의하고 생명주기를 설정하게 된다. +- `@bean` : `@Configuration` 를 선언한 클래스에서 메서드에 추가하는 어노테이션으로 해당 메소드 명의 빈을 정의한다. +- `@Required` : 빈 클래스를 초기화 할때 반드시 필요한 메서드를 정의할 때 사용하는 어노테이션이다. +- `@Primary` : 기본 빈 요소를 정의할때 사용하는 어노테이션으로 같은 클래스로 여러 개의 빈을 설정했을 때, `@Autowired` 를 통해 의존성 주입시 이 어노테이션이 추가된 빈을 우선적으로 연결한다. +- `@value` : 생성자나 `setter` 의 메소드, 필드 등에다가 스프링에서 설정한 값을 주입할 수 있다. 주로 `application.properties` 및 스프링이나 자바 property 값을 가져올 때 쓴다. +- **`@DependsOn`**: `@Bean` 및 `@Component` 등에 정의 및 선언한 빈 생성 시 요구되는 다른 빈을 정의할 때 사용한다. 이 어노테이션을 달면, 이 어노테이션에서 설정한 빈이 등록되지 전까지 어노테이션이 달린 빈을 선언하지 않게 된다. +- **`@Scope`**: 빈의 생명주기를 설정한다. 스프링에서는 기본적으로 싱글톤으로 빈 객체를 사용하기 때문에 기본값은 singleton이며 다른 생명주기를 설정하는 것도 가능하다. From d1965a95a61b33e157f1ed578a80001cc484b650 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?=EB=82=98=EA=B2=BD=ED=98=B8?= Date: Wed, 8 May 2024 23:17:41 +0900 Subject: [PATCH 50/56] =?UTF-8?q?docs:=208=EC=A3=BC=EC=B0=A8=20=EA=B3=BC?= =?UTF-8?q?=EC=A0=9C=20=EA=B3=B5=EC=A7=80?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- week08/README.md | 7 +++++++ 1 file changed, 7 insertions(+) create mode 100644 week08/README.md diff --git a/week08/README.md b/week08/README.md new file mode 100644 index 0000000..989e792 --- /dev/null +++ b/week08/README.md @@ -0,0 +1,7 @@ +# COW MVC PRACTICE 학습 저장소 + +## 📮 미션 제출 방법 +- 미션 구현을 완료한 후 GitHub을 통해 제출해야 한다. + - [미션 구현 저장소](https://github.com/Hoya324/cow_mvc_practice) 에 자신의 작성한 미션 pr 작성 + - 미션 구현에서 기록한 md파일은 [COW-Spring-3](https://github.com/COW-edu/COW-Spring-3/tree/main/week08) 리포지토리에 pr 작성 + - 미션 구현 pr 링크 첨부(필수) \ No newline at end of file From 2d8a9c2d8644f8e37ca6e90a8ab85d215fbb2b7d Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?=EB=82=98=EA=B2=BD=ED=98=B8?= Date: Wed, 8 May 2024 23:17:47 +0900 Subject: [PATCH 51/56] =?UTF-8?q?docs:=20=ED=8C=8C=EC=9D=BC=20=EC=88=98?= =?UTF-8?q?=EC=A0=95?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .../\354\265\234\354\233\220\353\271\210.md" | 0 1 file changed, 0 insertions(+), 0 deletions(-) rename "\354\265\234\354\233\220\353\271\210.md" => "week02/\354\265\234\354\233\220\353\271\210.md" (100%) diff --git "a/\354\265\234\354\233\220\353\271\210.md" "b/week02/\354\265\234\354\233\220\353\271\210.md" similarity index 100% rename from "\354\265\234\354\233\220\353\271\210.md" rename to "week02/\354\265\234\354\233\220\353\271\210.md" From 6e918e895842db5d14e9eb3ef92347bb41219f66 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?=EB=82=98=EA=B2=BD=ED=98=B8?= Date: Thu, 9 May 2024 13:58:06 +0900 Subject: [PATCH 52/56] =?UTF-8?q?docs:=20week08=20h2=20=EB=B2=84=EC=A0=84?= =?UTF-8?q?=20=EC=B6=94=EA=B0=80?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- week08/README.md | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/week08/README.md b/week08/README.md index 989e792..82215ab 100644 --- a/week08/README.md +++ b/week08/README.md @@ -2,6 +2,7 @@ ## 📮 미션 제출 방법 - 미션 구현을 완료한 후 GitHub을 통해 제출해야 한다. - - [미션 구현 저장소](https://github.com/Hoya324/cow_mvc_practice) 에 자신의 작성한 미션 pr 작성 + - [미션 구현 저장소] [docker 사용 버전](https://github.com/Hoya324/cow_mvc_practice) 또는 [h2 사용 버전](https://github.com/Hoya324/cow_mvc_session) 에 자신의 작성한 미션 pr 작성 + - docker 환경 설정이 어려운 경우 h2 사용 권장합니다. - 미션 구현에서 기록한 md파일은 [COW-Spring-3](https://github.com/COW-edu/COW-Spring-3/tree/main/week08) 리포지토리에 pr 작성 - 미션 구현 pr 링크 첨부(필수) \ No newline at end of file From 8d982342c2f21c1eeb2c5bb17cf61bbc6b30dd8a Mon Sep 17 00:00:00 2001 From: YOON <120346721+0702Yoon@users.noreply.github.com> Date: Thu, 9 May 2024 21:39:05 +0900 Subject: [PATCH 53/56] Update README.md --- week08/README.md | 38 ++++++++++++++++++++++++++++++++++++-- 1 file changed, 36 insertions(+), 2 deletions(-) diff --git a/week08/README.md b/week08/README.md index 82215ab..24afc23 100644 --- a/week08/README.md +++ b/week08/README.md @@ -1,8 +1,42 @@ # COW MVC PRACTICE 학습 저장소 - +Postman을 사용하여, 여러분이 직접 api를 설계합니다. 그 다음 여러분이 스프링을 사용하여 웹 서버를 구현하고 Postman을 통해 요청에 대한 적절한 응답이 왔는 지를 확인하는 것이 이번 과제의 +최종 목표입니다. ## 📮 미션 제출 방법 - 미션 구현을 완료한 후 GitHub을 통해 제출해야 한다. - [미션 구현 저장소] [docker 사용 버전](https://github.com/Hoya324/cow_mvc_practice) 또는 [h2 사용 버전](https://github.com/Hoya324/cow_mvc_session) 에 자신의 작성한 미션 pr 작성 - docker 환경 설정이 어려운 경우 h2 사용 권장합니다. - 미션 구현에서 기록한 md파일은 [COW-Spring-3](https://github.com/COW-edu/COW-Spring-3/tree/main/week08) 리포지토리에 pr 작성 - - 미션 구현 pr 링크 첨부(필수) \ No newline at end of file + - 미션 구현 pr 링크 첨부(필수) +--- + +현재 목표가 웹 서버를 개발하기에 인터넷, http, Rest Api에 대해서 조사하시면 여러분들에게 도움이 될 것 같습니다. + +또 추가적으로 DB를 잘 모르시는 분들에게 엔터티간의 관계, 1:1 1:N 처리에 문제가 생길 수 있기에 추가적으로 학습하셔도 좋을 것 같습니다. + +5/14 화요일 23:59 까지 제출해주시면 되겠습니다. + +## [필수] + +## 인터넷과 네트워크 + +--- + +## http란 + +--- + +## http 메서드 + +--- + +## http 상태 코드 + +--- + +## Rest API란 + +--- + +## [추가] + +## Entity간의 연관 관계의 주인 From e16576f04034b05a0f3d16d3cfa5a53c842a4863 Mon Sep 17 00:00:00 2001 From: BuildTools Date: Sat, 11 May 2024 11:46:09 +0900 Subject: [PATCH 54/56] docs : Add 0711kc.md --- week08/0711kc.md | 42 ++++++++++++++++++++++++++++++++++++++++++ 1 file changed, 42 insertions(+) create mode 100644 week08/0711kc.md diff --git a/week08/0711kc.md b/week08/0711kc.md new file mode 100644 index 0000000..24afc23 --- /dev/null +++ b/week08/0711kc.md @@ -0,0 +1,42 @@ +# COW MVC PRACTICE 학습 저장소 +Postman을 사용하여, 여러분이 직접 api를 설계합니다. 그 다음 여러분이 스프링을 사용하여 웹 서버를 구현하고 Postman을 통해 요청에 대한 적절한 응답이 왔는 지를 확인하는 것이 이번 과제의 +최종 목표입니다. +## 📮 미션 제출 방법 +- 미션 구현을 완료한 후 GitHub을 통해 제출해야 한다. + - [미션 구현 저장소] [docker 사용 버전](https://github.com/Hoya324/cow_mvc_practice) 또는 [h2 사용 버전](https://github.com/Hoya324/cow_mvc_session) 에 자신의 작성한 미션 pr 작성 + - docker 환경 설정이 어려운 경우 h2 사용 권장합니다. + - 미션 구현에서 기록한 md파일은 [COW-Spring-3](https://github.com/COW-edu/COW-Spring-3/tree/main/week08) 리포지토리에 pr 작성 + - 미션 구현 pr 링크 첨부(필수) +--- + +현재 목표가 웹 서버를 개발하기에 인터넷, http, Rest Api에 대해서 조사하시면 여러분들에게 도움이 될 것 같습니다. + +또 추가적으로 DB를 잘 모르시는 분들에게 엔터티간의 관계, 1:1 1:N 처리에 문제가 생길 수 있기에 추가적으로 학습하셔도 좋을 것 같습니다. + +5/14 화요일 23:59 까지 제출해주시면 되겠습니다. + +## [필수] + +## 인터넷과 네트워크 + +--- + +## http란 + +--- + +## http 메서드 + +--- + +## http 상태 코드 + +--- + +## Rest API란 + +--- + +## [추가] + +## Entity간의 연관 관계의 주인 From bf05fac3ccc91cde80ed0738b2f134b7bd7f6273 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?=EB=82=98=EA=B2=BD=ED=98=B8?= Date: Sat, 11 May 2024 22:19:56 +0900 Subject: [PATCH 55/56] =?UTF-8?q?docs:=20=EA=B3=B5=EC=A7=80=20=ED=8C=8C?= =?UTF-8?q?=EC=9D=BC=20=EC=88=98=EC=A0=95?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- week07/README.md | 11 +++++++++++ week08/README.md | 2 ++ 2 files changed, 13 insertions(+) create mode 100644 week07/README.md diff --git a/week07/README.md b/week07/README.md new file mode 100644 index 0000000..455e3a2 --- /dev/null +++ b/week07/README.md @@ -0,0 +1,11 @@ +> ‼️ 해당 파일은 절대로 지우지 말아주세요 ‼️ + +# 7주차 과제 - Spring 사전 조사 + +5/7 화요일 23:59 까지 제출해주시면 되겠습니다. + +## 스프링의 장점 / 사용 이유 +## 싱글톤, 싱글톤 컨테이너 +## 레이어드 아키텍쳐 패턴 +## 스프링 어노테이션 10개 이상 정리 +## Postman 설치해오기 \ No newline at end of file diff --git a/week08/README.md b/week08/README.md index 24afc23..1e2b641 100644 --- a/week08/README.md +++ b/week08/README.md @@ -1,3 +1,5 @@ +> ‼️ 해당 파일은 절대로 지우지 말아주세요 ‼️ + # COW MVC PRACTICE 학습 저장소 Postman을 사용하여, 여러분이 직접 api를 설계합니다. 그 다음 여러분이 스프링을 사용하여 웹 서버를 구현하고 Postman을 통해 요청에 대한 적절한 응답이 왔는 지를 확인하는 것이 이번 과제의 최종 목표입니다. From 95d0333c21b8a529697524095fc35ecf3cf215af Mon Sep 17 00:00:00 2001 From: ChoiTheCreator <147716165+ChoiTheCreator@users.noreply.github.com> Date: Wed, 15 May 2024 23:08:02 +0900 Subject: [PATCH 56/56] =?UTF-8?q?[8=EC=A3=BC=EC=B0=A8]=20=EC=B5=9C?= =?UTF-8?q?=EC=9B=90=EB=B9=88=20=ED=95=99=EC=8A=B5=20PR=20=EC=A0=9C?= =?UTF-8?q?=EC=B6=9C=ED=95=A9=EB=8B=88=EB=8B=A4.?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- week08/README.md | 47 +++++++++++++++++++++++++++++++++++++++++++++++ 1 file changed, 47 insertions(+) diff --git a/week08/README.md b/week08/README.md index 1e2b641..5f80c66 100644 --- a/week08/README.md +++ b/week08/README.md @@ -20,25 +20,72 @@ Postman을 사용하여, 여러분이 직접 api를 설계합니다. 그 다음 ## [필수] ## 인터넷과 네트워크 +네트워크는 두개 이상의 컴퓨터, 라우터, 프린터와 같은 장치들이 서로 통신할 수 있도록 연결된 시스템을 말합니다. 이 연결은 유선(이더넷)이나 무선(와이파이, 블루투스)등의 방식으로 이루어 질 수 있습니다. 네트워크를 통해 장치들은 데이터를 공유하며 통신할 수 있습니다. +네트워크는 첫번째로 LAN (local area network), 말 그대로 한 건물 또는 소규모 지역내의 장치들을 연결하는 네트워크입니다. +예를들어, 하나의 사무실이나 학교에서 사용됩니다. +그다음은 WAN( Wide Area Network) LAN보다 넓은 규모의 네트워크입니다. 인터넷이 WAN 한 예시라고 할 수 있습니다. +인터넷은 수많은 컴퓨터 네트워크딜이 서로 연결되어 형성된 거대한 네트워크의 집합입니다. 인터넷은 전 세계의 수많은 LAN, WAN이 서로 연결된 형태라고 볼 수 있습니다. 우린 이걸로 사이트에 접속하고 이메일을 주고 받으며 소통합니다. +정리하자면 네트워크는 장치들이 서로 연결되어 통신할수 있게 하는 시스템이며, 인터넷은 전 세계의 네트워크들이 연결된 거대한 네트워크입니다 --- ## http란 +HTTP는 HyperText Transfer Protocol의 약자입니다. 이는 인터넷에서 데이터를 주고받는 규칙이나 절차를 의미합니다. +웹에서는 이 HTTP를 통해 웹 서버와 클라이언트(웹 브라우저)가 서로 소통합니다. 예를 들어, 웹 브라우저에 주소를 입력하면 그 주소에 해당하는 웹 서버에 HTTP를 통해 페이지를 요청하고, +서버는 그 요청에 대한 응답으로 웹 페이지를 보내주는 방식으로 작동합니다. 결론적으로 이는 웹에서 데이터를 주고 받는 규칙이라고 할 수 있습니다. --- ## http 메서드 +HTTP 메서드는 클라이언트가 서버에게 어떤 동작을 원하는지를 알려주는 방법입니다. + • GET: 데이터를 요청할 때 사용합니다. 클라이언트가 검색을 할때 주로 사용됩니다. + • POST: 새로운 데이터를 서버에 제출할 때 사용합니다.회원가입이나 내가 원하는 글 작성 시에 즉 포스팅할때 POST 메서드를 이용합니다. + • PUT: 기존의 데이터를 업데이트할 때 사용합니다. 프로필 사진이나 배경을 변경할 때 사용됩니다. + • DELETE: 데이터를 삭제할 때 사용합니다. --- ## http 상태 코드 +HTTP 상태 코드는 웹 서버가 클라이언트의 요청에 대해 응답할 때 사용하는 숫자 코드입니다. 이는 요청이 성공적이었는지, 추가 조치가 필요한지, 오류가 발생했는지 +등 요청의 결과를 나타냅니다. +1 1xx (정보 응답): 요청을 받았으며 프로세스를 계속한다는 것을 나타냅니다. + 예를 들면, 100 (Continue)과 같은 경우 클라이언트가 요청의 나머지 부분을 계속 보낼 수 있음을 나타냅니다. +2 2xx (성공): 클라이언트의 요청이 성공적으로 수행되었음을 나타냅니다. + 예를 들면 201 (Created) - 요청이 성공적으로 이루어지고 새로운 리소스가 생성되었음을 나타냅니다. +3. 3xx (리다이렉션): 요청을 완료하기 위해 추가 조치가 필요함을 나타냅니다. ( 해석하면 다시 방향을 줘라..) + 예를들면 301 (Moved Permanently) - 요청된 리소스가 영구적으로 새 위치로 이동했음을 나타냅니다. +4. 4xx (클라이언트 오류): 클라이언트 측에서 오류가 발생했음을 나타냅니다. + 예를들면, 아주 유명한 404 (Not Found) - 서버가 요청한 리소스를 찾을 수 없음을 나타냅니다. 혹은 403 (Forbidden) - 서버가 요청을 거부함을 나타냅니다. +5 5xx (서버 오류): 서버가 요청을 처리하지 못했음을 나타냅니다. + 예를들면, 500 (Internal Server Error) - 서버에 일반적인 오류가 발생함을 나타냅니다 혹은 503 (Service Unavailable) - 서버가 일시적으로 요청을 처리할 수 없음을 나타냅니다. + 정리하자면, HTTP 상태 코드는 웹 개발과 디버깅 과정에서 중요한 역할을 하고r 웹 애플리케이션과 서버의 상태를 이해하는 데 도움을 줍니다. --- ## Rest API란 +일단 먼저 API는 Application Programming Interface의 약자로, 다른 소프트웨어 애플리케이션들이 서로 소통하고 상호작용할 수 있도록 해주는 규칙이나 프로토콜의 집합입니다. +API는 함수, 메소드, 데이터 형식 등을 정의하며, 하나의 소프트웨어가 다른 소프트웨어의 기능이나 데이터에 접근할 수 있게 합니다. +예를 들어, 인스타그램의 사용자의 위치 정보를 보여주는 기능에서 인스타그램은 위치 정보를 제공하는 API를 사용할 것입니다. 이 경우, 앱은 API를 통해 위치 정보를 요청하고, API는 요청에 따라 위치 정보를 앱에게 제공합니다. +그렇다면 REST API는 먼저 약자 REST란 Representational State Transfer의 약자로, 웹 서비스의 아키텍처 스타일 중 하나입니다. REST는 웹의 기본 속성을 활용하여 기능을 제공하며, 웹 리소스(웹 페이지, 데이터 등)를 URL로 나타내고, HTTP 메서드(GET, POST, PUT, DELETE 등)를 사용하여 해당 리소스에 대한 CRUD(Create, Read, Update, Delete) 연산을 수행하는 것이 특징입니다. +REST API는 REST 아키텍처 스타일을 따르는 API를 의미합니다. REST API를 통해 클라이언트는 서버에게 원하는 리소스를 URL로 표현하고, 그 리소스에 대한 동작을 HTTP 메서드를 통해 요청합니다. 서버는 그 요청에 따라 적절한 응답을 클라이언트에게 보내줍니다. +예를 들어, "http://example.com/users"라는 (http://example.com/users%22%EB%9D%BC%EB%8A%94) URL로 GET 요청을 보내면, 서버는 해당 URL에 대응하는 'users' 리소스의 정보를 반환할 것입니다. 이처럼 REST API는 웹 서비스를 간단하고 직관적으로 만들어주며, 웹의 기본 구조와 잘 맞아 다양한 플랫폼에서 활용됩니다. --- ## [추가] ## Entity간의 연관 관계의 주인 +엔티티(Entity)는 데이터 모델링이나 소프트웨어 개발 영역에서 사용되는 개념으로서, 실세계에서 독립적으로 존재하며 식별 가능한 정보의 단위를 의미합니다. +이 엔티티는 데이터베이스의 테이블에서 레코드를 나타내며, 엔티티의 속성은 테이블의 컬럼에신 자신만의 고유한 속성을 가지고 있습니다. + 예를 들어, '고객' 엔티티는 이름, 주소, 전화번호 등의 속성을 가질 수 있고, '주문' 엔티티는 주문 날짜, 배송 주소, 주문 상품 등의 속성을 가질 수 있습니다. + 데이터베이스에서는 이러한 엔티티를 표현하기 위해 테이블이 사용되며, 엔티티의 각 속성은 테이블의 컬럼으로 매핑됩니다. + +엔티티는 객체 지향 프로그래밍에서도 중요한 개념으로, 실세계의 개체를 소프트웨어 내에서 표현한 객체를 가리킵니다. + +ORM(Object-Relational Mapping)에서는 데이터베이스의 테이블과 객체 지향 프로그래밍의 클래스를 연결하는데, 이 때 클래스의 인스턴스가 엔티티가 됩니다. 이 엔티티는 데이터베이스의 테이블에서 레코드를 나타내며, 엔티티의 속성은 테이블의 컬럼에 해당합니다. + + + 엔티티 간의 연관 관계의 주인이란, 관계형 데이터베이스에서 두 테이블 간의 관계를 맺을 때, 이 관계를 관리(정의하고, 업데이트하고, 삭제하는 등)하는 쪽을 가리킵니다. 연관 관계의 주인은 외래 키를 관리하는 쪽입니다. +연관 관계의 주인과 반대되는 개념은 연관 관계의 비주인이며, 이는 연관 관계를 맺는 테이블 중에서 주인이 아닌 쪽을 가리킵니다. 비주인은 외래 키를 관리하지 않기 때문에, 연관 관계를 설정하거나 변경해도 데이터베이스에는 영향을 주지 않습니다. +예를 들어, "게시글(Post)"과 "댓글(Comment)"이라는 두 엔티티가 있을 때, 댓글이 게시글에 종속적인 관계라면, '게시글'은 '댓글'의 연관 관계의 주인이 됩니다. 이 경우 '게시글'이 '댓글'을 관리하며, '댓글'에 외래 키를 두어 '게시글'과 '댓글'의 관계를 나타냅니다. +연관 관계의 주인 설정은 ORM(Object-Relational Mapping) 프레임워크에서 중요한 역할을 합니다. 연관 관계를 잘 정의하고 관리하는 것은 애플리케이션의 성능과 데이터의 일관성을 유지하는 데 중요하기 때문입니다.