[새싹 x 코딩온] 웹 풀스택 영등포 5기 20주차 회고 - 1

용가리🐉·2023년 12월 12일
0
post-thumbnail

📌 Wrapper 클래스

8가지 기본 자료형(primitive type)을 객체로 표현하기 위해 제공되는 클래스

  • 객체로서 다양한 메서드와 속성을 사용
  • 포장하고 있는 기본 타입은 외부에서 변경할 수 없으며, 객체로 생성하는데 목적이 있음
  • 포장 객체를 생성하기 위한 클래스는 java.lang 패키지에 포함되어 있음

📣 사용 이유

  • 컬렉션 저장
    • 자바의 컬렉션(ex. ArrayList)은 기본 데이터 타입 직접 저장 불가
    • 기본 데이터 타입을 저장하고 싶을 때 Wrapper 클래스 사용
  • null 값 허용
    • 기본 데이터 타입은 null 값을 가질 수 없음
    • 어떤 값이 없거나 알 수 없는 경우를 표현하고 싶을 때, Wrapper 클래스는 null 값을 가질 수 있어 유용함
  • 메서드와 유틸리티
    • Wrapper 클래스는 문자열 변환, 값 비교와 같은 유용한 메서드들 제공
  • 메서드의 매개변수
    • 메서드에 객체를 매개변수로 전달 혹은 반환 시, Wrapper 클래스가 유용

📣 오토박싱과 오토언박싱

  • auto-boxing : 기본 데이터 타입을 Wrapper 클래스 객체로 자동 변환
  • auto-unboxing : Wrapper 클래스 객체를 기본 데이터 타입으로 자동 변환
ArrayList<Integer> numbers = new ArrayList<>();
numbers.add(1); // 오토박싱으로 int가 Integer로 변환되어 저장
numbers.add(2);
int sum = numbers.get(0) + numbers.get(1); // 오토언박싱으로 Integer가 int로 변환
System.out.println("합계: " + sum);

📣 포장 값 비교

  • 포장 객체는 값 비교를 위해 ==, != 연산자 사용 불가능 → 참조값을 비교하기 때문
  • equals() 메소드로 내부 값 비교
  • 포장 객체의 효율적인 사용을 위해 아래 범위의 값을 갖는다면 포장 객체는 공유됨 (이 외의 값은 내부 값이 아닌 참조값을 비교함을 주의할 것)

📌 제네릭

결정되지 않은 타입을 파라미터로 처리하고, 실제 사용 시 파라미터를 구체적인 타입으로 대체시키는 기능

  • 자바에서 형 안전성(type safety)을 높이기 위해 도입된 프로그래밍
  • 컴파일 시간에 타입 오류를 더욱 효과적으로 찾아낼 수 있으며 클래스, 인터페이스, 메서드에 대한 타입을 파라미터로 전달할 수 있게 해줌
// Container 클래스에서 something 필드의 타입은 아직 결정되지 않음
public class Container<T> {
	public T something;
}

// Container 클래스 사용 시, 구체적인 타입(Integer)으로 대체
Container<Integer> c1 = new Container<Integer>;
c1.something = 100;

📣 장점

  • 타입 안전성: 잘못된 타입의 객체가 저장되는 것을 컴파일 시간에 방지
  • 형 변환 필요성 감소: 명시적인 형 변환이 필요 없어짐
  • 코드 재사용성: 일반 클래스나 메서드로 다양한 타입에 대해 동작하는 코드 작성 가능

📣 타입

  • 결정되지 않은 타입을 파라미터로 가지는 클래스와 인터페이스
  • <> 괄호 안에는 일반적으로 대문자와 알파벳으로 작성
public class 클래스명<T>
public interface 인터페이스명<E>

📣 예시

  • addElement()에는 원하는 타입의 데이터 삽입 가능
public class MyCustomList<T> {
	ArrayList<T> list = new ArrayList<>();
    
    public void addElement(T element) {
    	list.add(element);
    }
    
    public void removeElement(T element) {
    	list.remove(elememt);
    }
}
  • 두 개의 아이템을 출력하는 메서드
class Utility {
 public static <T> void printPair(T first, T second) {
 	System.out.println("(" + first + ", " + second + ")");
 }
 
 public static void main(String[] args) {
 	printPair("apple", "banana");
    printPair(1, 2);
    printPair(1.5, 2.5);
 }
}

