package util;
public interface IDataStore {
public int on(String $type, String $value);
public void off(String $type, Object $object);
public void off(String $type, int $id);
public void off(String $type);
public void off();
public void trigger(String $type, Object $object);
public void trigger(String $type);
}
어떤 특정한 스트링키에 매핑시킬 수 있는 여러 데이터를 가질 수 있는 자료구조예요.
상황에 따라 키가 스트링이 아닌 오브젝트로 바꿔서 사용해도 됩니다. 그럼 더욱 더 넓은 관계의 데이터 구조를 다룰 수 있게 되겠죠. 값이 아닌 키조차도 오브젝트형이라면.
내부적으론 자바의 Map과 배열리스트라는 자료를 응용해서 만든거구요.
C++의 STL을 사용하면 자바보다 훨씬 쉽게 구현할 수 있어요. STL은 구조체의 성격이라서 얼록이라는 과정이 필요없고 이 부분은 이런 자료구조의 로직에서 자바보다 더 쉬운 응용이 가능하더라구요. 그래서 쉬운 C++보다는 "아주 조금" 더 생각해야할 부분이 있는 자바로 구현했어요.
on이라는 메서드는 하나의 특정 키에 여러개의 값을 매핑할 수 있게 등록하는 기능을 가집니다.
off는 등록한 값을 지우는 기능을 하죠
trigger는 값을 꺼내는 역할을 합니당. 지금은 그냥 리턴 타입이 없게 만들어뒀어요.
테스트용에 불과하니까요 ㅎㅎ
package until;
import java.util.ArrayList;
import java.util.HashMap;
public class DataStore implements IDataStore{
private HashMap<String, ArrayList<Object>> index =
new HashMap<String, ArrayList<Object>>();
private static DataStore instance;
private DataStore(){}
public static DataStore sharedObject(){
if(instance == null){
instance = new DataStore();
}
return instance;
}
@Override
public int on(String $type, String $value) {
if(!this.index.containsKey($type)){
this.index.put($type, new ArrayList<Object>());
}
this.index.get($type).add($value);
return this.index.get($type).size();
}
@Override
public void off(String $type, Object $object) {
if(!this.index.containsKey($type)) return;
if(this.index.get($type).isEmpty()) return;
if(!this.index.get($type).contains($object)) return;
this.index.get($type).remove($object);
}
@Override
public void off(String $type, int $id) {
if(!this.index.containsKey($type)) return;
if(this.index.get($type).isEmpty()) return;
if($id >= this.index.get($type).size()) return;
this.index.get($type).remove($id);
}
@Override
public void off(String $type) {
if(!this.index.containsKey($type)) return;
if(this.index.get($type).isEmpty()) return;
this.index.get($type).clear();
}
@Override
public void off() {
this.index.clear();
}
@Override
public void trigger(String $type, Object $object) {
if(!this.index.containsKey($type)) return;
if(!this.index.get($type).contains($object)) return;
System.out.println($object);
}
@Override
public void trigger(String $type) {
if(!this.index.containsKey($type)) return;
for(int i=0; i<this.index.get($type).size(); ++i){
System.out.println(this.index.get($type).get(i));
}
}
}
로직을 보시면, 데이터 스토어는 맵을 갖고 있고 이 맵은 키에 매핑시킬 자료로 프리미티브값이 아닌 "배열"을 갖고 있어요.
on에서 데이터를 등록할 때, 연관키가 없을 경우에만 이 키에 대응시키는 배열을 얼록해주는 논리를 쓰고 있죠. 이 부분에서 STL보다는 살짝 더 고민을 해줘야하는 것 같아요. 얼록이라는 과정때문이죠.
테스트 코드는 아래와 같아요.
/* 데이터 스토어를 싱글턴 유형으로 생성 */
IDataStore dataStore = DataStore.sharedObject();
/* 객체에 사람이라는 키로 도킨스, 매트, 해리스를 저장 */
dataStore.on("사람", "도킨스");
dataStore.on("사람", "매트");
dataStore.on("사람", "해리스");
/* 객체에 동물이라는 키로 강아지, 고양이, 사자를 저장 */
dataStore.on("동물", "강아지");
dataStore.on("동물", "고양이");
dataStore.on("동물", "사자");
/* 사람이라는 키로 저장되어있는 모든 데이터를 출력 */
dataStore.trigger("사람");
System.out.println("----------");
/* 동물이라는 키로 저장되어있는 모든 데이터를 출력 */
dataStore.trigger("동물");
System.out.println("----------");
/* 사람이라는 키에서 john이라는 값을 지움.(그러나 john이라는 값이 저장되어 있지 않기 때문에 아무런 일도 발생하지 않음 */
dataStore.off("사람","john");
/* 사람이라는 키에서 해리스라는 값을 지움.(위에서 저장했던 해리스가 지워짐) */
dataStore.off("사람", "해리스");
/* 다시 출력. 사람이라는 키에서 해리스만 지워진것을 확인할 수 있음 */
dataStore.trigger("사람");
System.out.println("----------");
dataStore.trigger("동물");
System.out.println("----------");
댓글 없음:
댓글 쓰기