싱글톤 패턴을 이용한 CardFactory - Card 간의 관계 파악이 아직 덜 된 것 같다.
고유한 Serial을 각 인스턴스가 갖게 할 때 Factory측에서 시리얼을 들고 있다가 각 Card에 부여해주는 식으로 가는 줄 알았는데, Card 클래스 쪽에서 시리얼을 들고 있다가 생성자에서 인스턴스 생성 시 자신의 멤버 변수에 시리얼을 대입하는 방식으로 진행되고 있었다.
싱글톤 패턴 구현은 괜찮은데, 이런 부분이 약간 난해해서 더 많은 자료를 가지고 구현해보면서 복습해야 할 듯 하다.
this는 생성된 인스턴스 스스로를 가리키는 예약어이다.
Person.java
public class Person { private int age; public void setAge(age) { this.age = age; // 사용 예 } }
Person.java
public class Person { String name; int age; Person() { this("Hong", 24); } Person(String name, int age) { this.name = name; this.age = age; } }
주의할 점으론 this로 다른 생성자를 호출하기 이전에 다른 코드를 넣으면 안 된다. 클래스 생성 완료되지 않은 시점에서는 부를 수 없는 것이므로.
Person.java
... Person returnItSelf() { return this; // 자기 자신 반환 } ...
학생이 버스를 타거나 지하철을 타는 경우를 예로 들어 보겠다.
package 명은 cooperation, 학생 클래스는 이름, 학년, 소지금을 갖는다.
코드가 많이 길어져서 링크로 대체
https://gist.github.com/crisine/6b546a89f54f8e9cb38f1264bbcbeb01
출력 :
Hong님의 남은 돈은 7500입니다.
버스 100번의 승객은 1명이고, 수입은 1000입니다.
1호선의 승객은 1명이고, 수입은 1500입니다.
Student를 여러 명 선언하고 각각에게 고유한 학번을 순서대로 부여하려고 하면 전체 학생들이 공유할 수 있는 정적 변수가 필요해진다.
static int serialNum; // 정적 변수
여러 명의 학생 인스턴스를 생성하고, 개별 인스턴스마다 각각 고유한 학번을 갖도록 하며 실제로 그렇게 고유한 값이 할당되었는지 확인하는 예제를 작성해보자.
Student.java
package staticex; public class Student { static int serialNum = 1; int studentID; public Student() { this.studentID = serialNum++; } public void showInfo() { System.out.println("student ID : " + studentID); } }
MainClass.java
package staticex; public class MainClass { public static void main(String[] args) { Student st1 = new Student(); Student st2 = new Student(); st1.showInfo(); st2.showInfo(); } }
출력 :
student ID : 1
student ID : 2
System.out.println(Student.serialNum); ...
Student는 클래스 이름. 여기서는 직접 클래스 이름으로 serialNum 변수를 참조중이다.
static 변수는 인스턴스 생성과는 별개로 먼저 생성되므로, 생성 전에 이렇게 직접 참조도 가능.
static 변수를 위한 메서드도 있는데 이를 'static 메서드' 또는 '클래스 메서드' 라고 함.
Student.java
public class Student { private static int serialNum = 1000; ... public static int getSerialNum() { int i = 10; return serialNum; } public static void setSerialNum(int serialNum) { Student.serialNum = serialNum; } }
StudentTest.java
public class StudentTest { public static void main(String[] args) { Student student = new Student(); System.out.println(Student.getSerialNum()); } }
serialNum 을 직접 참고하지 않고 get() 메서드를 사용하여 참조하며 static 메서드로 클래스 이름을 직접 호출하고 있음.
static으로 선언되지 않은 멤버 변수의 경우에는 인스턴스 생성 시에 생성되는 변수이므로 클래스 내의 메서드에서는 사용할 수 없다.
지역 변수(로컬 변수) : 스택 메모리, 함수 외부로 나가면 소멸
멤버 변수(인스턴스 변수) : 힙 메모리, 가비지 컬렉터가 메모리 수거시 소멸
static 변수(클래스 변수) : 데이터 영역, 프로그램 시작 시 생성, 프로그램 종료 후 메모리 해제 시 소멸
객체 지향에서 인스턴스를 단 하나만 생성하는 디자인 패턴을 싱글톤 패턴이라 한다.
직원은 여러명 일 수 있지만 회사는 한개여야 하는 경우가 그렇다.
Company.java
package singleton; public class Company { private static Company instance = new Company(); private Company() { } public static Company getInstance() { if (instance == null) { instance = new Company(); } return instance; }
CompanyMain.java
package singleton; public class CompanyMain { public static void main(String[] args) { Company com1 = Company.getInstance(); Company com2 = Company.getInstance(); System.out.println(com1 == com2); } }
회사 클래스에서 static으로 유일한 인스턴스를 생성했고, 이렇게 생성한 인스턴스는 외부에서 접근할 수 있게 열어줘야 하므로 getInstance 메서드를 만들었다.
해당 메서드는 만약 인스턴스가 생성되지 않은 경우 인스턴스를 만들고, 생성된 인스턴스를 반환해준다.
이를 테스트하기 위해서 CompanyMain에서 변수를 두 개 만들고, 이 두 변수의 주소 값이 같은지 체크한다.
출력 :
true
동일한 인스턴스임을 확인했다.