📣 제한된 타입 파라미터 (bounded type parameter)

  • 모든 타입으로 대체될 수 없고, 특정 타입과 자식 or 구현 관계에 있는 타입만 대체할 수 있는 타입 파라미터
  • extends 키워드를 제네릭으로 사용 시, 해당 타입 파라미터에 대한 상한을 지정할 수 있음
    • 타입 파라미터가 특정 클래스의 서브 클래스, 또는 특정 인터페이스의 구현 클래스만 가능하도록 제한 가능

🟠 사용법

// <T extends 제한 타입>
<T extends Number>

📣 와일드 카드 (?)

  • 제네릭 타입을 매개값 혹은 리턴 타입으로 사용 시, 타입 파라미터로 ? 사용 가능
  • 제네릭에서 와일드카드(?)'알 수 없는 타입'을 의미함
  • 와일드카드는 제네릭 코드에서 더 큰 유연성을 얻기 위해 사용되며 특히 제네릭 메서드나 제네릭 클래스에서 다양한 제네릭 타입 처리 시 유용하게 사용됨

🟠 사용법

  • ?(Unbounded Wildcard): 어떠한 타입도 될 수 있음
  • ? extends T(Upper Bounded Wildcard): T 타입 또는 T의 서브타입
  • ? super T(Lower Bounded Wildcard): T 타입 또는 T의 슈퍼타입

📌 Collection

데이터 구조와 알고리즘을 제공하는 프레임워크

  • 객체의 그룹을 효율적으로 관리하기 위한 다양한 클래스와 인터페이스 제공
    • 객체들을 효율적으로 추가, 삭제, 검색할 수 있도록 인터페이스와 클래스들을 java.util 패키지에 포함
  • 컬렉션 프레임워크의 주요 인터페이스
    • Collection
      • 가장 기본적인 인터페이스
      • 모든 컬렉션 클래스가 이를 구현
    • List
      • 순서가 있는 데이터의 집합을 다룰 때 사용
      • 데이터 중복 허용
    • Set
      • 순서가 없는 데이터의 집합을 다룰 때 사용
      • 데이터 중복 불허
    • Map
      • 키와 값의 쌍으로 데이터 저장
      • 키는 중복 X

📣 Collection Framework 상속 구조

  • List, Set
    • 객체를 추가, 삭제, 검색하는 방법에 공통점이 있어 공통된 메소드만 따로 모아 Collection 인터페이스로 정의해두고 이를 상속받음
  • Map
    - 키와 값을 쌍으로 묶어서 관리하는 구조
    - List, Set과 사용법이 다름

📣 List

🟠 ArrayList

  • List 인터페이스의 동적 배열 구현
  • 초기 크기가 있지만, 요소가 추가됨에 따라 자동으로 크기가 확장됨
  • 배열 기반 → 인덱스를 사용한 요소 접근이 빠르지만, 중간에 요소를 삽입하거나 삭제하는 연산은 느린 편

🟠 LinkedList

  • List와 Deque 인터페이스의 양방향 연결 리스트 구현
  • 연결 리스트 기반 → 중간에 요소를 삽입하거나 삭제하는 연산이 빠르지만, 인덱스를 사용한 요소 접근은 느린 편

📣 Set

  • List와 달리 중복된 요소를 저장할 수 없으며 순서를 보장하지 않는 컬렉션
  • Set 컬렉션에서 공통적으로 사용 가능한 Set 인터페이스 메소드
    • 객체 추가
      • boolean add(E e) : 주어진 객체를 저장(중복된 요소가 없다면 true, 있으면 false 반환)
    • 객체 검색
      • boolean contains(Object o) : 주어진 객체가 저장되었는지 여부
      • _isEmpty()_ : 컬렉션이 비어 있는지 여부
      • Iterator<E> iterator() : 저장된 객체를 한 번 씩 가져오는 반복자 리턴
      • int size() : 컬렉션에 저장된 전체 객체 수 리턴
    • 객체 삭제
      • void clear() : 저장된 모든 객체 삭제
      • boolean remove(Object o) : 주어진 객체를 삭제

🟠 HashSet

  • Set의 대표적인 클래스
  • 해시 테이블을 사용하여 요소 저장
  • 순서를 보장하지 않으며, 동일한 객체는 중복 저장하지 않음

🟠 LinkedHashSet

  • HashSet을 확장하여 요소의 삽입 순서 기억
  • 요소의 삽입 순서대로 반복

