1. 싱글톤 패턴 (Singleton Pattern)
디자인 패턴 중 하나로, 특정 클래스의 인스턴스가 하나만 생성되어 전역적으로 접근 가능하도록
하는 패턴이다. 싱글턴 패턴은 주로 리소스 공유, 설정 관리, 로깅, 드라이버 객체 관리 등과 같이
애플리케이션 내에서 단 하나의 인스턴스만 필요한 경우에 사용된다.
💡 싱글톤 패턴의 사용 목적
- 리소스 접근의 중복 방지
싱글톤 패턴은 리소스나 서비스에 대한 중복된 접근을 제한하여, 과도한 리소스 사용을 방지하고
효율적인 자원 관리를 가능하게 한다. - 전역 접근 지점 제공
싱글톤 인스턴스는 애플리케이션 전역에서 접근 가능한 고정된 접근 지점을 제공하여,
모든 컴포넌트가 필요한 서비스에 쉽게 접근할 수 있게 한다. - 인스턴스의 유일성 보장
클래스의 인스턴스가 하나만 생성되는 것을 보장함으로써, 인스턴스 간 데이터 불일치 문제를 예방할 수 있다.
💡 싱글톤 패턴 구현 방법
- private 생성자
외부에서 인스턴스를 직접 생성할 수 없도록 생성자를 private로 선언한다. - private static 인스턴스 변수
클래스 내부에서 유일한 인스턴스를 참조할 private static 변수를 선언한다. - public static 메소드
외부에서 인스턴스에 접근할 수 있는 public static 메소드를 제공한다.
이 메소드는 내부적으로 private static 변수를 통해 인스턴스에 접근하며, 인스턴스가 아직 생성되지 않았다면
새로 생성하여 반환한다.
💻 예제 코드01
public class Singleton {
// 유일한 인스턴스를 저장할 private static 변수
private static Singleton instance;
// 생성자를 private으로 선언하여 외부에서의 인스턴스 생성을 막음
private Singleton() {}
// 인스턴스에 접근할 수 있는 public static 메소드
public static Singleton getInstance() {}
if(instance == null) {
//인스턴스가 아직 생성되지 않았다면 새로 생성
instance = new Singleton();
}
return instance;
}
}
💻 예제 코드02
package pack01;
public class Ex08_SingletonClass {
int kor = 90;
public Ex08_SingletonClass() {
}
private static Ex08_SingletonClass class1 = new Ex08_SingletonClass(); // 자기 자신을 new
public static Ex08_SingletonClass getInstance() {
return class1;
}
}
package pack01;
import java.time.LocalDate;
public class Ex08_Main {
public static void main(String[] args) {
// 싱글톤 패턴 연습
Ex08_SingletonClass() s1 = new Ex08_SingletonClass();
System.out.println(s1.kor);
Ex08_SingletonClass() s2 = new Ex08_SingletonClass(); // new를 만들면 인스턴스가 계속 추가됨
System.out.println(s2.kor);
System.out.println(s1 + " " + s2);
System.out.println(s1.hashCode() + " " + s2.hashCode());
// 90
// 90
// pack01.Ex08_SingletonClass@6504e3b2 pack01.Ex08_SingletonClass@515f550a
// 1694819250 1365202186
// s1의 값을 s3, s4와 공유
Ex08_SingletonClass s3 = Ex08_SingletonClass().getInstance();
System.out.println(s3.kor);
Ex08_SingletonClass s4 = Ex08_SingletonClass().getInstance();
System.out.println(s4.kor);
System.out.println(s3.hashCode() + " " + s4.hashCode());
// 90
// 90
// 1330106945 1330106945
// 날짜 출력 싱글톤 사용 예
LocalDate mynow = LocalDate.now();
LocalDate mynow2 = LocalDate.now(); // 같은 인스턴스를 mynow, mynow2에 공유
System.out.prinln(mynow.hashCode() + " " + mynow2.hashCode()); // 주소가 같기 나온걸 확인
System.out.println(mynow2.getYear()); // 내 컴퓨터가 가지고 있는 년도를 알려줌(윤년 체크 다 하고 출력)
디자인 패턴 정리
안녕하세요~ Jay의 블로그입니다.
realzero0.github.io
- 출처 : realzero0 github.io
2. 배열 참조형 변수
자바에서 배열은 참조형 변수(Reference type variable)이다.
참조형 변수는 메모리상의 객체나 배열을 가리키는 변수로, 데이터가 아니라 데이터가 저장된 주소값을 갖는다.
이는 기본 자료형 변수(Primitive type variable)와 대비되는 개념인데, 기본 자료형 변수는 실제 데이터 값을 저장한다.
(int, double, boolean 등)
기본형 | 참조형 |
int a = 5; | car car1 = new car; |
int b; | car car2; |
b = a; | car2 = car1; |
값을 전달 | 주소 전달 |
💡 배열 참조형 변수 사용 시 주요 특징
- 메모리 주소 저장
배열 변수는 실제 배열 데이터가 저장된 메모리의 주소를 저장한다.
이 주소를 통해 배열의 데이터에 접근할 수 있다. - 동적 할당
배열은 실행 시간에 크기가 결정되며, 필요에 따라 객체처럼 동적으로 메모리를 할당받는다.
이 과정은 new 키워드를 사용하여 수행된다. - 타입 안정성
배열은 선언될 때 그 원소의 타입이 명시되어야 하며, 해당 타입의 데이터 만을 저장할 수 있다.
이는 프로그램의 안정성을 보장하는 데 도움을 준다. - 가비지 컬렉션
배열 참조형 변수가 더 이상 배열을 참조하지 않게 되면
(즉, 참조하는 변수가 없거나 다른 배열을 참조하도록 변경되면),
해당 배열은 가비지 컬렉션의 대상이 된다.
자바의 가비지 컬렉터는 더 이상 사용되지 않는 메모리를 자동으로 회수한다.
💡 배열 선언과 초기화
int[] arr; // 배열 참조형 변수 선언
arr = new int[5]; // 정수형 배열의 메모리 할당과 참조 변수 초기화
💡 배열 선언함과 동시에 초기화
int[] arr = {1, 2, 3, 4, 5} // 배열 선언과 동시에 초기화
💻 예제 코드
package pack01;
public class Ex09_Callby01 {
int a = 10; // 기본형 변수
int b = 20;
int c[] = {1, 2}; //배열 참조형 변수
}
package pack01;
public calss Ex09_Callby02 {
public void ex(int a, int b) { // 매개변수(parameter)로 기본형을 사용. 값이 넘어옴
int imsi = a;
a = b;
b = imsi;
System.out.println("메소드 내의 a : " + a + ", b : " + b);
}
public void ex(Ex09_Callby01 data) { // 매개변수로 참조형을 사용. 객체 주소가 넘어옴
int imsi = data.a; // imsi에 a의 값을 넘김
data.a = data.b; // data.b에 data.a 값을 넘김(10)
data.b = imsi; // imsi에 data.b 값을 넘김(20)
Sytem.out.println("메소드 내의 a : " + data.a + ", b : " + data.b);
}
public void ex(int[] ar) {
int imsi = ar[0]; // Ex09_Callby에 있는 int c[] = {1, 2}; 의 첫 번째 값을 줌.
ar[0] = ar[1];
ar[1] = imsi;
System.out.println("메소드 내의 배열 요소[0]:" + ar[0] + ", [1]:" + ar[1]);
// 메소드 내의 배열 여소 [0]:2, [1]:1
}
}
package pack01;
public class Ex09_Main {
public static void main(String[] args) {
// 메소드 호출 시 매개변수를 통한 자료 전달 (타입이 기본형, 참조형) = (값이 전달되느냐, 주소가 전달되느냐)
Ex09_Callby01 myData = new Ex09_Callby01();
Ex09_Callby02 myMethod = new Ex09_Callby02();
System.out.println("원래 a:" + myData.a + ", b:" + myData.b); // 원래 a:10, b:20
myMethod.ex(myData.a, myData.b); // 인수로 기본형 전달(값이 전달)
// = System.out.println("메소드 내의 a : " + data.a + ", b : " + data.b); // 메소드 내의 a : 20, b : 10
System.out.println("1. 수행 후 a: " + myData.a + ", b:" + myData.b); // 원래의 값 호출
System.out.println();
myMethod.ex(myData); // Ex09_Callby01 객체 타입의 주소를 전달
System.out.println("2. 수행 후 a: " + myData.a + ", b:" + myData.b);
System.out.println();
//배열의 대표명은 주소를 가지고 있다
System.out.println("배열의 대표명 c : " + myData.c); // 배열의 대표명 c : [I@4ac68d3e
// int c[] = {1, 2};
// int kbs[] = myData.c; // myData.c의 주소를 kbs에게 주소를 치환했으므로 둘의 주소값은 같다.
// System.out.println(myData.c[0]); // 1
// System.out.println(kbs[0]); // 1
myMethod.ex(myData.c);
System.out.println("3. 배열 수행 후 a: " + myData.c[0] + ", b:" + myData.c[1]);
// 3. 배열 수행 후 a: 2, b:1
}
}
💻 결과
원래 a:10, b:20
메소드 내의 a : 20, b : 10
1. 수행 후 a: 10, b:20
메소드 내의 a : 20, b : 10
2. 수행 후 a: 20, b:10
배열의 대표명 c : [I@4ac68d3e
메소드 내의 배열 요소[0]:2, [1]:1
3. 배열 수행 후 a: 2, b:1
3. 포함 관계 (has a)
포함 관계는 객체 지향 프로그래밍에서 매우 중요한 개념 중 하나로, 한 클래스가 다른 클래스의 객체를 멤버 변수로 포함하는 관계를 말한다. 이 관계는 합성(Composition) 또는 집합(Aggregation)으로 더 구체화될
수 있으며, 객체 간의 상호작용을 통해 더 큰 기능을 구현하는 데 사용된다.
💡 has a 관계의 특징
- 재사용성
이미 구현된 클래스를 새로운 클래스에서 재사용할 수 있게 해 준다. - 낮은 결함도
클래스 간의 의존성을 최소화하여 시스템의 유연성과 유지 보수성을 향상시킨다. - 모듈성
시스템을 잘 정의된 컴포넌트로 분리하여 각 컴포넌트의 독립적인 개발과 테스트를 가능하게 한다.
💻 예시 코드
자동차와 엔진을 예로 들어 설명하면, 자동차는 엔진을 포함하고 있으며, 이는 자동차가 엔진의 기능을 사용한다는
것을 의미한다. 즉, 자동차 클래스는 엔진 클래스의 객체를 멤버 변수로 가지는 has a 관계에 있다.
class Engine {
// 엔진 관련 메소드와 변수
}
class Car {
private Engine engine; // Car has an Engine
public Car() {
engine = new Engine(); // Car 클래스 생성자에서 엔진 객체 초기화
}
// Car 클래스와 다른 메소드들
}
이 관계에서 Car 클래스는 Engine 클래스를 포함하고 있어, 엔진과 관련된 기능을 Car 객체를 통해 사용할
수 있다. 자동차가 주행하기 위해서는 내부적으로 엔진을 켜는 것처럼 말이다.
💻 예제 코드
package pack02;
public class Ex10_PohamHandle { // 부품 클래스
// 부품 만들기
int quantity; // 핸들 회전량
public Ex10_PohamHandle() {
quantity = 0;
}
String leftTurn(int q) {
quantity = q;
return "좌회전";
}
String rightTurn(int quantity) {
this.quantity = quantity;
return "우회전";
}
String straightTurn(int quantity) {
this.quantity = quantity;
return "직진";
}
}
package pack02;
public class Ex10_PohamCar {
// 여러 개의 부품이 모인 완성차 설계도(class)
int speed = 0;
String ownerName, turnMessageShow; // 완성차 설계도의 멤버필드 // 클래스도 멤버로 쓸 수 있음
// 객체가 안 만들어져 있기 때문에 Ex10_PohamCar(String name)에서만 사용가능함
Ex10_PohamHandle handle; // 부품 클래스를 자신의 멤버처럼 사용
public Ex10_PohamCar() {
}
public Ex10_PohamCar(String name) {
ownerName = name;
handle = new Ex10_PohamHandle(); // class의 포함관계(has a 관계)
}
public void playcarTurnHandle(int q) { // q = 핸들 회전량
if(q > 0) { // 우회전(양수)
turnMessageShow = handle.rightTurn(q);
}
if(q < 0) turnMessageShow = handle.leftTurn(q); // 좌회전(음수)
if(q == 0) turnMessageShow = handle.straightTurn(q);
}
}
package pack02;
public class Ex10_CarMain {
public static void main(String[] args) {
// 클래스의 포함관계 연습
Ex10_PohamCar tom = new Ex10_PohamCar("미스터 톰");
tom.playcarTurnHandle(30);
System.out.println(tom.ownerName + "의 회전량은 " + tom.turnMessageShow + " " + tom.handle.quantity);
// 미스터 톰의 회전량은 우회전 30
tom.playcarTurnHandle(-20);
System.out.println(tom.ownerName + "의 회전량은 " + tom.turnMessageShow + " " + tom.handle.quantity);
// 미스터 톰의 회전량은 좌회전 -20
System.out.println();
Ex10_PohamCar james = new Ex10_PohamCar("제임스 삼촌");
james.playcarTurnHandle(0);
System.out.println(james.ownerName + "의 회전량은 " + james.turnMessageShow + " " + james.handle.quantity);
// 제임스 삼촌의 회전량은 직진 0
}
}
💻 결과
미스터 톰의 회전량은 우회전 30
미스터 톰의 회전량은 좌회전 -20
제임스 삼촌의 회전량은 직진 0
[JAVA] IS-A 관계, HAS-A 관계
IS-A 관계, HAS-A 관계 안녕하세요? 장장스입니다. IS-A 관계, HAS-A 관계에 대해 알아보겠습니다. 객체지향 프로그래밍에서 우리는 상속을 사용합니다. 언제 상속을 사용해야 할까요? IS-A 관계 상속은
zangzangs.tistory.com
- 출처 : zangzangs tistory
[Java] 클래스 관계 HAS-A (포함) / IS-A (상속) 정리
클래스는 객체지향 프로그래밍에서 중요한 개념이다. 클래스의 Has-a, Is-a 관계에 대해 알아보자. 1. HAS-A (포함) 관계 HAS-A는 포함관계를 의미한다. ( ~는 ~을 가지고 있다.) 다른 클래스의 기능(변수
hyunki99.tistory.com
- 출처 : hyunki99 tistory
4. Frame class (포함 관계)
Frame class는 AWT(Abstract Window Toolkit) 패키지에 있는 GUI 컴포넌트 중 하나로, 윈도우 기반의 애플리케이션을 만들 때 사용한다. Frame은 최상위 윈도우이며, 타이틀 바, 보더 등 일반적으로 우리가 보는 창의 모습을 가지고 있다.
이 클래스는 다른 GUI 컴포넌트들을 포함할 수 있는 컨테이너 역할을 하며, 버튼, 텍스트 필드, 레이블 등을 담을 수 있다.
💻 예시 코드
import java.awt.Frame;
import java.awt.Label;
public class MyFrame {
public static void main(String[] args) {
Frame frame = new Frame("My First Frame"); // 프레임 생성. 타이틀은 "My First Frame"
Label label = new Label("Hello, World!"); // 레이블 컴포넌트 생성
frame.add(label); // 프레임에 레이블 추가
frame.setSize(300, 200); // 프레임의 크기를 설정
frame.setVisible(true); // 프레임을 화면에 표시
}
}
💻 예제 코드
package pack02;
import java.awt.Frame;
// 자바가 제공하는 Frame 클래스로 창 띄우기 : 포함 관계
public class MyFrame01 {
private String title = "포함 관계";
private Frame frame;
public MyFrame01() { // 생성자에 너무 많은 내용이 들어있으면 좋지 않다.
frame = new Frame(title);
}
private void display() {
frame.setSize(500, 300); // 프레임 사이즈
frame.setLocation(700, 450); // 너비와 높이(모니터 어디에 뜰건지) <<정중앙 ㅋㅋ
frame.setVisible(true); // 창 띄워!!!
}
public static void main(String[] args) {
MyFrame01 frame01 = new MyFrame01();
frame01.display();
}
}
💻 결과
[자바GUI-AWT] Frame클래스
1. Frame 클래스 ① 각종 응용프로그램을 위한 윈도우를 제공하는 클래스 ② 모든 GUI 프로그램에서는 ...
blog.naver.com
- 출처 : 래치 블로그
변수를 시작으로 배열까지는 자바에 어떠한 타입들이 있구나. 이럴 때 쓰는구나라고 이해했는데,
클래스로 넘어오면서 상속과 싱글톤 패턴.. 참조형 변수 등 새로운 것을 배우니 매우 어렵게 느껴졌다.
학원 다니기 한 달 전부터 생활코딩을 틈틈이 보며 자바에 대한 영상을 조금 봤는데, 엄청 기초적인..
자바의 개념, 변수, IOT 코드 따라 치는 것만 해봐서 더 어렵게 느껴지는 것일지도 모르겠다.
처음부터 다 이해하고 잘하는 사람이 어디 있겠는가 싶으면서도.. 개발하는 사람들이 너무 대단해 보이는 요즘이다.
지금 회고 작성하는 시점이 이날 수업 하고 나서 며칠이 흘렀는데 아직도 어렵고 헷갈리는 걸 보면 나는 더 노력해야
할 것 같다. 공부머리가 이럴 때 좀 돌아줬으면 좋겠는데...ㅠㅠ 화이팅 하자 내 자신!
'에이콘아카데미 회고 > 5회차) 자바기반 풀스택 개발자 양성과정' 카테고리의 다른 글
JAVA) 09번째 회고 (0) | 2024.04.11 |
---|---|
JAVA) 08번째 회고 (0) | 2024.04.09 |
JAVA) 06번째 회고 (0) | 2024.04.09 |
JAVA) 05번째 회고 (0) | 2024.04.02 |
JAVA) 04번째 회고 (0) | 2024.04.02 |