포스트

(Day18) - OOP, 객체지향 프로그래밍 상세 [4] 클래스의 사용법

이 글은 제가 교육을 수강하며 기록하고 추가한 내용입니다. 강사님과 무관하게 잘못된 내용이 있을 수 있습니다.


클라우드 기반 웹 데브옵스 프로젝트 개발자 교육 과정 (5기)

  • 비트캠프 엄진영 강사님 (https://github.com/eomjinyoung/)
  • 훈련기관 : 네이버클라우드주식회사
  • 기간: 2023-11-14 ~ 2024-5-22
  • 남은 일자 : 113 일 ( 18/129 )

본 내용은 제가 교육을 수강하며 기록한 내용으로, 빠른 템포를 따라가며 기록하고 제가 공부한 내용을 추가하므로 내용의 정확성이 부족할 수 있는 점 양해 부탁드립니다.

18일(2023-12-7, 목)

복습

클래스 문법을 이용하여 사용자 정의 데이터를 정의하고 사용할 수 있는가?

클래스에서 인스턴스 변수를 선언하려면 statc 명령어를 사용하지 않고 변수를 선언하면 된다.

레퍼런스 배열을 이용하여 인스턴스 목록을 다룰 수 있는가?

레퍼런스를 배열로 만들 수 있다. 각각의 레퍼런스가 가리키는 인스턴스는 배열처럼 생성되지 않는다. (JVM이 결정한다.)

클래스 변수와 로컬 변수의 생명주기를 설명할 수 있나?

  • 클래스 변수는 클래스가 로딩될 때 생성, JVM 종료될 때 삭제
  • 로컬 변수는 메서드 호출될 때 생성되고, 메소드 호출이 종료되면 로컬 변수도 삭제된다.

    클래스 로딩의 의미와 로딩 시점을 설명할 수 있나?

    클래스 로딩은 .class 파일의 내용을 JVM 내의 Method Area 메모리 영역에 올리는 것이다. 클래스를 메모리에 적재한다고도 표현한다. 물론 파일을 그대로 올리지는 않는다. 진입점(Entry point)인 main()으로 시작하는 등 요구사항에 대해 더 나은 로딩 방법이 있다. 이는 JVM이 결정한다.

왜 클래스를 메모리에 로딩해야 하나?
보조기억장치는 너무 느리다. 배치도 사용에 최적화되어 있지 않다.

실생활에 비유하기: 마트 가서 뭘 사와서 냉장고에 넣는다고 하면 마트 봉다리를 그대로 냉장고에 넣지 않는다. 클래스파일도 그냥 메모리에 넣는 것이 아니라, Method Area 쪽에 올릴 때 정리해서 올린다. 실제 정리하는 방법은 JVM 구현체마다 다를 수 있다. 지금은 구체적인 내용을 학습할 시기는 아니다.

로딩 시점은?
클래스가 필요할 때 로딩된다.
  • 클래스의 인스턴스가 생성될때
  • 클래스의 정적 변수가 사용될때 (단, 정적 변수는 final로 선언된 상수 x)
  • 클래스의 정적 메소드가 호출될때

학습

기존 코드를 기반으로 기능을 구현해보기

회원 메뉴를 추가하고 CRUD 를 구현하기

가입인사 게시판을 추가해보기 (app13->14)

게시판과 동일한 클래스다. C&P(Copy and Paste)로 구현이 가능하다.

C&P, 뭔가 불편하지 않은가?

변수의 이름을 수정할 필요조차 없다. 사실상 다를 게 없는 클래스를 중복해서 작성하게 된 것이다. 새 게시판이 필요할 때 마다 클래스 파일을 복사해서 만든다..?

C&P에 대하여

C&P의 장점: 간단하다. C&P의 단점: 코드가 중복된다.

실제로 게시판을 실무 수준으로 구현하면 클래스가 몇 백개가 될 수 있다. 이런 몇 백개의 클래스가 C&P로 추가되는 경우 유지보수 비용엄청나게 증가하게 된다. 개발에 들어가는 시간이 중복된 클래스들의 수에 비례하여 증가하게 된다.

코드가 중복되면 작업이 중복된 각각의 클래스만큼 늘어난다.

왜 C&P를 하게 됐나?

기존 작성된 게시글 목록은 static field를 사용했기 때문에 클래스당 오직 한 번만 생성할 수 있다. 새 게시판의 목록을 따로 저장할 수 없으니 복제해서 만들게 된 것이다. 같은 의미의 말로 다시 말하면, 인스턴스로 만들어서 각각의 인스턴스가 사용해야 할 변수를 클래스 변수로 만들었기 때문에, 레퍼런스들을 만들고 각각의 인스턴스로 사용할 것을 그렇게 사용하지 못하기 때문이다.

클래스를 복사하는 경우

복사한 클래스와 거의 유사한 기능을 구현하기 위해 클래스를 복사한 경우는 코드 중복을 만드는건지, non-static 을 통한 중복 해소가 가능한지 생각해야 한다.

도메인

사람들이 도메인(Domain)이라는 말을 하면, 그것은 Business Domain을 말하는 것이다. 이것은 업무 영역을 말하는 것이다.

GPT가 다룰 수 없는 도메인은 가치가 계속 높아질 것이다. 학습할 수 없는, 공개되지 않은, 상위 레벨의 업무 영역은 가치가 더욱 높아질 것이다.

로켓 기술 알려줘, 배터리 구조 알려줘. 이러면 생성형 인공지능이 제대로 된 대답 해줄까? 기업은 이런 정보를 숨길 명분이 있다.

의학지식, 법률지식은 공개가 되어야만 하는 지식이다. 학습이 되어야만 하는 지식이다. 이런 지식들은 도메인 이해관계자가 숨길 명분이 없다.

도메인 전문가가 더 강한 파워를 가지는 시대가 오고 있다.

도메인 전문가가 유리해지는 시기가 온다지만, 나는 그러한 파도를 타는 도메인 전문가들은 제한적일 것이라고 생각한다.

(app14->15)

static 으로 선언된 메서드와 변수를 non-static으로 변경한다. 게시판을 여러개 만든다고 하면! Board 클래스를 이제 레퍼런스의 배열로 만들어서, 각각의 인스턴스들을 레퍼런스에 넣어주면 된다.

생성자의 필요성에 대해

이렇게 인스턴스를 활용하여 코드 중복을 막게 되면, 생성자의 필요성에 더욱 공감할 수 있다. 현실 세계에서도 제품을 찍어서 판매할 때, 최소한의 기본 세팅을 해서 내보낸다. 이처럼 인스턴스를 찍어서 내보낼 때, 최소한의 기본적인 세팅을 하게 하는 것이 생성자다. 인스턴스가 사용되기 전에 유효한 상태(사용가능한 상태)로 설정하기 위한 방법이 생성자다.

생성자 문법이 없었다면 어떻게 인스턴스를 설정해야 하는지 알기 어렵다. 인스턴스를 잘못 설정하거나, 설정하지 않고 생성하게 될 수 있다. 개발자의 실수가 생길 수 있다. 유지보수의 비용을 낮추기 위해서 생성자가 필요하다는 것을, 이렇게 C&P의 문제를 해결하기 위해 인스턴스를 사용하게 되며, static -> non-static 으로 전환해가는 과정에서도 느낄 수 있다.

클래스의 재사용성에 대해

만약 당장 재사용이 필요한 클래스가 아니더라도, 가능하면 향후의 확장성을 고려하여 인스턴스 메서드 및 인스턴스 변수를 사용한다. 인스턴스로 사용하지 않을 것이 절대적으로 보장된다면 스태틱 메서드 및 스태틱 변수로 선언해도 괜찮다.

어떤 책에서는 this를 생략한 채 인스턴스 메서드와 인스턴스 변수를 먼저 설명하고 나중에 static method, static variable에 대해서 설명하는 경우가 있는데, 이건 학습에 좋지 않다. static을 먼저 배우고, static variable 및 static method의 한계를 이해한 다음에 instance method 및 instance variable을 배우는게 맞다.

Prompt 클래스

static => non-static (확장성 고려)

  • input() 메서드를 String 받고 출력해주는 용도로만 사용하고 있다.
    • inputInt()
    • inputFloat()
    • inputBoolean() 근데 이거 정수로 바꾸고 논리값으로 바꾸고.. input을 사용하는 클래스에서 해야하는 걸까? 아니면 Prompt 클래스에서 해 줘야 하는 일일까? Prompt 클래스에서 해 주는 게 응집력이 더 강하다!

접근제어자 (복습)

Java 접근제어자에 대한 복습! | 접근 제어자 | 클래스 내부 | 같은 패키지 | 하위 클래스 | 다른 패키지 | |—————–|—————–|—————–|—————–|—————–| | public | ✔ | ✔ | ✔ | ✔ | | protected | ✔ | ✔ | ✔ | ✘ | | (default) | ✔ | ✔ | ✘ | ✘ | | private | ✔ | ✘ | ✘ | ✘ |

  • ✔: 접근 가능
  • ✘: 접근 불가능

메서드와 변수의 접근제어자에 대해

많은 책에서,

  • 메서드는 public
  • 변수는 private

으로 예제를 제공하기 때문에 이렇게 해야 하는 것이라고 생각을 할 수 있다. 그러나 초보 때는 공개하지 말고 default로 두어라. 문제가 발생할 때만 공개하라.

패키지로 클래스를 분류하기

자주 쓰는 클래스는 어떤 패키지로 분류하나?

utility 를 의미하는 패키지로 정리한다. 패키지는 프로젝트 하위에 두지 말고 프로젝트와 동등하게 하라.

myapp 학습 방법

스텝별로 올라가는 것을 보여주었으니 (오늘은 12~15) 이를 반복해라. 한번 이상 반복하고 나면, 12->13->14->15 에서 12->15로 가도 된다. 직접 반복해 보는 게 문법부터 활용까지 배우는 가장 좋은 방법이다.

12. 배열을 이용하여 여러 개의 데이터를 다루기

  • 배열을 이용하여 인스턴스 목록을 다루는 방법

13. 회원 메뉴를 추가하고 CRUD를 구현하기

  • 메뉴 메뉴를 다음과 같이 변경
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
----------------------------------------------

[과제관리 시스템]

  

1. 과제

2. 게시글

3. 회원

4. 도움말

0. 종료

----------------------------------------------

  • 회원 데이터의 입력, 조회, 변경, 삭제하는 기능 구현하는 방법

  • 회원 입출력 항목: 이메일, 이름, 암호, 가입일

14. 스태틱 필드의 한계 확인

  • BoardMenu 클래스를 복제하여 ‘가입인사 게시판’을 추가

  • 클래스 코드 복제의 문제점 확인

    • length, boards 변수가 static 변수라서 인스턴스로 만들어서 각각의 게시판들이 따로 인스턴스화하여 사용하지 못한다!! 뜯어 고쳐야 한다. 메서드도 static 메서드로 선언되어 있어서 인스턴스 변수에 접근하지 못한다. 역시 non-static으로 만들어야 한다.

15. 인스턴스 필드와 인스턴스 메서드 활용

  • BoardMenu 클래스에 인스턴스 필드 및 메서드 적용, 생성자 적용

  • 향후 확장성을 고려하여 AssignmentMenu, MemberMenu, MainMenu 클래스에도 인스턴스 필드와 인스턴스 메서드, 생성자를 적용

  • 그래서 실무에서는 대부분의 클래스가 인스턴스 필드와 인스턴스 메서드로 구성된다.

  • 향후 확장성을 고려하여 Prompt 크래스에도 인스턴스 필드와 인스턴스 메서드를 적용

  • 생성자 도입: Scanner 사용할 입력 도구를 지정할 수 있게 한다.

  • Prompt에 inputInt(), inputFloat(), inputBoolean() 메서드 추가

  • 사용자 입력한 문자열을 int, float, boolean으로 변경해주는 일을 한다.

  • 의존 객체 주입의 개념과 구현

  • 생성자를 통해 Prompt 객체를 XxxMenu에 주입

  • 리팩토링

  • ANSI Escape Sequence 값을 별도의 클래스로 분리

  • 역할에 따라 클래스를 패키지로 나눠서 분류

이 기사는 저작권자의 CC BY 4.0 라이센스를 따릅니다.