🟠 TreeSet

  • 자동으로 정렬된 순서로 요소 저장
  • 사용자 정의 정렬도 가능

📣 Map

  • 키와 값으로 구성된 엔트리(Entry) 객체를 저장하는 데이터 구조
  • 키는 고유해야 하며, 값을 중복될 수 있음
  • Map 컬렉션에서 공통적으로 사용 가능한 Map 인터페이스
    • 객체 추가
      • V put(K key, V value) : 주어진 키와 값 추가, 저장이 되면 값을 리턴
    • 객체 검색
      • boolean containsKey(Object key) : 주어진 키가 있는지 여부
      • boolean containsValue(Object value) : 주어진 값이 있는지 여부
      • Set<Map.Entry<K,V>> entrySet() : 키와 값을 쌍으로 구성된 모든 Map.Entry 객체를 Set에 담아 리턴
      • V get(Object key) : 주어진 키의 값을 리턴
      • boolean isEmpty() : 컬렉션이 비어 있는지 여부
      • Set<K> keySet() : 모든 키를 Set 객체에 담아서 리턴
      • int size() : 저장된 키의 총 개수를 리턴
      • Collection<V> values() : 저장된 모든 값 Collection에 담아서 리턴
    • 객체 삭제
      • void clear() : 모든 Map.Entry(키와 값)를 삭제
      • V remove(Object key) : 주어진 키와 일치하는 Map.Entry 삭제, 삭제되면 값을 리턴

🟠 HashMap

  • 해시 테이블을 사용하여 키-값 쌍을 저장
  • 순서를 보장하지 않음

🟠 LinkedHashMap

  • HashMap을 확장하여 키-값 쌍의 삽입 순서나 접근 순서를 기억
  • 순서가 중요한 경우에 유용

🟠 TreeMap

  • 키에 따라 자동으로 정렬됨

📌 Spring

엔터프라이즈용 Java 애플리케이션 개발을 편하게 할 수 있게 해주는 오픈소스 경량급 애플리케이션 프레임워크

  • 엔터프라이즈용 Java 애플리케이션 : 대규모의 복잡한 데이터를 관리하는 애플리케이션
  • 경량급 : 기존 기술 대비 개발자가 작성할 코드가 상대적으로 단순
  • 애플리케이션 프레임워크 : 애플리케이션을 개발하는 데에 필요한 코드들의 뼈대를 제공

  • Java 웹 프레임워크로 Java 언어를 기반으로 함
  • Java 기반의 웹 어플리케이션을 만들 수 있는 백엔드 프레임워크
  • 수많은 국내 기업과 해외 기업에서 많이 사용하는 프레임워크

📣 구조

📣 특징

🟠 IoC (Inversion of Control, 제어의 역전)

  • 객체의 생성부터 소멸까지 개발자가 아닌 스프링 컨테이너가 대신해주는 것
  • 제어권이 개발자가 아닌 IoC에 있으며, IoC가 개발자의 코드를 호출해 필요한 객체를 생성, 소멸해 생명주기를 관리함
  • 예시
    • Java에서 객체 생성
      class Sample {
      	private Apple apple = new Apple();
      }
    • 스프링 컨테이너가 객체 관리
      • Apple 객체의 제어권이 Sample에 있는 것이 아닌, SampleTest 클래스에 있음
        의존성을 역전시켜서 제어권을 직접 갖지 않는 것이 IoC

        class Sample {
        	private Apple apple;
            
            public Sample(Apple apple) {
            	this.apple = apple;
            }
        }
        
        class SampleTest {
        	Apple apple = new Apple();
            Sample sample = new Sample(apple);
        }

🙌 정리

  • 즉, new로 일일이 객체를 생성하지 않아도 됨!
// 클래스 A에서 new 키워드로 클래스 B의 객체를 생성
public class A {
	b = new B();
}

// IoC를 적용한다면
// B 객체를 생성하지 않음 -> 그럼에도 어디선가 객체를 받아와서 b에게 할당함
public class A {
	private B b;
}

🟠 DI (Dependency, 의존성 주입)

  • 구성 요소의 의존 관계가 소스코드 내부가 아닌 외부의 설정 파일을 통해 정의됨 → 외부에서 객체를 주입 받아 사용
  • DI (의존성 주입) 방법으로 IoC (제어의 역전)를 구현
    → 이를 통해 코드 간의 재사용률을 높이고, 모듈 간의 결합도를 낮출 수 있음

