JAVA 웹 개발 패키지 - 패스트캠퍼스/Chapter2

Static / Static 응용 - 싱글톤 패턴 ( singleton pattern )

giggs 2021. 12. 28. 12:20

 

여러 인스턴스에서 공통으로 사용하는 변수를 선언하자 - static 변수

 

 

공통으로 사용하는 변수가 필요한 경우

 

  • 여러 인스턴스가 공유하는 기준 값이 필요한 경우
  • 학생마다 새로운 학번 생성
  • 카드회사에서 카드를 새로 발급할 때마다 새로운 카드 번호를 부여
  • 회사에 사원이 입사할 때마다 새로운 사번이 필요한 경우

 

 

 

 


 

 

 

 

static 변수 선언과 사용하기

 

 

static int serialNum;

  • 인스턴스가 생성될 때 만들어지는 변수가 아닌, 처음 프로그램이 메모리에 로딩될 때 메모리를 할당
  • 클래스 변수, 정적변수라고도 함(vs. 인스턴스 변수)
  • 인스턴스 생성과 상관없이 사용 가능하므로 클래스 이름으로 직접 참조

 

 

 


 

 

 

 

 

 

 

 

 

 

 

 

 

 

Program -- (road) --> memory (process)

프로그램을 구동시키면 메모리에 올라가게 된다. 메모리에 올라간 상태를 process 라 하고, tread 상태로 돌아가는~

 

 

 

memory에 올라갈때 크게 2가지 영역으로 나뉜다.

  1. 데이터 영역 -> 데이터 영역 , 상수 영역, static영역 이라고도 하는데 주로 Data 영역이라고 함
  2. Code 영역 -> instruction set 이라고도 함, 명령어 집합으로 line by line으로 사용

 

 

 

데이터 영역에 들어가는 것 -> 상수 / 리터럴 / static 

 

 

 

데이터 영역 -> 프로그램이 프로세스가 돼서 메모리에 로딩되는 순간 데이터 영역에 잡히고,

                    프로그램이 끝나서 메모리 언로드 되는 순간 메모리 수거

 

스택 메모리 -> 지역변수 공간, 반환되면 자동으로 사라짐

 

힙 메모리 -> instance 가 생성될 때마다 사용하는 메모리, 동적 메모리,  instance가 사라지는 순간 메모리 수거

 

 

 


 

 

 

static 변수 사용 예제)

회사원이 입사할 때마다 새로운 사번 부여하기

 

 

 

 

 

Employee 생성될때마다

시리얼넘 ++ 해서

Id 값으로 넣어준다.

 

 

static 변수 선언

 

 

 

 

 

 

 

get/set

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

name set

 

※ class name으로 참조

시리얼넘 확인용으로 출력

생략해도 출력 결과물 같음

 

 

get으로 가져와서 출력

 

 

 

출력 확인 GOOD :)

 

 

 

 

 

static 변수와 메서드는 인스턴스 변수, 메서드가 아니므로 클래스 이름으로 직접 참조

 

 

 

 


 

 

 

static메서드의 구현과 활용

 

 

 

serialNum 은 중요한 정보다. 외부에서 볼 수는 있지만 함부로 변경하거나 하면 안 되므로

① private으로 변경 - 외부에서 바로 사용 불가능 - get으로 호출

② get/ set 중 set 삭제 내용 제공 X

③ getSerialNum으로 호출해서 사용

 

① private

 

② set

 

 

 

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

 

③ get

 

class 이름으로 참조

 

 

 

 

 


 

 

 

 

static 메서드(클래스 메서드)에서는 인스턴스 변수를 사용할 수 없다.

  • static 메서드는 인스턴스 생성과 무관하게 클래스 이름으로 호출될 수 있음
  • 인스턴스 생성 전에 호출 될 수 있으므로 static 메서드 내부에서는 인스턴스 변수를 사용할 수 없음

 

static 메서드 안에서는

 

지역변수 i는 사용 가능

( 안에서 쓰고 사라지는 변수이기 때문에 )

 

employeeName 

멤버 변수, 인스턴스 변수 사용 불가능

(static 메서드 불러오는 순간에 변수가 없을 수도 있으므로) 

 

 

 

 

 

 

