학습노트2 - 첫 예제, 테스트 코드

TDD

  • 테스트가 주도 하는 개발
  • 레드 그린 사이클

항상 실패하는 테스트를 먼저 작성 RED
테스트 통과하는 프로덕션 코드 작성 GREEN
테스트 통과 하면 프로덕션 코드를 리팩토링 REFACTOR

https://repo.yona.io/doortts/blog/issue/1

단위 테스트 (Unit Test)

  • TDD 가 이야기 하는 첫번째 단계인 기능 단위의 테스트 코드 작성

  • 단위 테스트 없이 할때의 개발/테스트/디버깅 Flow

  1. 코드 작성
  2. 프로그램 (Tomcat) 실행
  3. Postman 으로 API 테스트, HTTP 요청 보내기
  4. 요청결과를 System.out.println 으로 찍은 메세지로 눈으로 검증
  5. 결과가 다르면 프로그램(Tomcat) 주지 하고 코드를 수정

xUnit

가장 대중적인 테스트 프레임워크
자바는 JUnit, 2000년도에 JUnit4 -> JUnit5 로 넘어간 것으로 보임

Controller 예제 & Test Code

  1. @GetRestController
  2. @GetMapping
  3. @RequestParam
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
@RestController
public class HelloController {

@GetMapping("/hello")
public String hello()
{
return "hello";
}

@GetMapping("/hello/dto")
public HelloResponseDto helloDto(
@RequestParam("name") String name,
@RequestParam("amount") int amount)
{
return new HelloResponseDto(name, amount);
}
}

Test Code

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
@RunWith(SpringRunner.class)
@WebMvcTest
public class HelloControllerTest {

@Autowired
private MockMvc mvc;

@Test
public void hello가_리턴된다() throws Exception {
String hello = "hello";

mvc.perform(get("/hello"))
.andExpect(status().isOk())
.andExpect(content().string(hello));
}

@Test
public void hellodto가_리턴된다() throws Exception {
String name = "name";
int amount = 100;

mvc.perform(get("/hello/dto")
.param("name", name)
.param("amount", String.valueOf(amount)))
.andExpect(status().isOk())
.andExpect(jsonPath("$.name", is(name)))
.andExpect(jsonPath("$.amount", is(amount)));
}
}

Lombok 예제 & Test Code

  1. DTO 작성, @Getter, @RequiredArgsConstructor, 변수는 private final
  2. Assertj 사용
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
@Getter
@RequiredArgsConstructor
public class HelloResponseDto {

private final String name;
private final int amount;

}

public class HelloResponseDtoTest {

@Test
public void 롬복_기능_테스트() {
//given
String name = "test;";
int amount = 1000;

//when
HelloResponseDto dto = new HelloResponseDto(name, amount);

//then
assertThat(dto.getName()).isEqualTo(name);
assertThat(dto.getAmount()).isEqualTo(amount);
}
}

JPA 와 Spring Data 소개

JPA 란? ORM 이란?

  • 객체와 관계형 Database을 연결하는 기술: ORM
  • 자바에서의 ORM 기술: JPA
  • 한국, 중국에서 MyBatis 벤더의 SQL mapping 기술이 많이 쓰임 (legacy되어가고 있음)

JPA 사용해야 하는 이유

1.생산성

  • JPA를 사용하면 지루하고 반복적인 CRUD용 SQL 개발자가 직접 작성 하지 않아도 됨
  • Spring Data JPA를 사용하면 interface 선언만으로 쿼리 구현이 가능

2.유지보수

  • 칼럼 추가/삭제 시 직접 CRUD 관련 쿼리 수정 필요 없이 JPA가 관리 모델 (Entity) 수정 하면 된다.
1
2
3
4
5
6
public class Item {
private Long itemId;
private String itemName;
private Long price;
private String category; // 이부분이 변경 혹은 추가 될때 생각 해 보면..
}

3.데이타 접근 추상화와 벤더 독립성

  • 데이타베이스 벤더 마다 미묘하게 다른 데이터 타입이나 SQL을 JPA를 이용하여 손쉽게 해결
    예: Oracle 사용 중 -> MySql

4.SQL 중식 적인 개발에서 객체 중신으로 개발 (패러타임)

