### 들어가기전
- 소스 : https://github.com/ohhoonim/collections-java.git
- 컬렉션, 함수형프로그래밍, 스트림
## 컬렉션
- 컬렉션이란?
- '컬렉션' === '데이터집합'
- 전공자들이 배우는 자료구조와는 살짝 다른 것 임
- 수학에서 배우는 집합과는 조금 다른게 교집합, 합집합 이런 건 없음.
- 컬렉션을 객체로 볼까 말까
- 컬렉션을 단순히 여러 객체를 한번에 가리키는 역할로만 볼 수도 있지만 컬렉션 자체를 객체로 볼 수도 있다.
- 컬렉션을 객체로 취급하면 매개변수 전달시 참조 호출의 효과를 얻을 수 있다. 참조 호출이므로 컬렉션 내의 값을 변경하면 컬렉션이 변경될 수 있다.
- 컬렉션과 제네릭
- 다양한 형태의 데이터집합을 다루려면 매번 데이터집합 타입에 맞는 컬렉션 클래스를 작성할 순 없다.
- 예제코드 : [CollectionIsObject.java]
- 어떤 컬렉션을 쓸가
- Collection vs Iterable vs List ??
- 컬렉션이 표현하는 개념
- 크기
- 원소간 순서
- 원소의 독자성
- 켈렉션을 선택했다는 것은 개발자의 성능에 대한 의도를 드러낸다
## 컬렉션 인터페이스와 구현체
- 예제코드 : [CollectionInterfaces.java]
- 배열 : 크기 고정. 가장 단순한 형태
- Iterable : 순차 열람을 지원하는 컬렉션
- Collection : 원소 추가, 제거 기능
- ArrayList : 기본 구현체이다.
- List : 원소의 순서가 있으며, 위치 정보(index)를 통해 접근 가능
- ArrayList : 원소 검색시 장점이 있다
- LinkedList : 원소 수정시 장점이 있다.
- Set : 중복된 원소가 없는 컬렉션
- HashSet : 빠르지만 순서는 보장하지 않는다
- LinkedHashSet : 순서를 보장하지만 조금 느리다
- TreeSet : 원소를 정렬해주지만 수정시 logN에 비례한다.
- SortedSet : 중복 원소가 없으면서 원소간 순서가 정해진 컬렉션
- Map : 키(key)에 의해 원소에 접근
- HashMap: 빠르지만 순서는 보장하지 않는다
- LinkedHashMap : 원소간 순서를 보장한다
- TreeMap : 키에 따라 순차열람이 가능하지만 수정시 logN에 비례한다.
- 유틸 클래스 : Collections
- 예제코드 : [CollectionUtil.java]
## 스트림 들어가기전 함수형 프로그래밍
- 컬렉션과 스트림
- Stream은 Collection을 대체하려고 만든 것이 아니다.
- 조합해서 잘 쓰면 된다.
- 다섯 형태만 기억하자
- consumer : input만 있는 형태
- supplier : output만 있는 형태
- function : input/output이 모두 있는 형태
- predict : 참/거짓을 판별하는 형태
- runner : input/output 이 없는 형태
- 예제코드 : [Functional.java]
## 스트림 연산과 파이프라인
- intermediate operation : return a new stream. They are always _lazy_;
- stateless : filter, map, flatMap, peek
- stateful : distinct, sorted, skip, dropWhile
- short-circuiting, limit, takeWhile
- terminal operation
- forEach, forEachOrdered, toArray, reduce, collect, toList, min, max, count
- short-circuiting : anyMatch, allMatch, noneMatchj, findFirst, findAny
```java
int sum = widgets.stream()
.filter(w -> w.getColor() == RED)
.mapToInt(w -> w.getWeight())
.sum();
```
## 스트림 필수 유틸 클래스 : Collectors
```java
// Accumulate names into a List
List<String> list = people.stream()
.map(Person::getName)
.collect(Collectors.toList());
// Accumulate names into a TreeSet
Set<String> set = people.stream()
.map(Person::getName)
.collect(Collectors.toCollection(TreeSet::new));
// Convert elements to strings and concatenate them, separated by commas
String joined = things.stream()
.map(Object::toString)
.collect(Collectors.joining(", "));
// Compute sum of salaries of employee
int total = employees.stream()
.collect(Collectors.summingInt(Employee::getSalary));
// Group employees by department
Map<Department, List<Employee>> byDept = employees.stream()
.collect(Collectors.groupingBy(Employee::getDepartment));
// Compute sum of salaries by department
Map<Department, Integer> totalByDept = employees.stream()
.collect(Collectors.groupingBy(Employee::getDepartment, Collectors.summingInt(Employee::getSalary)));
// Partition students into passing and failing
Map<Boolean, List<Student>> passingFailing = students.stream()
.collect(Collectors.partitioningBy(s -> s.getGrade() >= PASS_THRESHOLD));
```
Session 대신 JWT를 사용하는 이유 실 서버는 하나의 인스턴트로만 동작하지 않는다. 서버의 고가용성(high availabliity, HA)을 확보하기 위해 두 개 이상의 병렬서버로 운영하게 된다. 서버가 병렬로 운영되는 상황에서 세션을 사용하면 각 서버간의 세션을 동기화하는 문제가 발생한다. 이를 해결하기 위해 공유 데이터베이스를 이용한 세션공유 기법들을 사용하기도 한다. 서버가 많아지면 세션동기는 더 어렵다. JWT를 사용하면 세션사용으로 인한 서버 자체에 부담도 줄이면서 공유 세션에 대한 관리가 한층 수월하다. 스프링 시큐리티 - SecurityConfig.java session을 사용하지 않도록 설정 jwtAuthFilter 추가 httpBasic 제거 - JwtAuthenticationFilter.java config.filter 패키지에 파일 추가 jwt dependency 추가 (3개). gradle refresh하는 거 까먹지 말기 config.service 패키지에 [JwtService.java](http://JwtService.java) 추가 jwtService와 UserDetailService final field 추가. @RequiredArgsConstructor 까먹지 말기 - config.service.JwtService 소스 참조해서 파일 작성 - controller, service 수정 User 를 리턴하면 pwd가 그대로 노출되므로 AuthResponse와 AuthRequest로 교체 Github https://github.com/ohhoonim/factory.git 유튜브 영상 스프링부트 - 보안 JWT JWT - refresh 토큰과 logout
Inlay Hint > Parameter names java.inlayHints.parameterNames.enabled: literals java.inlayHints.parameterTypes.enabled java.inlayHints.variableTypes.enabled editor.inlayHints.enabled: offUnlessPressed Code lens editor.codeLens: true editor.codeLensFontSize java.referencesCodeLens.enabled java.implementationCodeLens: all ligature 폰트 설정 editor.fontFamily: 'D2Coding ligature’ "editor.fontLigatures": true, 편집기 확대 축소 단축키 설정 zoom 으로 검색 Google Style Formatter 설정 java.format.settings.url https://raw.githubusercontent.com/google/styleguide/gh-pages/eclipse-java-google-style.xml JDK 설정 java.configuration.detectJdksAtStart Language Server JAVA_HOME 설정 java.jdt.ls.java.home Gradle JAVA_HOME 설정 java.import.gradle.java.home Installed JDK 설정 java.configuration.runtimes Static 클래스, 메서드 import java.completion.favoriteStaticMembers "org.springframework.test.web.client.match.MockRestRequestMatchers. ", "...
# 5-Step Architecture Spec 이 문서는 헥사고날 아키텍처를 실무적으로 변형하고, DDD의 전략적 설계를 극대화한 5-Step Architecture의 표준 공정을 정의한다. 샘플 리파지토리 : https://github.com/ohhoonim/smart-factory/tree/main/back/factory-api-module ### Core Philosophy > "Service는 배달부(Messenger)일 뿐, 뇌(Brain)는 **Model**에, 법(Law)은 **Policy**에 둔다." > --- ## The 5-Step Standard Process ### Step 1: 도메인 자아 확립 (Domain Model Discovery) 비즈니스의 핵심 상태와 행위를 관리하는 Aggregate Root(AR)를 정의한다. - **원칙**: 데이터 필드가 아닌 '상태 변화의 규칙'과 '생애주기'에 집중한다. - **핵심**: AR 내부에서만 상태 변경이 가능하도록 캡슐화하며, 외부로부터의 직접적인 필드 수정을 금지한다. ### Step 2: 법전 정의 (Policy Abstraction) 비즈니스 제약 조건 중 변하기 쉬운 규칙(보안, 한도, 계산 로직)을 인터페이스로 추상화한다. - **원칙**: 도메인 모델이 프레임워크(Spring)나 환경 설정에 오염되지 않도록 보호한다. - **효과**: 정책의 변경이 모델이나 서비스의 코드 수정을 유발하지 않도록 결합도를 낮춘다. ### Step 3: 도구 제작 (Activity Implementation) 도메인이 외부 세계와 소통하기 위한 구체적인 기술(DB, Storage, 외부 API)을 구현한다. - **원칙**: 헥사고날의 **Output Adapter** 역할을 수행하며, 기술적 복잡성을 이 계층에 가둔다. - **명칭**: `QueryActivity`(조회), `CommandActivity`(...
댓글
댓글 쓰기