본문 바로가기

프로그래밍 언어 기초/JAVA

Chapter 8. 접근 제한자(Access Modifier)와 싱글턴 패턴(Singleton Pattern)

8. 1. 접근 제한자(Access Modifier)?

 몇 개월에 걸쳐 열심히 만들어낸 음원을 다른 사람이 도용해서 쓴다면 정말 화가 나겠죠. 이러한 사태를 방지하기 위해 저작권이라는 권리가 존재하는 것처럼 개발자가 열심히 만든 자바 소스 코드를 다른 사람이 함부로 동의 없이 사용하거나, 삭제 또는 망가뜨리는 행위를 하게 된다면 프로그래밍 생태계는 그야말로 무법지대가 되어버릴 것입니다. 이처럼 내가 작성한 코드 또는 다른 개발자가 작성한 코드를 어느 수준까지 사용 또는 편집하는 것을 허용할지 구체적으로 가이드를 제시하는 데 사용하는 것이 바로 접근 제한자입니다.

 

접근제한자는 객체지향 프로그래밍의 4대 원칙 중 하나인 캡슐화와 연관이 있는 개념입니다. 캡슐화란 객체의 속성(data fields)과 행위(메서드, methods)를 하나로 묶고, 실제 구현 내용 일부를 내부에 감추어 은닉 하는 것입니다. 이와 관련된 내용은 객체지향 프로그래밍에서 집중적으로 다뤄보도록 하겠습니다.

 

 프로그래밍 언어마다 접근제한자의 키워드는 약간씩 상이합니다. 그래도 대부분 개념은 공유하고 있는 편입니다.

 자바에서 사용하는 접근제한자는 아래의 네가지입니다.

 

자바의 접근제한자(Access Modifier)

접근제한자
(Access Modifier)
설명 적용 범위
public 자유롭게 외부에서 접근 가능 클래스, 필드, 메소드, 생성자
protected 상속받은 클래스에서만 사용 가능 필드, 메소드, 생성자
default 같은 패키지 내에서만 사용 가능 클래스, 필드, 메소드, 생성자
private 자기 자신 내부에서만 사용 가능 필드, 메소드, 생성자

 

생성자, 필드, 메소드에서의 접근제한자 용례

public class AccessModifier { //  클래스 앞에 접근자는 기본 적으로 public이다.
			
	// 생성자에서 사용 가능한 접근 제한자
	// 오버로딩을 통해 이름이 같은 생성자를 여러개 등록하기 위해 매개변수를 다르게 설정 
	public AccessModifier() {}
	protected AccessModifier(int value) {}
	AccessModifier(long value) {} // default라는 키워드가 있지만, Interface에서만 사용 가능하다.
	private AccessModifier(String value) {}
	
 	
	// 필드에서 사용 가능한 접근 제한자
	public int value1;
	protected int value2;
	int value3; // default는 생략한다.
	private int value4; // 클래스 내부에서 사용 가능, 클래스 인스턴스를 사용했을 경우 참조는 가능하다.
	
	
	// 메소드에서 사용 가능한 접근 제한자
	// 오버로딩을 통해 이름이 같은 함수를 여러개 등록하기 위해 매개변수를 다르게 설정 
	public void call() {	System.out.println("hello public");	}
	protected void call(int value) {	System.out.println("hello protected");	}
	void call(long value) {	System.out.println("hello default");}
	private void call(String value) {	System.out.println("hello private"); }
	
}

 

클래스에서의 접근제한자 용례

- public과 default 두 종류 뿐이다.

public class PublicClass { // 모든 클래스의 가장 기본 폼인 public class

}
class DefaultClass { // 접근제한자를 작성하지 않고 클래스를 생성하면 default 클래스가 된다!

}
 