핵심: Entity 클래스

  • 데이터베이스 테이블과 매핑되는 자바 클래스/객체
  • 구조: EntityManagerFactory –생성–> EntityManager –관리–> Entity
  • 어노테이션을 사용 해서 설정
    @Entity: JPA가 관리 할 객체임을 명시
    @Table: 매핑할 데이타 베이스 테이블 이름 명시
    @Id : 기본 키 매핑
    @GeneratedValue : 기본키 매핑 전략
    @Column: 필드와 칼럼을 매핑

기본키 매핑 전략, 자동 생성

  • TABLE 전략: 채번 테이블을 사용
  • SEQUENECE 전략: 데이터베이스 시퀀스 사용 eg. Oracle
  • IDENTITY 전략: 기본키 생성을 데이터베이스에 위임 eg. MySQL
  • AUTO 전략: 선택한 데이터베이스 방언 통해 셋팅

복합키

  • @EmbeddedId : Entity 클래스의 필드에 지정
  • @Embeddable : 복합 키 식별자 클래스 에 지정

그외

@Temporal: 날짜 타입 매핑
@Transient : 특정 필드를 칼럼에 매핑 하지 않을 경우에 지정

연관 관계

  • Entity들은 대부분의 경우 다른 Entity들과 연관관계를 가짐
  • 데이타베이스 테이블은 외래키(FK)로 JOIN을 이용해서 관계 테이블을 참조
  • Entity는 객체 참조를 이용해서 연관된 Entity 참조
  • 연관관계 매핑 - 데이터베이스 테이블의 외래 키(FK)를 객체와 매핑 하는 것

연관 관계 (association)

  • 객체에서는 참조 변수로 가져감
  • 데이타베이스에서는 외래키로 JOIN을 이용해서 관계 테이블을 참조
  • @JoinColumn : 외래키 매핑

다중성(Multiplicity)

  • @OneToOne
  • @OneToMany
  • @ManyToOne
  • @ManyToMany

방향성

  • 단방향 (Unidirectional)
  • 양방향 (Bidirectional)
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
@Entity
public class Member {
@Id
@Column(name="member_id")
private Long memberId;

private String name;

@Column(name="created_dt")
private LocalDataTime createdDate;
}

@Entity
public class MemberDetail {
@Id
@Column(name = "member_detail_id")
private Long memberDetailId;

@ManyToOne(cascade = CascadeType.ALL)
@JoinColumn(name="member_id")
private Member member;

private String type;
private String description;
}

영속성 전이 (persistence cascade)

  • Entity의 영속성 상태 변화를 연관된 Entity에도 함께 적용되는 것
  • 연관관계의 다중성(Multiplicity) 지정 시 cascade 속성으로 설정
Cascade Type 설명
PERSIST Entity를 영속 객체로 추가 할때 연관된 Entity도 함께 영속 객체로 추가 한다.
REMOVE 함께 삭제
DETACH 함께 분리
REFRESH 다시 읽어 올때 함께 다시 읽어 온다
MERGE 준영속 상태에서 영속 상태로 변경 할때 함께 변경
ALL 모든 상태 변화에 함께 적용

페치 전략 (Fetch Strategy)

  • FetchType.EAGER
  • FetchType.LAZY
1
2
3
4
5
6
7
8
9
10
11
12
13
public class OrderEntity {
@OneToMany(
mappedBy = "order",
cascade = { CascadeType.ALL } // 영속성 전이
)
List<OrderItemEntity> orderItems = new ArrayList<>();
}

public class OrderItemEntity {
@JoinColumn(name="order_id")
@ManyToOne(fetch = FetchType.LAZY)
private OrderEntity order; // 관계의 주인
}

Spring Data

  • 다양한 데이터 저장소에 대한 접근을 추상화 하기 위한 Spring 프로젝트
  • JPA, JDBC, Redis, MongoDB, Elasticsearch 등

Spring Data JPA

  1. Repository 추상화를 통해 interface 선언만으로도 구현 가능
  2. 메서드 이름으로 쿼리 생성
  3. Web Support (페이징, 정렬, 도메인 클래스 컨버터 등)

Repository

  • Spring Data Repository
  • data access layer 구현을 위해 반복 작성, 유사 코드를 줄일수 있는 추상화 제공
