TIL. 스태틱, 싱글톤패턴

hyuko·2023년 1월 12일
0

Java

목록 보기
22/26

스태틱

스태틱 이란?

  • static 이 붙어 있으면, 메모리의 공간자체가 다른 아이이다.
  • static 영역은 공유가 되는 영역이다.
  • 생성될 때 따로 다시 생성이 되는 영역이 아닌 클래스가 선언이 될 때 바로 메모리에 공간이 생긴다.
  • 그 static 으로 정의된 아이는 하나만 정의된다.

그 이유로 인해서 static 을 쓰게 되면 Class.스태틱 을 쓸 수가 있다.

  • 스태틱 메소드안에는 지역변수는 상관 없으나 전역변수를 쓰고 싶을 때는 스태틱변수만 가능하다.

예를 들어서 하나의 종이에 한 사람씩 이름을 쓰고 번호를 적게되는데 최초에 처음 사람은 1번이라고 쓴후
그다음 번호인 2번을 적어주고 다음사람에게 넘겨준다는 방식이 있다 이러할 때 하나의 종이라는 개념이 static 이다.
즉 공유되는 하나의 공간이라는 의미를 가진다.


스태틱 예제 코드

  • Student 라는 객체가 생성이 될 때마다 studentCode가 생성이 된다
  • 이 studentCode는 20230000 으로 고정되어 있는 값에 ai라는 값을 더해
  • 자동적으로 생성 될 때마다 20230001, 20230002 처럼 늘어나길 원한다.
public class Student {

    private static final int CODE = 20230000;
    private static int ai = 1; // auto_increment 자동 증가

    private int studentCode;
    private String name;

    // 생성이 될 때 마다 studentCode 가 생성이 되는데
    // 그 생성 되는 코드는 상수값 20230000 고정 되어 있는 값에
    //ai 값을 더하게 되고 그후 static 으로 만든 변수인 ai는 공유되는 공간이기에
    //ai++ 을 하는경우 1에서 1이 더해진 2가 다음 생성 때 대입이 된다.
    public Student(String name) {
        studentCode = CODE + ai;
        ai++;
        this.name = name;
    }

    public static int getAutoIncrement() {
        System.out.println("현재 AI: " + ai);
//        System.out.println("학생이름: " + name); 스태틱 메소드에서 꼭 생성이 되어야 있는 변수를 썻기때문에 쓸 수 없다.
        return ai;
    }

    @Override
    public String toString() {
        return "Student{" +
                "studentCode=" + studentCode +
                ", name='" + name + '\'' +
                '}';
    }
}

==================================================

public class StudentMain {

    public static void main(String[] args) {
        Student[] students = new Student[5];
        

        students[0] = new Student("홍길동");
        students[1] = new Student("김유신");
        students[2] = new Student("강감찬");
        students[3] = new Student("이순신");
        students[4] = new Student("장보고");

       

        for (int i = 0; i < students.length; i++) {
            System.out.println(students[i]);
            
        }

        System.out.println();

       
        for (Student student : students) {
            System.out.println(student);
            
           
        }

        int autoIncrement = Student.getAutoIncrement();
        System.out.println(autoIncrement);
    }
}

  • 위의 코드를 실행하게 되면 나오는 콘솔화면


싱글톤 패턴 (생성패턴)

싱글톤이란?

  • 단 한번의 생성만 일어난다.
  • 하나의 클래스에 오직 하나의 인스턴스를 가진다.

하나의 클래스를 이용해서 많은 객체(인스턴스)를 생성해서 쓸 수 있지만, 하나의 고정된 객체로 여러군데에
쓰이는 경우 싱글톤을 이용한다.


하나의 클래스에서 하나의 객체만 생성해서 쓴다 즉 static 을 이용하지만 생성은 한번만 일어나기 때문에
생성은 한번만 일어나기위해 생성자를 private 로 막아주고 이 클래스의 객체가 한번 생성이 될 당시에
어디에서든 같은 값을 접근 할 수 있게 static 변수로 instance 를 null 로 초기화 해주고
최초에 메서드가 선언이 될 때 instance 의 값을 생성해서 대입해준다.
그 후에는 null 값이 아니기 때문에 같은 instance 값을 리턴하게 된다.
그 이유는 static 이기 때문에 값이 변경되지 않으면 그대로 그 값을 들고 있기 때문이다.
이로써 이 클래스는 유일한 객체가 되었다.

  • 싱글톤의 기본 생성 방식

public class Singletone {
	private static Singletone instance = null;
	
    private Singletone(){}
    
    public static Singletone getInstance() {
    	if(instance == null) {
        	instance = new Singletone();
        }
        return instance;
    }
}

싱글톤 예제코드

  • A라는 클래스는 학생의 정보를 배열에 담고, 학생을 저장하고, 보여주는 메서드를 가진다
  • 이 A라는 클래스를 B는 학생을 저장하는 메서드를 쓰길 원한다.
  • C클래스는 A에 있는 학생을 보여주는 메서드를 사용하길 원한다.

여기서 우리는 A를 싱글톤으로 제작해서 만들어 본다.

public class A {

    private static A instance = null;
    private Student[] students;


    private A() {
        students = new Student[3];
    }

    public static A getInstance() {
        if (instance == null) {
            instance = new A();
        }
        return instance;
    }

    public void addStudent(Student student) {
        for (int i = 0; i < students.length; i++){
            if (students[i] == null) {
                students[i] = student;
                return;
            }
        }
        System.out.println("더 이상 학생을 추가할 수 없습니다.");
        System.out.println();
    }

    public void showStudents() {
        for (Student student : students) {
            if (student != null) {
                System.out.println(student);
            }
        }
        System.out.println();
    }
}

==============================================

public class B {

    public void insertStudent() {
        Scanner scanner = new Scanner(System.in);

        System.out.print("학생 이름: ");
        String name = scanner.nextLine();


        Student student = new Student(name);
        A.getInstance().addStudent(student);
        A.getInstance().showStudents();
    }
}


===========================================

public class C {

    public void showAll() {
        A.getInstance().showStudents();
    }
}

여기서 본래 싱글톤을 쓰지 않는다면 B라는 객체는
A를 생성해서 a.메소드 이런식으로 써야할 것이고

C도 마찬가지로 A를 생성해야 쓸 수 있다.
하지만 생성할 필요없이 유일한 객체인 A를 생성하지
않으면서 A.getInstance를 통해 메서드들을 불러와서 쓸 수 있다.


profile
백엔드 개발자 준비중

0개의 댓글