2022. 10. 5. 14:56ㆍDev.Program/Java & Spring
책 p251-252
3.4 Singleton 디자인 패턴(JSP 에서 쓰는 MemberBean/DAO 도 디자인패턴임)
⇒ 어떤 목적을 달성하기 위한 프로그래밍 가이드
> 여러개의 인스턴스를 만들면 안될 때(ex) Account() 같이 은행코드들), Singleton 디자인 패턴을 사용함.
< 싱글톤 디자인 패턴(Singleton Design Pattern) >
- 단 하나의 인스턴스만을 공유하도록 하는 프로그래밍 기법
- 외부에서 인스턴스 생성을 하지 못하게 차단하고 클래스 내에서 직접 인스턴스를 생성하여 외부에 생성된 인스턴스를 리턴
- 누구나 단 하나의 인스턴스만을 공유하여 사용해야함
< 패턴 규칙 > → 개념 부분 이므로 잘 모르겠으면 밑에 실제 정의할 때의 문법 순서 잘 보기
- 외부에서 인스턴스 생성이 불가능하도록 생성자에 private 접근제한자 선언
- 자신의 클래스 내에서 인스턴스를 생성하여 참조변수에 저장
- ⇒ 외부에서 인스턴스 생성이 불가능하므로
- ⇒ 인스턴스 생성없이 접근해야하므로 static 키워드 사용
- ⇒ 외부에서 함부로 접근하지 못하도록 private 접근제한자 선언
- 생성된 인스턴스를 외부로 리턴하는 Getter 메서드 정의
- ⇒ private 접근제한자 멤버변수에 저장된 인스턴스를 리턴
- ⇒ 인스턴스 생성없이 접근해야하므로 static 키워드 사용
★ < 실제 정의할 때의 문법 순서 > ★
- 멤버변수 선언 및 인스턴스 생성(private static)
- 생성자 정의(private)
- Getter 정의(public static)
======== Ex3.java 만들기
> 생성자에 private 접근지정자 선언
- 원래 우리가 만들던 생성자(public)
- public 부분을 private 로 바꿈
- 그럼 main 안에 오류남.
- SingletonClass sc = new SingletonClass(); // 여기가 생성자를 호출하는 코드
- 이렇게 자신의 클래스에서 직접 인스턴스 생성 가능
- 그런데, 밖(main 부분)에서 인스턴스 생성을 못하기 때문에 어차피 호출을 못함….!
- 변수에 접근 할 방법이 없다.
- 그럴때 필요한 건? Static!! ⇒ 인스턴스 생성 없이도 접근해야하므로 static 키워드 사용
- 앞에 static 만 붙여줌.
- main() 에서 sc 를 부르는 방법! (static이기 때문에 클래스명.멤버변수로 부름)
- 근데 위에서 = null; 이라고 하면 다 날아가기 때문에 저것도 접근제한자를 통해 값을 바꿀 수 없도록 변경해줌.
> 이제 여기에 다시 접근하려면!? Getter / Setter (Alt + Shift + S → R)
- 우린 필요한 Getter만 생성을 해줌. 근데 여기서도 문제가 생김. public 호출하려면 밖에서 인스턴스 생성이 되야하는데 우린 그게 안된다.
- 그래서 여기도 static 붙여줌!
class SingletonClass {
// 외부에서 생성자 호출이 불가능하도록 private 접근제한자 선언
private SingletonClass() {}
// 외부에서 인스턴스 생성이 불가능한 대신
// 자신의 클래스에서 직접 인스턴스 생성
// ⇒ 인스턴스 생성없이 접근해야하므로 static 키워드 사용
private static SingletonClass instance = new SingletonClass();
// private 접근제한자가 선언된 멤버변수에 대신 접근하여
// 생성된 인스턴스를 외부로 리턴하는 Getter 메서드 정의
public static SingletonClass getInstance() {
return instance;
}
} ( ⇒ 나중에 Singleton 패턴 만들라고 해보면 static 을 잘 빼먹습니다! )
- ⇒ 나중에 Singleton 패턴 만들라고 해보면 static 을 잘 빼먹습니다!
- SingletonClass2 클래스를 만들어서 자동완성 하려니까 오류남(생성할 게 없어서)
- private SingletonClass2() {} ⇒ 따로 수동으로 적어줌
- 그 이후에 Getter 는 자동완성으로 해주면 된다(알아서 static 붙음)
- 메인에서 호출하는 방법.
- static 메서드인 getInstance() 메서드 호출을 위해 클래스명.메서드(); 로 호출
확인용 > 이제 getInstance() 안에
public void print() {
System.out.println("print() 메서드 호출!");
}
- 이렇게 print() 메서드를 만들고
> 위(main 안)에서 sc.print(); 로 호출하면 결과값 잘 나온다
p 251-253
< Ex3.java >
⇒ 싱글톤 디자인 패턴 = 싱글톤 패턴이라고도 함! (인스턴스를 한 개만 만들기 위해 쓴다)
- 출력창
- 계속 new 를 하면서 새로 만들어준 거라면 두 개가 다르다고 나올텐데, 생성자 한 개를 돌려 쓰니까 같다고 나옴!
======== Test3.java 만들기
문제 )
class Account {
//----------------------------------------------
// Account 클래스의 싱글톤 디자인 패턴 적용
>>>>> 여기에 만들기 (안보고 해보기!) //----------------------------------------------
}
답 )
class Account {
private static Account instance = new Account();
private Account() {}
public static Account getInstance() {
return instance;
}
private String bankName = "ITWILL 은행";
public String getBankName() {
return bankName;
} ⇒ 추가
}
⇒ 이거 연습 많이 많이 해보기!!!! 그럼 안까먹습니다. (특히 static 적는거 잘 까먹음!)
> main에서 호출할 때
public static void main(String[] args) {
Account ac = Account.getInstance();
System.out.println(ac.getBankName());
}
====================⇒ 여기까지가 static 은 끝!
교재 p.240 (1) final
변수에 final 이 붙으면 상수라고 생각하면 됨.
< final 키워드 >
- '변경의 마지막' 이라는 의미로 사용되는 키워드
- 변수, 메서드, 클래스에 사용 가능
- 변수에 final 키워드가 사용될 경우
- 변수 값 변경 불가 = 상수로 취급됨
- 반드시 초기화 코드가 포함 되어야 함
- 초기화 코드를 포함하지 않는 변수를 blank final 변수라고 하며 생성자에서 반드시 해당 변수 초기화가 수행되어야 함!
- (⇒ 주로 객체마다 다른 고정된 값을 사용해야 하는 경우)
- 기존 상수(final 변수)를 그대로 사용하는 것은 가능
- 대표적인 변경 불가 상수 : Math 클래스의 PI 등
- 상수 선언 시 주로 대문자로 이름을 지정
- (단어 간의 구분 시 언더스코어(_) 기호 사용. ex) MY_NAME)
- 메서드에 final 키워드가 사용될 경우
- 메서드 내용 변경 불가 = 메서드 오버라이딩 금지
- 슈퍼클래스의 메서드를 상속받아 그대로 사용하는 것은 가능
- 클래스에 final 키워드가 사용될 경우
- 클래스 내용 변경 불가 = 상속 금지
- 해당 클래스의 인스턴스 생성을 통해 그대로 사용하는 것은 가능
- 대표적인 상속 불가 클래스 : String 등
======== Ex4.java 만들기
1. 변수에 final 키워드가 사용될 경우
- 이렇게는 아무 오류 없이 잘 실행된다. (우리가 평소에 내내 하던 것)
- class FinalVariable {} 안에 int b를 final int b로 바꿔줌 (final을 붙여줌)
- 위에 컴파일 에러 발생! final 변수(= 상수)는 값 변경이 불가하기 때문! (에러문구 보기)
- 주의사항! 초기화를 안하면 없는 채로 고정이 되기 때문에 오류남. (c)
- 별도의 초기화가 되지 않은 상수(blank final 변수)는 선언 과정에서 오류 발생됨(에러문구 보기)
> 예외 사항. 생성자를 통해 초기화하는 코드가 포함될 경우!
⇒ 생성자를 통해 c를 초기화 시키니까 오류 없어짐.
- 생성자에서 단 한 번의 초기화는 가능하다 (한번만 가능)
>> 대표적인 변경 불가 상수 : Math 클래스의 PI
- 여기 잘 보면 S(static)와 F(final) 다 붙어 있음.
- 값 변경 불가!
2. 메서드에 final 키워드가 사용될 경우
> 이제 메서드()에 final 을 붙여보자.
⇒ 메서드()에 final 붙인다는 건 오버라이딩을 못한다는거!
> final 없이 기본
> 메인에서 호출
FinalMethod fm = new FinalMethod();
fm.finalMethod();
SubFinalMethod sfm = new SubFinalMethod();
sfm.finalMethod();
> 여기서 final 을 붙여보자.
- final 붙이니까 밑에서 오버라이딩 수행 못함. (빨간 줄 그이는 거 확인)
- 일반 메서드는 오버라이딩이 가능하다.
3. 클래스에 final 키워드가 사용될 경우
> 이제 남은 건 class 에 final 을 붙이는 것.
- final을 붙였는데도 인스턴스 생성도 잘 되고 출력도 잘 됨!
- 여기 까지는 문제가 없다!!!
- 그럼 뭐가 안될까? → extends 를 못함(상속 불가!)
- final class 는 상속 받을 수 없다! (오류문구 보기)
'Dev.Program > Java & Spring' 카테고리의 다른 글
[Java] 인터페이스(interface) (1) | 2022.10.05 |
---|---|
[Java] 추상(Abstract) 클래스/메서드 (0) | 2022.10.05 |
[Java] static (0) | 2022.10.05 |
[Java] instanceof 연산자/다형성/자바프로그램실행과정/static (0) | 2022.10.05 |
[Java] 형변환(Type Casting) - 업캐스팅/다운캐스팅 (0) | 2022.10.05 |