1
2
3
4
5
6
7
8
9
10
11
12
ItemEntity entity1 = new ItemEntity(); 
entity1.setItemName("peach");
entity1.setPrice(135L);
entityManager.persist(entity1);

ItemEntity entity2 = entityManager.find(ItemEntity.class, entity1.getItemId());
entity2.setPrice(235L);
entityManager.merge(entity2);

//JPQL, Criteria API를 이용, 쿼리 수행
String jpql = "select item from ItemEntity item where item.itemName like '%peach%'";
List<ItemEntity> entities = entityManager.createQuery(jpql, ItemEntity.class).getResultList();
  • Repository 설정
1
2
3
public interface ItemRepository extends JpaRepository<ItemEntity, Long> {

}
  • 왠만한 CRUD, Pagination, Sorting 관련 메서드 제공
    Repository <T,ID> <–
    CrudRepository<T,ID> <–
    PagingAndSortingRepository<T,ID> <–
    JpaRepository<T,ID>
제공 메서드 SQL 구문
save insert/ update
findOne select
count select count(*)
delete delete

Spring Data JPA에서 제공 하는 메서드 이름으로 쿼리 생성
이름 규칙에 맞춰 interface에 선언하면 자동으로 쿼리 생성 해 준다.

1
2
3
4
5
6
7
8
9
// select * from Items where item_name like '%{itemName}%'
ItemEntity findBy`ItemName`Like(String itemName)

// select item_id from Items where item_name = '{itemName}'
// and price = {price} limit 1
boolean existsBy`ItemName`And`Price`(String itemName, Long price);

int countBy`ItemName`Like(STring itemName);
void deleteBy`Price`Between(long price1, long price2);

https://docs.spring.io/spring-data/jpa/docs/current/reference/html/#repository-query-keywords

복잡한 쿼리 작성

  • JPA에서 제공 하는 객체 지향 쿼리
  • JPQL: 엔티티 객체를 조회하는 객체 지향 쿼리
  • Criteria API: JPQL을 생성 하는 빌더 클래스
  • 3rd party: Querydsl, JOOQ, …

Pageable

웹에서 page 관련..
?page=0&item

출처: https://www.youtube.com/watch?v=XQZY0yN9gz0&t=2057s

(오키) 자바의정석, 2주차 챕터 7 - 객체지향 개념2

1. 상속

  • 기존의 클래스로 새로운 클래스를 작성 하는 것 (코드의 재사용)
  • 두 클래스를 부모와 자식으로 관계를 맺어 주는 것
1
2
3
class 자식클래스 extends 부모클래스 {
// ...
}

자식 —(extends/확장)—> 부모

1
2
3
4
5
6
7
8
class Point2D {
int x;
int y;
}

class Point3D extends Point2D {
int z;
}

3. 포함 관계 (Composite)

  • 클래스의 멤버로 참조 변수를 선언 하는 것
  • Cicle 안에 Point 의 참조 변수를 포함
1
2
3
4
5
6
7
8
9
10
11
12
13
class Circle {
int x, y, r;
}

class Circle {
Point c = new Point(); // 원점
int r; // 반지름
}

class Car {
Engine e = new Engine();
Door[] d = new Door[4];
}

차는 엔진과 4개의 도어를 포함

4. 클래스 간의 관계 결정 하기

  • 상속 관계 : A는 B이다. (is-a)
  • 포함 관계 : A는 B를 가지고 있다. (has-a)
1
2
3
4
5
6
7
8
class Circle {
point c = new Point();
int r;
}

class Circle extends Point {
int r;
}

대부분은 포함 일 것이다.

5. 단일 상속 (Single inheritance)

  • 자바는 단일 상속만 허용한다.
  • 조상은 하나만 허용 한다.
1
2
3
class TvDVD extends TV, DVD {  // 둘중에 하나만 가능

}
  • 비중이 높은 클래스하나만 상속 관계로 하고 나머지는 포함 관계로 하면
    다중 상속 처럼 구현 가능 하다.
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
class TV {
boolean power;
int channel;
void power() {power = !=power;}
}
class DVD {
boolean power;
void power() ..
void play() ..
void stop() ..
}
class TvDVD extends TV {
DVD dvd = new DVD();

void play () {dvd.play();}
...
}

