[GO SOPT] 1차 세미나

devguri·2023년 4월 20일
0
post-thumbnail

📌Java와 객체 지향 프로그래밍의 이해

✍️SOLID 원칙

SRP 단일 책임 원칙

  • 한 클래스는 하나의 책임만 가져야 한다.
  • 중요한 기준은 변경! 변경 있을 떄, 한 부분만 변경가능하면 단일 책임 원칙 잘 지킨 것
  • ex) 객체의 생성과 사용을 분리

OCP 개방-폐쇄 원칙

✅ 확장은 열려있고, 변경은 닫혀 있다.

  • 뼈대로 만든 인터페이스는 변경하지 않아야 하고, 인터페이스를 확장하여 새로운 기능을 구현하고 새로운 여러 객체를 만들 수 있어야함
  • 다형성을 활용하기
  • 인터페이스를 구현한 새로운 클래스를 하나 만들어서 새로운 기능을 구현 (인터페이스는 변경되는 것이 아니고, 구현하는 클래스 하나를 만들면서 확장하는 것)

LSP 리스코프 치환 원칙

  • 프로그램의 객체는 정해진 원칙과 규칙을 지키면서 코드를 짜야한다.
  • 다형성에서 하위 클래스는 인터페이스 규약을 다 지켜야 하는 것
  • 단순 컴파일 성공하는 것이 안리ㅏ 원칙을 따르는 것

ISP 인터페이스 분리 원치

  • 특정 클라이언트를 위한 인터페이스 여러개가 범용 인터페이스 하나보다 낫다.
  • 인터페이스 하나도 그 기능을 나눠서 여러 클라이언트가 관리할 수 있도록 분리하는 것이 효과적임
  • 인터페이스가 명확해지고 대체 가능성이 높아진다.

DIP 의존관계 역전 원칙

✅ 클라이언트 클래스가 구현 클래스가 아닌 인터페이스를 바라보도록 해야한다.

  • 프로그래머는 추상화에 의존해야지 구체화에 의존하면 안된다는 원칙을 따르는 방법 중 하나다. (인터페이스에 의존)
  • 역할에 의존하게 해야하는 것과 같다. 클라이언트가 인터페이스에 의존해야 유연하게 구현체 변경할 수 있다.

-> 이 MemberService 클라이언트는 인터페이스와 구현 클래스에도 동시에 의존해서 문제가 생긴다.

💡 의존한다는 것 : 현재 구현한 클래스를 알고 있다는것

클래스와 인스턴스

  • 클래스 : 필요한 속성과 행위를 멤버변수와 메서드로 정의하는 것, 객체 만들어내기 위한 틀
  • 인스턴스 : 클래스를 정의한 것으로 실제 메모리를 할당받아 데이터화 한 객체 (실제로 사용하는 것)

변수 할당 방식

  1. 리터럴 사용한 방식
  2. new 연산자 이용한 방식

변수 선언시 new 키워드를 사용하는 것과 그냥 선언하는 것의 차이는 무엇일까요 ?

✍️ new 연산자 VS Literal 방식

  1. new 연산자
    • new를 통해 선언시 Heap 영역에 존재
    • 같은 변수를 할당시 다른 메모리 공간에 할당됨
  2. 리터럴 방식
    • 변하지 않는 값을 의미한다.
    • 리터럴 방식을 통해 선언시 heap 메모리 영역에 있는 string constant pool이라는 영역에 생성됨
    • a=10 일때 10이라는 것은 변하지 않는 고정적인 값으로, 리터럴이라고 부름
    • 같은 값에 선언시 같은 주소를 가리키게 된다.
  • new 키워드 사용하기

    String one = new String("example");
    String two = new String("example");

  • 리터럴 방식 사용

    String one = "apple";
    String two = "apple";

-> 이렇게 new를 사용하게 되면 one과 two는 다른 주소를 할당 받고, 리터럴 방식을 사용한 경우, 두 변수의 메모리 주소 값이 동일하게 나온다.

equals VS '=='

위의 변수 할당 방식에 따라 데이터 비교 방식과 결과가 달라진다.

