언어/JAVA

[JAVA] SingletonPattern

hvoon 2022. 9. 7. 17:53

-웹프로그래밍에서 자주 사용하는 기법

-웹프로그래밍의 특성상 하나의 프로그램을 서버에 두고 다수의 사용자가 접속해서 그 하나의 프로그램을 사용하게 되는데 이때 그 프로그램내의 클래스로 만들어지는 객체는 다수의 사용자인원수 만큼 따로생성되어 사용되기 마련임. 이때 메모리 과부하가 일어날 수 있으며 이를 해결하기 위해 하나의 객체를 각각 다른 사용자가 혼자 사용하는 것처럼 공유해서 쓸 수 있게 하는 방식이 싱글턴 방식임

-특정 클래스의 인스턴스를 반드시 한개만 생성할 수 있도록 강제하는 패턴

-하나의 인스턴스를 여러 래퍼런스 변수가 공유하여 사용하도록 제어하는 방식임

// 싱글톤 생성법
import java.util.Calendar;
class SingletonEx{
	int n1;
	int n2;
// 1. 생성자를 private로 보호함
	private SingletonEx() { }
// 2. 클래스 내부에서 생성자를 호출해서 객체하나(new 인스턴스)를 생성
//	  이 역시도 private로 생성함. &static으로 생성함
	private static SingletonEx itc=new SingletonEx();
// 위 itc 객체에 저장된 new SingletonEx()가 모두가 공유해서 사용할 유일한 new 인스턴스가 됨
// 3. 생성해놓은 객체의 참조변수값을 리턴하는 public형의 메서드를 생성
// 메서드 이름 getInstance() - static으로 생성함
	public static SingletonEx getInstance(){
		return itc;
	}
}

public class Singleton {
	public static void main(String[] args) {
		// SingletonEx s1=new SingletonEx();
		// SingletonEx s2=new SingletonEx();
		// SingletonEx s1=new SingletonEx();
		// SingletonEx s2=s1;
		// SingletonEx s1=new SingletonEx(); 
// 1. 생성자가 private으로 보호되므로 오류
// SingletonEx.getInstance()가 리턴해주는 유일한 인스턴스의 주소를 s1에 저장해서 사용
		 SingletonEx s1= SingletonEx.getInstance();
		 SingletonEx s2= SingletonEx.getInstance();
		 SingletonEx s3= SingletonEx.getInstance();
		 
		System.out.println(s1);
		System.out.println(s2);
		System.out.println(s3);
// 객체 참조 변수를 println으로 출력하면 클래스이름과 해쉬코드가 출력됨
// 해쉬코드: 각 객체들을 서로 구분할 수 있는 고유값->새로운 저장장소의 주소를 계산하는 피연산이기도 함
		s1.n1=150;
		s2.n2=200;
		System.out.println(s3.n1+" "+s3.n2);
		// Calendar c=new Calendar(); ->error
		Calendar c=Calendar.getInstance();
	}
}
public class Card {
	final static int spade=4;
	final static int diamond=3;
	final static int heart=2;
	final static int clover=1;
	private int kind; // 	4:Sqade/ 3:Diamond/ 2:Heart/ 1:Clover
	private int number; //	 A:1/ 2-10/ J:11/ Q:12/ K:13
	Card(int kind, int number){
		this.kind=kind;
		this.number=number;
	}
	Card(){
		this(spade,1);
	}
	// 무늬와 숫자를 String으로 리턴해주는 멤버메서드
	// kind: 4, number: 13이라면 문자열"[Spade:K]"라고 리턴
	public String toString() {
		String[]kinds= {"","♣","♥","◆","♠"};
		String[]numbers= {"","A","2","3","4","5","6","7","8","9","10","J","Q","K"};
		String result=" ["+kinds[kind]+":"+numbers[number]+"] "; // [Spade:K]
		return result;
	}
}

class CardDeck{
	private Card[]cards=new Card[52]; // 카드 52장의 저장된 배열(참조변수 배열)
	// new Card(); 동작이 52번 필요함
	// cards[0]=new Card(Card.spade,1);
	// cards[1]=new Card(Card.spade,2);
	// cards[2]=new Card(Card.spade,3);
	 CardDeck() { // 생성자에서 배열 52칸에 new Card()	;로 인스턴스를 할당함
		 int i=0;
		 for(int k=1; k<=4; k++) { // 카드의 종류 1~4 반복
			 for(int n=1; n<=13; n++) { // 카드 번호 1~13 반복
				 cards[i]=new Card(k,n); // 카드 장수 i는 0~51
				 i++;
			 }
		 }
	 }
	public Card pick(int i) {
		return cards[i]; // cards[i] 객체(참조값)가 리턴
	}
	public void shuffle() {
		// 모든 카드를 한번씩 랜덤한번째의 카드와 자리바꿈함. 반복실행 이용
		for(int i=0; i<52; i++) {
			int r=(int)(Math.random()*52);
			Card temp=cards[i];
			cards[i]=cards[r];
			cards[r]=temp;
		}
	}
}

public class Game {
	public static void main(String[] args) {
		CardDeck d=new CardDeck();
		d.shuffle();
		/*
		Card c1=d.pick(0);
		System.out.printf("%s ",c1.toString());
		System.out.printf("%s ", d.pick(1).toString());
		System.out.printf("%s ", d.pick(2));
		System.out.printf("%s ", d.pick(3));
		System.out.printf("%s ", d.pick(4));
		*/
		// 현재 프로그램을 1인당 카드 7장, 플레이어 5명으로 늘려서 카드를 골고루 분배하고
		// 플레이어 1명당 한줄에 분배된 카드를 출력
		Card []p1=new Card[7];
		Card []p2=new Card[7];
		Card []p3=new Card[7];
		Card []p4=new Card[7];
		Card []p5=new Card[7];
		int k=0;
		for(int i=0; i<p1.length; i++) {
			p1[i]=d.pick(k++);
			p2[i]=d.pick(k++);
			p3[i]=d.pick(k++);
			p4[i]=d.pick(k++);
			p5[i]=d.pick(k++);
		}
		for(int i=0; i<7; i++) System.out.printf("%s",p1[i]); 
		System.out.println();
		for(int i=0; i<7; i++) System.out.printf("%s",p2[i]); 
		System.out.println();
		for(int i=0; i<7; i++) System.out.printf("%s",p3[i]); 
		System.out.println();
		for(int i=0; i<7; i++) System.out.printf("%s",p4[i]); 
		System.out.println();
		for(int i=0; i<7; i++) System.out.printf("%s",p5[i]);
		/*
		Card c=new Card(Card.diamond, 11);
		System.out.println("Card: "+c.toString());
		Card d=new Card(Card.diamond, 1);
		System.out.println("Card: "+d.toString());
		System.out.println("Card: "+c);
		System.out.println("Card: "+d);
		*/
	}
}