6. Object 클래스 - 모든 클래스의 조상

  • 부모가 없는 클래스는 자동적으로 Object 클래스를 상속 받게 된다.
  • Object 클래스에 정의된 11개의 메소드를 상속 받는다.
  • toString(), equals(Object obj), hashCode() …

상속 계층도

  • SmartTV —> TV —> Object

7. 오버라이딩 (overriding)

  • 상속 받은 조상의 메서드를 자신에 맞게 변경 하는 것
  • 덮어 쓰기

8. 오버라이딩의 조건 3가지

9. 오버라이딩 vs. 오버로딩

  • 오버로딩 : 기존의 없는 메서드를 새로 정의
  • 오버라이딩 : 상속 받은 메서드의 내용을 변경, 재 정의

10. 참조 변수 super

  • 객체 자신을 가리키는 참조 변수

11. 조상의 생성자 super()

  • 생성자의 첫줄에 반드시 호출
  • 없다면 컴파일러가 자동으로 삽입 해줌
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
class Point {
int x;
int y;

point (int x, int y) {
this.x = x;
this.y = y;
}

String getLocation() {
return "x:"+x +"y:"+y;
}
}

class Point3D extends Point {
int z;
Point3D(int x, int y, int z) {
this.x = x;
this.y = y;
this.z = z;
}
String getLocation() {
return "x:"+x+"y:"+y+"z:"+z;
}
}

컴파일 에러 발생, Point3D 생성자 첫줄에 super() 넣어짐
Point 클래스 정의에 기본 생성자가 없어 에러 발생

12. 패키지 (package)

  • 서로 관련된 클래스의 묶음
  • .class
  • 실제 이름(Full name) -> java.lang.String
  • rt.jar 에 압축된 파일, JDK 설치경로\jre\lib에 위치 (Java 8 까지)
  • Java9 부터는 rt.jar 없어짐, 모듈 개념이 생겨서 더 작은 단위로 쪼갬
  • package 선언 없으면 default package에 들어가게 됨

14. 클래스 패스 (classpath)

  • 클래스 파일의 위치를 알려주는 경로
  • 환경변수 classpath로 관리, 경로간의 구분자는 ; 를 사용

15. import 문

  • java.lang 패키지의 클래스는 import 하지 않고도 사용 할숭 ㅣㅆ다.
  • String, Object, System, Thread…
  • import 패키지명.클래스명; 또는 import 패키지명.*;

16. static import 문

  • static 멤버를 사용 할때 클래스 이름 생략 가능
1
2
3
import static java.lang.Integer.*; // 클래스의 모든 static 메서드
import static java.lang.Math.random; // Math 클래스의 random()만
import static java.lang.System.out; // System.out을 out 만으로 참조가능

17. 제어자 (modifier)

  • 접근 제어자 public, protected, default, private
  • 그외 static, final, abstract, native, transient, synchronized, volatile, strictfp

20. abstract - 추상의, 미완성의

  • 클래스 : 추상 메서드가 선언되어 있음을 의미한다.
  • 메서드 선언부만 작성하고 구현부는 작성 하지 않은 추상 메서드임을 알린다.
    추상 클래스의 인스턴스 생성 불가
1
2
3
abstract class AbstractTest {
abstract void move();
}

21. 접근 제어자

  • private 같은 클래스내에서만
  • default 같은 패키지내에서만
  • protected 같은 패키지내, 다른 패키지의 자손
  • public 접근 제한 없음

22. 캡슐화와 접근 제어자

접근 제어자를 사용하는 이유

  • 외부로부터 데이터를 보호 하기 위해서

23. 다형성 (polymorphism)

  • 여러가지 형태를 가질수 있는 능력
  • 조상 타입 참조 변수로 자손 타입 객체를 다루는 것

‘Tv t = new SmartTV();’ 타입 불일치 하지만 다룰수 있는 것

24. 참조 변수의 형 변환

  • 사용 할수 있는 멤버의 갯수를 조절 하는 것
  • 조상 자손 관계의 참조 변수는 서로 형변환 가능
  • 상속 관계가 아닌 클래스 간의 형 변환 불가