의존성이란?

  • save, delete 구현을 위해서는 FileBoardPersistence 가 필요함
  • BoardService 클래스가 FileBoardPersistence 클래스에 의존
  • 기획이 변경되어 파일이 아닌 데이터베이스에 게시글을 저장해야 한다면, FileBoardPersistence 클래스에 의존하는 클래스 모두를 수정해야 함 → 의존성 주입 등장 배경

📎 방법 1. Field Injection (필드 주입)

@Autowired
private FieldService fieldService;

📎 방법 2. Setter Injection (수정자 주입)

private SetterService setterService;

@Autowired
public void setSetterService(SetterService setterService) {
	this.setterService = setterService;
}

📎 방법 3. Constructor Injection (생성자 주입)

private final ConstructorService constructorService;

@Autowired
public ExampleComponent(ConstructorService constructorService) {
	this.constructorService = constructorService;
}

🟠 AOP (Aspect Object Programming, 관점 지향 프로그래밍)

  • 여러 객체에 공통으로 적용할 수 있는 기능을 구분함으로써 재사용성을 높여주는 기법
    • 어떤 로직을 기준으로 "핵심 관점", "부가 관점"으로 나누어서 보고 그 관점을 기준으로 각각 모듈화
    • 기능을 비즈니스 로직공통 모듈로 구분한 후, 개발자의 코드 밖에서 필요한 시점에 비즈니스 로직을 삽입하여 실행되도록 함
  • ex. 계좌 이체입출금 로직을 처리할 때 공통적으로 로깅보안 작업을 수행해야 함
    • 일반적으로 이 경우, 공통의 코드두 개의 로직에 모두 넣고 사용함
    • AOP는 공통 관심(로깅, 보안)을 따로 빼내어 객체 별로 처리하는 것이 아닌 관점 별로 외부에서 접근해 사용하도록 만듦

      → 개발자는 핵심 관점 코드에만 집중할 수 있음

🟠 POJO (Plain Old Java Object, 단순한 자바 오브젝트)

  • 객체 지향적인 원리에 충실하면서 환경과 기술에 종속되지 않고 필요에 따라 재활용될 수 있는 방식으로 설계된 오브젝트
  • 다른 기술을 사용하지 않고 순수 Java만을 통해서 생성한 객체
  • ex. 필드, getter, setter 만 존재하는 기본적인 Java 오브젝트
class Person {
	private String name;
    
    public String getName() {
    	return name;
    }
    
    public void setName(String name) {
    	this.name = name;
    }
}
  • 외부 라이브러리를 import 해서 특정 객체(POJO가 아닌 객체)를 사용한다면, 해당 기술이 deprecated(더 이상 사용되지 않음) 되거나 새로운 기술로 변경되면 관련 코드를 모두 변경해야 하는 번거로움이 발생함 → 해당 객체가 외부 라이브러리에 의존적인 상황은 좋지 않음

📌 Spring Boot란?


쉽고 빠르게 Spring 프레임워크를 사용할 수 있는 도구

  • Spring은 필요한 여러 설정 (ex. 톰캣 서버 설정, XML 설정, ...) 이 복잡하다는 단점이 있음
  • Spring Boot는 Spring에 속해 있음

📣 주요 특징

  • WAS 내장 되어 있어 독립적으로 실행 가능
    • WAS (Web Application Server): 웹 애플리케이션 실행 장치
    • 내장된 WAS는 톰캣, 제티 등 여러 옵션 중 선택 가능
  • 스프링 부트 스타터
    • 개발에 필요한 빌드 구성을 단순화하는 스프링 부트 스타터 제공
  • 애플리케이션 설정을 XML이 아닌 Java 코드 작성 가능
    • 개발자가 더 직관적이고 유연하게 애플리케이션 설정 가능
  • JAR 이용해 자바 옵션 만으로도 배포 가능
    • JAR (Java Archive) 파일: 애플리케이션과 의존 라이브러리들을 하나의 파일로 묶은 형태, 배포 및 실행 환경에서 별도의 설정이 필요 없다는 장점 (애플리케이션 이식성과 배포 과정 단순화)
    • JAR 파일로 패키징해 배포 가능
profile
자아를 찾아 떠나는 중,,,

0개의 댓글

관련 채용 정보