Post

2024.JAN.01(THU) JAVA DAY 21

✅ singleton, map

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
//Book.java
public class Book {
    private String title;
    private String author;

    public Book() {
    }

    public Book(String title, String author) {
        this.title = title;
        this.author = author;
    }

    public void displayInfo() {
        System.out.println("책 제목: " + title + "이고, 작가는 " + author + "입니다.");
    }
}

//Car.java
public class Car {
    private int year;
    private String color;

    public Car() {
    }

    public Car(int year, String color) {
        this.year = year;
        this.color = color;
    }

    public void drive() {
        System.out.println(year + "년식 자동차를 주행합니다.");
    }

    public void stopEngine() {
        System.out.println(year + "년식 자동차의 시동을 끕니다.");
    }

    public void showInfo() {
        System.out.println("이 차의 년식: " + year + "이고, 색상은 " + color + "입니다.");
    }
}

//Singleton.java
@Retention(RetentionPolicy.RUNTIME)
@Target({ElementType.METHOD, ElementType.TYPE})
//TYPE: class, interface
public @interface Singleton {
    String name();

}

//SingletonConfig.java
public class SingletonConfig {
    @Singleton(name = "book")
    public Book makeBook(){
        return new Book("title", "author");
    }

    @Singleton(name = "book2")
    public Book makeBook2(){
        return new Book("title2", "author2");
    }

    @Singleton(name = "car")
    public Car makeCar(){
        return new Car(2022, "red");
    }

    @Singleton(name = "car3")
    public Car makeYellowCar(){
        return new Car(2021, "yellow");
    }
}

//SingletonContext.java
public class SingletonContext {
    private static SingletonConfig config;
    private static Map<String, Method> singletonMap = new HashMap<>();
    private static Map<String, Object> singletonObjectMap = new HashMap<>();

    public static void setConfig(SingletonConfig config) {
        SingletonContext.config = config;
    }

    static synchronized Object getSingleton(String name) throws
        //name에 해당하는 싱글톤 객체를 반환한다.
        InvocationTargetException, IllegalAccessException{
        //주어진 name에 해당하는 객체가 있는지 확인한다.
            Object singletonObject = singletonObjectMap.get(name);
        //없으면 config객체를 총해 싱글톤 패턴을 구현한 클래스에서 생성된다.
            if (singletonObject == null){
                singletonObject= singletonMap.get(name).invoke(config);
                singletonObjectMap.put(name, singletonObject);
        }
        return singletonObject;
    }

    public static void executeMethodsBySingletonAnnotation(Object object) {
        //주어진 object가 가지고 있는 메소드를 검사한다.
        //@Singleton Annotation이 적용된 메소드를 찾아 그 메소드와 이름을 map에 저장한다.
        Class<?> clazz = object.getClass();
        Method[] methods= clazz.getDeclaredMethods();

        for(Method method:methods){
            Annotation[] annotations = method.getDeclaredAnnotations();
            for(Annotation annotation:annotations){
                if(annotation instanceof Singleton){
                    Singleton singletonAnnotation= (Singleton) annotation;
                    String name= singletonAnnotation.name();
                    singletonMap.put(name, method);
                }
            }
        }
    }
}

//Main.java
public class Main {
    public static void main(String[] args) throws InvocationTargetException, IllegalAccessException {
        SingletonConfig singletonConfig = new SingletonConfig();

        SingletonContext.executeMethodsBySingletonAnnotation(singletonConfig);
        SingletonContext.setConfig(singletonConfig);

        Book book = (Book) SingletonContext.getSingleton("book");
        Book bookCopy1 = (Book) SingletonContext.getSingleton("book");
        Book bookCopy2 = (Book) SingletonContext.getSingleton("book");

        Book book2 = (Book) SingletonContext.getSingleton("book2");

        Car redCar = (Car) SingletonContext.getSingleton("car");
        Car yellowCar = (Car) SingletonContext.getSingleton("car3");
        Car yellowCar2 = (Car) SingletonContext.getSingleton("car3");

        book.displayInfo();
        bookCopy1.displayInfo();
        bookCopy2.displayInfo();

        System.out.println("두 객체는 같나요? " + ( book == bookCopy1 ) );

        book2.displayInfo();

        redCar.showInfo();
        yellowCar.showInfo();
        yellowCar2.showInfo();

        System.out.println("두 객체는 같나요? " + ( redCar == yellowCar ) );
        System.out.println("두 객체는 같나요? " + ( yellowCar == yellowCar2 ) );
    }
}

//    책 제목: title이고, 작가는 author입니다.
//        책 제목: title이고, 작가는 author입니다.
//        책 제목: title이고, 작가는 author입니다.
//        두 객체는 같나요? true
//        책 제목: title2이고, 작가는 author2입니다.
//        이 차의 년식: 2022이고, 색상은 red입니다.
//        이 차의 년식: 2021이고, 색상은 yellow입니다.
//        이 차의 년식: 2021이고, 색상은 yellow입니다.
//        두 객체는 같나요? false
//        두 객체는 같나요? true



This post is licensed under CC BY 4.0 by the author.