+일반 메서드 안에서는 static 변수 사용 가능

(static 메서드는 프로그램 로드될 때 이미 메모리가 자리 잡고 있는 상태라서)

 

 

 

 

 


 

 

 

 

 변수의 유효 범위( scope )와 메모리

 

 

 

변수의 유효 범위(scope)와 생성과 소멸(life cycle)은 각 변수의 종류마다 다름

지역변수, 멤버 변수, 클래스 변수는 유효 범위와 life cycle, 사용하는 메모리도 다름

 

 

 

 

static 변수는 프로그램이 메모리에 있는 동안 계속 그 영역을 차지하므로 너무 큰 메모리를 할당하는 것은 좋지 않음

 

클래스 내부의 여러 메서드에서 사용하는 변수는 멤버 변수로 선언하는 것이 좋음

 

멤버 변수가 너무 많으면 인스턴스 생성 시 쓸데없는 메모리가 할당됨

멤버 변수를 안 쓰면 함수 사이에 매개변수 계속 전달해 줘야 하고, 외부에서도 클래스 사용 시 귀찮아짐

상황에 적절하게 변수를 사용해야 함!

 

 

 

 

 


 

 

 

 

static 응용 - 싱글톤 패턴(singleton pattern)

 

 

 

디자인 패턴 // 패턴 사용 시 유지 보수가 좋다

 

 

싱글톤 패턴이란?

  • 프로그램에서 인스턴스가 단 한 개만 생성되어야 하는 경우 사용하는 디자인 패턴
  • ex ) 서울 표준시, 미국 표준시, 회사 이름 등
  • static 변수, 메서드를 활용하여 구현할 수 있음

 

 

 

 

외부에서 마음대로

Company new 할 수 없도록

생성자 하나 제공

 

유일한 인스턴스 생성

private static ~~ 

 

유일한 객체를 

외부에서 쓸 수 있도록 

접근할 수 있도록 

public static ~~ 

 

+if는 방어적으로 코드 해놓은 것

 

 

 

 

 

 

 

 

static 변수 가져다 쓸 때는

class이름으로 바로 사용

(일반 변수 가져다 쓸 때는 

C oh1 =new C 해서 썼던 거 필요)

 

 

 

 

 

같다.

 

 

 

 

 

 

 

 

 

 

  • Compnay는 외부에서 생성할 수도 없고,
  • 내부에 private으로 하나 생성되어있고,
  • getInstance 메서드만 제공되고,
  • 이 메서드로 instance 만 사용할 수 있다.
  •  

 

 

 

클래스 다이어 그램 약식

 

클래스 이름

 

변수

 

 

생성자와 메서드

 

-는 private // +는 public이라는 뜻

 

 

 

 

 

Singleton이라는 클래스 이름에

private instance라는 멤버 변수가 하나 있고

Singleton이라는 생성자는 private 

getInstance public - 이거 가져다 쓰면 된다.

 

 

 


 

 

 

 



review

Static 변수

처음 접해보는 변수와 역할, 데이터 영역에 대해 이해하기 힘들었지만
상수와 리터럴과 같은 공간 - 데이터 영역에 있다는 것을 이해하고 나서
이해가 되기 시작하였다.

static 변수로 선언하면 
상수처럼 기준 값과 위치가 생성되는 것으로 이해하였다

기준 값과 위치가 생성된 static 변수를
공개 범위와 사용 범위 판단하여 public / private 선택해서 선언하고
public으로 제공된 static 메서드를  class 이름으로 참조해서 사용

후후
지금까지는 어떤 변수를 선언하고 사용할지에 대해서만 고민했다면

static 부분을 학습하고 난 후에는
변수들을 멤버 변수로 선언? 아니면 지역변수로 그때그때 사용?
그 변수들을 사용자에게 public? private?, 사용하게 할지 안 할지 
유일한 값을 가지는 건지? 메모리가 너무 크게 잡히지는 않을까?

많은 판단과 고민이 필요해져서 복잡해졌다.
하지만
생각이 복잡해진 만큼
코드를 보는 눈도, 코드를 이해하는 능력도 조금씩
업그레이드되는 느낌이라서 뿌듯하다.