조상의 객체를 자식의 참조변수 대입 할때 명시적 형변환 하면 컴파일 에러는 안 생기시지만
런타임에서 형변환 실행 에러 가 발생 함. java.lang.ClassCastException

26. instanceof 연산자

  • 참조 변수의 형변환 가능여부 확인에 사용, 가능하면 true 반환
  • 형변환 전에 반드시 instanceof로 확인해야 함
1
2
3
4
5
6
7
void doWork(Car c) {
if (c instanceof FireEngine) {
FireEngine fe = (FireEngine) c;
fe.water();
...
}
}

다형성 정리

  1. 조상 = 자손 (예: Tv t = new SmartTV();)
  2. 참조 변수의 형변환 - 리모콘 바꾸기, 사용 가능한 멤버 갯수 조절
  3. instanceof 연산자 - 형변환 가능 여부 확인

27. 매개변수의 다형성

  • 참조형 매개변수는 메서드 호출시, 자신과 같은 타입 또는 자손 타입의 인스턴스를 넘겨 줄수 있다.
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
class Product {
int price;
int bonusPoint;
}

class Tv extends Product {}
class Computer extends Product {}
class Audio extends Product {}

class Buyer {
int money = 100;
int bonusPoint = 0;
}

// 각각의 Product 종류 마다 buy 메서드 작성
void buy(Tv t) {
money -= t.price;
bonusPoint += t.bonusPoint;
}

// 아래 처럼 매개변수의 다형성 사용 하면 하나의 buy 메서드로 처리 가능 해짐
void buy(Product p) {
money -= p.price;
bonusPoint += p.bonusPoint;
}

29. 여러 종류의 객체를 배열로 다루기

  • 조상 타입의 배열에 자손들의 객체를 담을 수 있다.
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
Product p1 = new Tv();
Product p2 = new Computer();
Product p3 = new Audio();

Product p[] = new Product[3];
p[0] = new Tv();
p[1] = new Computer();
p[2] = new Audio();

public class Vector extends AbstractList
implments List, Cloneable, java.io.Serializable
{
protected Object elementData[];

}

31 추상 클래스 (abstract class)

  • 미완성 설계도. 미완성 메서드를 갖고 있는 클래스
  • 다른 클래스 작성에 도움을 주기 위한 것. 인스턴스 생성 불가
  • 상속을 통해 추상 메서드 완성
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
abstract class Player { // 추상 클래스, 미완성
boolean pause;
int currentPos;

Player() {
pause = false;
currentPos = 0;
}

abstract void play(int pos); // 추상 메서드 {}, 몸통 없음
abstract void stop();
}

Player p = new Player(); // 에러

class AudioPlayer extends Player {
void play(int pos) { /* ... */ }
void stop() { /* ... */ }
}

AudioPlayer ap = new AudioPlayer(); // 인스턴스 생성

32 추상 메서드 (abstract method)

  • 미완성 메서드. 구현부 몸통 {} 없는 메서드
  • 꼭 필요하지만 자손 마다 다르게 구현 될것으로 예상 되는 경우 사용
1
2
3
abstract class AbstractPlayer extends Player { // Player가 2개 추상 메서드
void play(int pos) { /* ... */ } // 1개만 구현 했음. 그래서 이 클래스도 abstract
}

33,34 추상 클래스의 작성

  • 상속 받는 자식 클래스가 꼭 구현해야 하는 메서드를 명시적으로 강제
  • 기존 클래스의 공통 부분을 뽑아서 추상 클래스를 만듬
  • 추상화 <-> 구체화
  • 추상화된 코드는 구체화된 코드보다 유연하다. 변경에 유리
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
GregorianCalendar cal = new GregorianCalendar(); // 구체적
Calendar cal = Calendar.getInstance(); // 추상적

public static Calendar getInstance(Local aLocale) {
return createCalendar(TimeZone.getDefault(), aLocale);
}

private static Calendar createCalendar(TimeZone zone, Local aLocale) {
// ...
if(caltype == 'budda') // 에 따라서 다른 caledar

else if (caltype == 'japanese')

else if (caltype == 'western')
}

35 인터페이스 (interface)

  • 추상 메서드의 집합
  • 구현된 것이 전혀 없는 설계도. 껍데기 (모든 멤버가 public)