public class cmp {
    public static void main(String[] args) {
        String str1 = "hyeons";
        String str2 = new String("hyeons");
		
        if(str1 == str2) {
            System.out.println("두개의 값이 같음.");
        } else {
            System.out.println("두개의 값이 같지 않음.");
        }
        
        if(str1.equals(str2)) {
            System.out.println("두개의 값이 같음.");
        } else {
            System.out.println("두개의 값이 같지 않음.");
        }
    }
}
  1. '==' 연산자
  • 비교하고자 하는 두개의 대상의 주소 값을 비교한다.
  • 위의 코드에서 str1, str2는 다른 주소를 가리키고 있기 때문에 서로 다르다는 결과를 얻을 수 있다.
  1. equals() 연산
  • 비교하고자 하는 두개의 대상의 값 자체를 비교한다.
  • str1과 str2는 주소는 다르지만 값자체는 같기 때문에 서로 값이 같다는 결과를 얻을 수 있다.

✍️ this, this() 차이

  • this : 인스턴스 자신을 가르키는 참조 변수
  • this() : 생성자

this

  • 참조 변수

    • 실제 값을 가진 변수가 아닌, 값이 들어가 있는 주소를 가지고 있는 변수임.

    • 참조변수는 메모리 공간이 stack, heap에 존재

    • Myclass class = new Myclass() 에서 class 참조 변수로서, stack 공간에 저장된다. 그리고 참조 변수의 주소값을 따라가서 heap 공간에 있는 MyClass()를 찾아가게 된다.

    • 참조변수 class는 주소값을 저장한다 생각 !

public class ConvenienceStore {
    // 편의점 브랜드
    String brand;
    // 편의점 주소
    String address;
    // 직원 수
    int staffCount;
    // 편의점 사장
    String boss;

    public ConvenienceStore(String brand, String address, int staffCount, String boss) {
        this.brand = brand;
        this.address = address;
        this.staffCount = staffCount;
        this.boss = boss;
    }
}
  • this는 생성자의 매개변수와 인스턴스 변수가 같을 때 구분하기 위해 사용한다.

  • this.brand가 인스턴스 변수, brand가 매개변수로 정의된 지역변수

  • static 메서드는 this 사용 못한다.

    this()

  • this()는 같은 클래스의 다른 생성자를 호출할 때 사용한다.

    public class ConvenienceStore {
       // 편의점 브랜드
       String brand;
       // 편의점 주소
       String address;
       // 직원 수
       int staffCount;
       // 편의점 사장
       String boss;
       
       // this() 생성자로 다른 생성자를 호출한다.
       ConvenienceStore() {
       	this("GS", "몰라", 1, "현정");
       }
    
       public ConvenienceStore(String brand, String address, int staffCount, String boss) {
           this.brand = brand;
           this.address = address;
           this.staffCount = staffCount;
           this.boss = boss;
       }
       
    }

✍️ final, static, static final 차이

  • Static

    • 객체 생성 없이 사용할 수 있는 필드와 메소드를 생성할 때 사용한다.
    • 객체마다 따로 할당할 필요 없이, 공용으로 사용하는 필드
    • 필드나 메소드를 객체마다 다르게 사용해야하는 경우는 인스턴스로 생성, 공용 데이터나 인스턴스 필드 포함하지 않는 경우 static 사용한다.
  • final

    • 해당 변수는 값이 저장되면 수정이 불가능하다는 의미다.

        public class Shop{
          final int closeTime = 22;
          final int openTime;
      
          public Shop(int openTime){
            this.openTime = openTime;
          }
        }
  • closeTime처럼 선언과 동시에 값주는 방식

  • openTime처럼 같이 생성하고, 객체 생성시 값을 주는 방법이 있다. 이러한 경우는 값은 변하지 않지만, 객체마다 다르게 설정이 가능함

  • static final
    => static + final = "고정된 + 최종적인", 상수를 선언하고자 할 때 사용한다.

    • 이때 final로 상수가 되지 않는 openTime과 같이 각 객체마다 고정 값이 달라지므로 각 객체마다 저장될 필요 없으며(static) + 여러 값 가질 수 없는(final) static final 을 통해 상수 선언한다.

정리

  • static : 공용으로 사용하는 필드, 객체마다 가질필요 없다.
  • final : 한 번 값 정해지고 나면, 값 바꿀 수 없는 필드
  • static final : 모든 영역에서 고정된 값으로 사용하는 상수

추상화

  • 클래스들의 공통적인 요소 뽑아서 상위 클래스 만드는 것
  • 미완성 설게도 -> 상속을 통해 하위 클래스에서만 완성 가능

  • 추상화 상속받을 때는 extends
  • 인터페이스 상속받을 때는 inplements

