SILENTSOFT
Published on

Java로 클래스 간 객체 공유하기

Authors

앞 포스팅에서 직접 참조를 없애고 클래스 간 이벤트 통신 함으로써 의존도를 낮췄다. 이번 포스팅에서는 이벤트 통신시, 클래스 간 객체를 공유하는 방법에 대해 설명하려고 한다.

사실 이벤트 호출시 Object를 파라메터로 추가하여 던지고 받아도 되지만, 이렇게 할 경우 해당 이벤트를 구현하는 클래스가 아닌, 다른 이벤트를 구현하는 클래스에서는 필요할 때 값을 참조하지 못하는 딜레마가 발생한다.

이 딜레마를 해결하려면, 예를들어 "EVENT_A"라는 이벤트를 호출할 때 어떤 객체를 파라메터로 넘겨주면 "EVENT_A" 이벤트를 구현하는 클래스에서 해당 객체와 함께 "EVENT_B" 이벤트를 다시 호출하여야 한다.

SharedMemory 클래스를 아래와 같이 작성하면 언제 어디서든 원할 때 값을 참조할 수 있어서 위 딜레마를 더 쉽게 해결할 수 있다.

SharedMemory.java
package org.silentsoft.io.memory;

import java.util.HashMap;

public final class SharedMemory {
	private static HashMap<String, Object> hashMap = new HashMap<String, Object>();

	public static synchronized HashMap<String, Object> getHashMap() {
		return hashMap;
	}

	public static synchronized void setHashMap(HashMap<String, Object> target) {
		hashMap = target;
	}
}

Event와 함께 사용하는 방법은 다음과 같다.

(코드는 앞 포스팅에서 작성했던 ListenerA, ListenerB를 조금 수정했다.)

ListenerA.java
package org.silentsoft.blog.event;

import java.util.ArrayList;

import org.silentsoft.io.memory.SharedMemory;
import org.silentsoft.io.event.EventHandler;
import org.silentsoft.io.event.EventListener;

public class ListenerA implements EventListener {
	public ListenerA() {
		EventHandler.addListener(this);
	}

	@Override
	public void onEvent(String event) {
		if (event.equals("EVENT_A")) {
			// do something here for EVENT_A event.
			System.out.println("I am A !");

			ArrayList<String> list = new ArrayList<String>();
			list.add("AA");
			SharedMemory.getHashMap().put("shared", list);
			list.add("BB");
		}
	}
}
ListenerB.java
package org.silentsoft.blog.event;

import org.silentsoft.io.memory.SharedMemory;
import org.silentsoft.io.event.EventHandler;
import org.silentsoft.io.event.EventListener;

public class ListenerB implements EventListener {
	public ListenerB() {
		EventHandler.addListener(this);
	}

	@Override
	public void onEvent(String event) {
		if (event.equals("EVENT_B")) {
			// do something here for EVENT_B event.
			System.out.println("I am B !");
			System.out.println(SharedMemory.getHashMap().get("shared")
					.toString());
		}
	}
}

Event 호출 코드

package org.silentsoft.blog.event;

import org.silentsoft.io.event.EventHandler;

public class Example {
	public static void main(String[] args) {
		ListenerA listenerA = new ListenerA();
		ListenerB listenerB = new ListenerB();

		EventHandler.callEvent(Example.class, "EVENT_A", false); // 동기 호출
		System.out.println("After introduce ListenerA");
		EventHandler.callEvent(Example.class, "EVENT_B"); // 비동기 호출
	}
}

ListenerA에서 "EVENT_A" 이벤트를 수신했을 때, ArrayList를 선언하고 "AA" 요소를 add한 뒤, SharedMemory에 넣었다. 이후, "BB" 요소를 add했다.

ListenerB에서 "EVENT_B"를 수신했을 때, ListenerA가 SharedMemory에 넣은 list를 출력한다. 이때, 출력값은 AA, BB이다.

예제를 위하여 이벤트 명과, SharedMemory의 Key값을 하드 코딩했지만, 영향도 분석 및 파악을 위하여 가능하면 이벤트 명은 EventConst 같은 클래스에, SharedMemory의 Key값은 KeyConst 같은 클래스를 만들어서 한 곳에 선언하는 것을 추천한다.