1
2
3
4
5
6
7
8
9
10
11
12
13
14
interface 인터페이스이름 {
public static final 타입 상수이름 = 값; //변수 iv, cv 안됨 오직 상수만
public abstract 메서드이름(매개변수목록); // 추상 메서드
}

interface PlayingCard {
public static final int SPADE = 4;
final int DIAMOND = 3;
static int HEART = 2; // public 이 생략됨
int CLOVER = 1; // final static 이 생략 됨

public abstract String getCardNumber();
String getCardKind(); // public abstract 이 생략 됨
}
  • 인터페이스의 조상은 인터페이스만 가능 (Object가 최고 조상 아님)
  • 다중 상속이 가능 (추상 메서드는 충돌 해도 문제 없음)
1
2
3
4
5
6
7
8
inteface Fightable extends Movable, Attackable { }
interface Movable {
void move(int x, int y);
}

interface Attackable {
void attack(Unit u);
}

37 인터페이스 구현

  • 인터페이스에 정의된 추상 메서드를 완성 하는 것
1
2
3
4
5
6
7
8
9
class 클래스이름 implements 인터페이스이름 {
// 인터페이스에 정의된 추상 메서드를 모두 구현 해야 한다.
}

class Fighter implements Fightable
{
public void move(int x, int y) { /* .. */ }
public void attack(Unit u) { /* .. */ }
}
  • 일부만 구현하는 경우, 클래스 앞에 abstract를 붙히면 됨
1
2
3
abstract class Fighter2 implements Fightable {
public void move(int x, int y) { /* .. */ }
}

정리

  • Q 인터페이스란?

(핵심) 추상 메서드의 집합
static 메서드, 디폴드 메서드가 JDK 1.8에 추가

  • Q 인터페이스 구현이라?

추상 메서드 몸통{} 만들기, 미완성 설계도 완성

  • Q 추상 클래스와 인터페이스의 공통점은?

추상 메서드를 가지고 있다 (미완성 설계도)

  • Q 추상 클래스와 인터페이스의 틀린점은?

cv, iv 을 가질수 없다

38 인터페이스를 이용한 다형성

  • 인터페이스도 구현 클래스의 부모
  • 인터페이스 타입 매개변수는 인터페이스 구현한 클래스의 객체만 가능
  • 인터페이스를 메서드의 리턴타입으로 지정 할수 있다

39 인터페이스의 장점1

  • 두 대상 객체간의 연결 대화 소통을 돕는 중간 역할 을 한다
  • 선언(설계)와 구현을 분리 시킬수 있게 한다
  • 인터페이스 덕분에 B가 변경 되어도 A는 안 바꿀수 있게 된다. (느슨한 결합)

39 인터페이스의 장점2

  • 개발 시간을 단축
  • 변경에 유리한 유연한 설계 가능
  • 표준화 가능
  • 서로 관계 없는 클래스들에 대해 관계를 맺어 줄수 있다 (Collection의 상속 계층도)
    예:

Unit <-상속- GroundUnit, AirUnit
GroundUnit <-상속- Marine, SCV, Tank
Air Unit <-상속- Dropship
Repairable <-구현- SCV, Tank, Dropship

1
2
3
4
5
6
7
8
void repair(Repairable r) {
if (r instanceof Unit) {
Unit u = (Unit) r;
while (u.hitPoint != u.Max_UP) {
u.hitPoint++;
}
}
}

40 디폴트 메서드와 static 메서드

  • 인터페이스에 디폴트 메서드, static 메서드 추가 가능 (JDK1.8 부터)
  • 인터페이스에 새로운 메서드 (추상 메서드)를 추가 하기 어려움

해결책 => 디폴트 메서드 (default method) 소개

  • 디폴트 메서드는 인스턴스 메서드 (사실 인터페이스 원칙 위반)
1
2
3
4
5
6
7
8
9
interface MyInterface {
void method();
void newMethod(); // 추상 메서드
}

interface MyInterface {
void method();
default void newMethod() { /* .. */ }
}
  • 디폴트 메서드가 기존의 메서드와 충돌 할때

오버라이딩 원칙으로 동작 (즉 구현된 클래스의 메서드가 있으면 그게 호출 됨)