상속

  • 부모 클래스에서 상속받은 것을 자식클래스에서 모두 선언할 필요가 없습니다.
  • 클래스 간 계층적 관계를 구성함

✍️ super, super() 차이

  • super : 부모, 자식 클래스의 변수/메서드 이름이 똑같을 때 구분위해 사용한다. 부모 클래스의 클래스 멤버 앞에 붙여준다.
  • super() : 자식 생성자 안에서 부모 클래스의 생성자 호출할때 사용한다. 자식 클래스 멤버가 부모 클래스 멤버 사용할 수 있어서 먼저 부모의 멤버들이 초기화 되어 있어야 한다.

추상클래스 VS 인터페이스

  • 추상 클래스
    • 접근 제어자 제한 없음
    • 모든 형태의 변수 사용 가능
    • 메서드 모두 사용 가능
    • 상속 키워드 : extends
  • 인터페이스
    • 사용 가능 변수 - static final
    • 사용 가능 접근 제어자 - public
    • 사용 가능 메소드 : abstract method, default method, static method, private method

공통점

  • 추상 메소드 갖고 있어야함
  • 인스턴스화 할 수 없음(new 생성자 사용 못함)
  • 상속한 클래스는 반드시 추상 메소드를 구현해야함

자바 제네릭(Generic)

✍️ 자바 원시 타입, 참조 타입

  • 원시타입 : 정수, 실수, 문자, 논리 리터럴 등 실제 데이터 값 저장하는 타입
  • 참조타입 : 객체의 주소를 저장하는 타입으로 번지 값을 통해 객체를 참조하는 타입이다.

Spring 특징

✍️ 스프링 핵심 키워드

POJO 프로그래밍 지향

자바의 객체지향적인 특징을 살려 비즈니스 로직에 충실한 개발이 가능하도록 하는 것

IoC/DI

  • IOC : 프로그램의 제어 흐름을 직접 제어하는 것이 아니라 외부에서 관리하는 것
  • 프레임워크 VS 라이브러리
    • 프레임워크 - 프레임워크가 내가 작성한 코드를 제어하고, 대신 실행하는 것
    • 라이브러리 - 내가 작성한 코드가 직접 제어의 흐름을 담당하는 것 (자바 객체를 json으로 바꾸는 것을 직접 호출 하는 것)
  1. DI(의존관계 주입)
  • 정적인 클래스 의존 관계와, 실행 시점에 결정되는 동적인 객체(인스턴스) 의존 관계 둘을 분리해서 생각
  • 의존관계 주입을 사용하면 정적인 클래스 의존관계를 변경하지 않고, 동적인 객체 인스턴스 의존관계를 쉽게 변경할 수 있다

AOP

  • Aspect Oriented Programming의 약자로 관점 지향 프로그래밍
  • 어떤 로직을 기준으로 핵심적인 관점, 부가적인 관점으로 나누어서 보고 그 관점을 기준으로 각각 모듈화하겠다는 것
  • 흩어진 관심사를 Aspect로 모듈화하고 핵심적인 비즈니스 로직에서 분리하여 재사용하겠다는 것

PSA

  • 환경의 변화와 관계없이 일관된 방식의 기술로의 접근 환경을 제공하는 추상화 구조
  • 잘 만든 인터페이스
  • Spring은 Spring Web MVC, Spring Transaction, Spring Cache 등의 다양한 PSA를 제공

✍️ spring 동작 과정

  1. 요청 받으면 DispatcherServlet이 수신하게 됨. 이를 위해 web.xml 파일을 연다.
  2. web.xml 파일에 작성된 내용을 기반으로 초기 파라미터로 전달 받는다.
  3. Bean으로 자동 등록하기 위한 component-scan 대상이 되는 패키지 경로 적형 있다.
  4. 웹 컨테이너는 component-scan의 대상이 되는 패키지 안의 Bean으로 등록되기 위한 어노테이션을 갖고 있는 모든 클래스를 Bean으로 등록한다.
  5. 사용자가 요청한 url에 대한 처리를 맞고 있는 @controller 클래스에 사용자의 요청을 전달한다.
  6. 사용자가 요청한 url에 대응되는 @RequestMapping 어노테이션을 갖고 있는 method 실행된다.
  7. 해당 메소드에 해당하는 값에 대한 view를 사용자에게 응답한다.
profile
Always live diligently

0개의 댓글

관련 채용 정보