8. 2. 싱글턴 패턴(Singleton Pattern)

 자바에서 프로그래밍 코드를 작성하는 디자인 패턴 중 싱글턴 패턴이라는 것이 있습니다. 이 디자인 패턴은 접근제한자를 잘 활용한 프로그래밍 디자인 패턴입니다. 싱글턴 패턴의 정의는 아래와 같습니다.

 

 

 소프트웨어 디자인 패턴에서 싱글턴 패턴(Singleton pattern)을 따르는 클래스는, 생성자가 여러 차례 호출되더라도 실제로 생성되는 객체는 하나이고 최초 생성 이후에 호출된 생성자는 최초의 생성자가 생성한 객체를 리턴한다. 이와 같은 디자인 유형을 싱글턴 패턴이라고 한다. 주로 공통된 객체를 여러개 생성해서 사용하는 DBCP(DataBase Connection Pool)와 같은 상황에서 많이 사용된다.
출처 위키백과 : 링크

 

 자바에서 클래스는 new 키워드를 통해 인스턴스를 생성할 수 있었습니다. 그런데, 그냥 가져다만 쓰는 되는 클래스라면? 어떤 데이터를 특별히 조작하거나 오버라이딩해서 새롭게 작성할 필요가 없는 클래스라면? 아니면 모두가 같은 데이터를 공유하는 클래스를 사용할 필요가 있는 경우라면? 이와 같은 질문에는 여러 해답이 있을 수 있겠지만, 자바의 개발자들은 싱글턴 패턴으로 이 고민을 해결하고자 했습니다. 컴퓨터의 메모리에 올라가는 클래스 객체를 하나만 하고, 그 객체를 여러 곳에서 참조한다면 한정된 컴퓨터의 메모리 자원을 효율적으로 쓸 수 있지 않을까 하는 고민에서 나온 작품인 것이지요. 실제로 이 패턴은 실무에서 유용하게 쓰이는 디자인 패턴이므로 잘 알아둘 필요가 있습니다. 싱글턴 패턴은 아래의 세가지 규칙을 따르는 코드 스타일을 말합니다.

 

 

1. 클래스 내부에서 private 접근제한자를 갖는 static 변수로 인스턴스를 생성

2. 클래스의 생성자의 접근 제한자를 private로 설정

3. public 접근 제한자 +static + 클래스명 의 형식을 갖는 메소드를 통해 인스턴스를 리턴;

 

💡 여기서 잠깐! static 이란?

 static 이란 메모리에 한번 할당되어 프로그램이 종료될 때 해제하겠다고 자바 컴파일러에 알려주는 키워드로 인스턴스를 생성하지 않고도 필드, 메소드 등에 접근할 수 있게 해줍니다. 이 키워드가 붇지 않은 클래스, 메소드, 변수, 필드 등은 인스턴스를 생성해서 접근하거나 사용해야 하는 등 추가적인 작업이 필요할 수 있습니다.

 

싱글턴 패턴을 지킨 클래스

 

public class SingletonClass {
	
	// 1. 자기 자신의 기본 생성자를 통해 객체를 생성합니다.
	private static SingletonClass instance = new SingletonClass();
	// 2. 자신의 기본 생성자의 접근 제한자를 private로 해주어 컴파일러가 public 기본 생성자를 생성하지 않게 합니다.
	private SingletonClass() {};
	// 3. public 접근 제한자 + static + 클래스 형식을 가지는 메소드를 통해 인스턴스를 리턴합니다.
	public static SingletonClass getInstance() {
		return instance;
	}
	
}
 

 

싱글턴 테스트

public class SingletonTest {
	
	public static void main(String[] args) {
	 	
		// SingletonClass sc1 = new SingletonTest(); // 생성자가 private이므로 컴파일 오류!
		SingletonClass instance1 = SingletonClass.getInstance(); // new 키워드로 생성한 것이 아님!
		SingletonClass instance2 = SingletonClass.getInstance(); 
		
		//  이렇게 생성된 객체는 서로 같을까? ( 메모리에서 같은 주소를 가리키고 있을까? )
		System.out.println(instance1 == instance2); // true
		
	}

}