42 내부 클래스 (inner class)

  • 클래스 안의 클래스
1
2
3
4
5
6
class A { // 외부 클래스

class B { // 내부 클래스
// 객체 생성 없어도 A의 멤버 접근 가능
}
}
  • 장점
  1. 내부 클래스에서 외부 클래스의 멤버들을 쉽게 접근 할수 있다
  2. 코드의 복잡성을 줄일수 있다 (캡슐화)

43,44 내부 클래스의 종류와 특징

  • 내부 클래스의 종류와 유효범위는 변수와 동일
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
class Outer {
int iv =0; // --> 1
static int cv =0; // --> 2

void myMethod() {
int lv=0; // --> 3
}
}

class Outer {
class InstanceInner {} // --> 1
static class StaticInner {} // --> 2

void myMethod() {
class LocalInner {} // --> 3
}
}

45 내부 클래스의 제어자와 접근성

  • 내부 클래스의 제어자는 변수에 사용 가능한 제어자와 동일

46 내부 클래스의 제어자와 접근성 예제 1

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25

class Example {

// 인스턴스 내부 클래스
class InstanceInner {
int iv = 100;
static int cv = 100; // 에러
final static int CONST = 100; // final static은 상수임으로 허용
}

// Static 내부 클래스
static class StaticInner {
int iv = 200;
static int cv = 200; // static 클래스에만 static 멤버 정의 강의
}

void myMethod() {
// 지역 내부 클래스
class LocalInner {
int iv = 300;
static int cv = 300; // 에러
final static int CONST = 300; // final static은 상수임으로 허용
}
}
}

JDK 1.8 부터 지역변수가 변경 안하면 final 로 자동으로 잡아줌, constant pool

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
class Example {
public static void main(String[] args) {
Outer2 oc = new Outer2(); // 외부 클래스의 인스턴스 생성 해야
Outer2.InstanceInner ii = oc.new InstanceInner(); // 내부 클래스 생성 가능

Outer2.StaticInner.cv;
Outer2.StaticInner si = new Outer2.StaticInner();
}
}

class Outer2 {
class InstanceInner {
int iv = 100;
}
static class StaticInner {
int iv = 200;
static int cv = 300;
}
void myMethod() {
class LocalInner {
int iv = 400;
}
}
}

51 익명 클래스 (anonyumous class)

  • 이름이 없는 일회용 클래스. 정의와 생성을 동시에
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
new 조상클래스이름() {
// 멤버 선언
}
// 또는
new 구현인터페이스이름() {
// 멤버 선언
}

class Example {
Object iv = new Object() { void method() {} }; // 익명 클래스
static Object cv = new Object() { void method(){} };

void myMethod() {
Object lv = new Object() { void method(){} };
}
}

이력서, 포토폴리오, 면접

서비스 회사

SI -> 스타트업 -> 서비스업체

마음가짐

  • 개발 좋아하는가?
  • Deep Deive ?
  • 팀플에 자신?
  • 개발자 들 사이 인기?

준비사항

  • 코테 (해커랭크), 알고리즘, 자료구조, 과제전형 준비
  • 최신 트렌드, 기술: Kotlin, js (react, vue), MVP 때문에
  • 개인 프로젝트 github 공유, idea를 구현한 사례
  • 팀프로젝트: 찾아서… 경험

이력서 다듬기

  • 철저히 기술 중심으로 작성, 수행 프로젝트 나열 X
  • 스토리 텔링 (문제 해결 방법), (성능 개선했던 스토리), 갈등 상황 극복 했던 스터리
  • 예: 병렬 구간 어떻게 해서 찾았습니다. API 별 시간을 재겨나, DB 카디널리티를 확인, LIVE DB에서 확인 방법, 갈등 구조에서 안 딸아오는 멤베에서 조그마한 과제를 주어서 좀더 큰 과제를 주었다. 등..
  • 예2: 팀 프로젝트 해서 서비스 런치 운영 경험, 부하 테스트 해서 대용량 서비스 경험, MAU, 동접 > 시뮬레이션 테스트 하고 DB 병목, API 병목, Auto Scale, 등등 어떻게 해결 했다.

서류 전형

  • Job Description 에 나온 기술과 매치 되는 회사에 지원
  • 서류 합격 되면, 서비스에 대해 deep 분석

면접 준비

  • 기술 스택에 대해 자세히 공부 (예: 싱글 쓰레드인데 중요한건 뭐죠?)
  • 보통은 이력서 내용을 기반으로 질문
  • 면접관 경험 있는 분과의 리뷰

https://www.youtube.com/watch?v=OL0eRT32hFI

흔한 채용 정보

우대사항

  • AWS를 활용한 개발, 운영 경험이 있으신 분

  • 빌드/테스트/배포 자동화 경험이 있으신 분

이동욱님 책에 단위 테스트 연습

  • Microservices 아키텍처 기반의 시스템 개발 유 경험자

  • Open API 기반 서버 시스템의 개발 및 운영 경험이 있으신 분

  • JPA, Hibernate등 ORM 사용과 도메인 모델링 경험

코사 - 소프트웨어기술자 경력관리시스템에 등록 하자

학습노트1 - 개발환경 셋팅

언어와 프레임워크로 웹개발

책이 2019년 하반기에 출판, 집필은 2018년으로 생각 되는데 서문에 대학생들에 물어보았을때
많이 쓰이는 조합이 4가지라고 들었다고 한다.

  1. PHP
  2. NodeJS 와 Express 프레임워크
  3. Python 과 Django 프레임워크
  4. Ruby와 Rails 프레임워크

자바와 스프링 프레임워크은 없었고 이유가 어렵고, 복잡하고 거추장 스럽다는 것이었다. 이는 최근에는 스프링 부트가 나와서 해소 되었으리라 보인다.

국내 선망의 IT 회사 (네이버, 카카오, 라인 등), 티몬, 쿠팡, 우아한 형제들등 스타트업, 서비스가 커지자 자바와 스프링 기반으로 전환을 많이 한다고 한다.

책 구성

  1. 1~5장: 스프링 부트, JPA, 스프링 시큐리티, JUnit, 객체지향 프로그래밍
  2. 6~7장: AWS 인프라, 기본 사용법 및 설정 (EC2, RDS)
  3. 8~10장: 스프링 부트 프로젝트를 AWS 인프라에 배포, 무중단 배포 환경

GitHub: http://bit.ly/fr-springboot

Spring Boot가 2.1 -> 2.4로, IntelliJ IDEA가 2019 -> 2020 의 변경 내역 정리글
https://jojoldu.tistory.com/539
Issues: https://github.com/jojoldu/freelec-springboot2-webservice/issues

만들게 되는 웹 애플리케이션

게시판 기능

  1. 게시글 조회
  2. 게시글 등록
  3. 게시글 수정
  4. 게시글 삭제

회원 기능

  1. 구글/네이버 로그인
  2. 로그인한 사용자 글 작성 권한
  3. 본인 작성 글에 대한 권한 관리

개발 환경

인텔리J 추천 하며 다만 HTML, CSS은 VS Code

Github 연결

인텔리J Ctrl+Shift+A 하면 Actions 검색창 열리고 share project on github을 검색
깃허브 연결

플러그인 설치 .ignore

Actions 검색창 > plugins > .ignore 찾아 설치
Alt+Insert > .ignore 파일 생성 > .idea 와 .gradle 체크

프로젝트 빌드를 Intellj 로 설정

Gradle 로 되어 있는데 바꾸어 주면 더 빨리짐

Github 에 커밋 하기

Ctrl+Shift+k

스프링 기초 - 1

View 환경 설정

스프링 부트가 제공 하는 Welcome Page

정적 페이지 로 resources/static/index.html

스프링 웹 개발 기초

  1. 정적 컨텐츠
  2. MVC와 Template 엔진
  3. API

MVC와 Template 엔진

기본 Flow : client가 Get 으로 URL 노드에 요청

  1. @Controller 클래스
  2. @GetMapping 으로 연결된 함수
  3. 함수 실행, Model model 에 Data를 채움 (MVC에 그 Model임)
  4. 함수가 가야 하는 View 파일 이름을 반환 함
  5. ViewResolver가 Thymeleaf 템플릿 엔진으로 가는 것임을 감지
  6. resources/templates/{파일이름}.html 에 model 데이타 치환, 생성
  7. client가 만들어진 html 받아 봄