- 개요
- 공유 가능한 정보를 객체 형태로 정의하고 재활용(Object Pooling) 해서 객체(컴퓨터 자원)수를 최소함으로 가볍게 합니다. (예로, 비행기 게임에서 적들의 비행기에 사용하는 이미지가 있을 때 유사한 많은 적 객체들마다 이미지를 가지고 있으면 많은 이미지들을 사용하게 되므로 자원을 많이 사용하게 된다. 그러나 해당 적 이미지들을 공유하는 객체를 사용함으로 자원을 가볍게 사용하도록 할 수 있다.)
- 구조 예
- Marine과 Firebat 은 Client에게 공유(재활용)할려는 객체이고, UniqueHero는 공유하지 않는 객체이다. Barrack 으로 Factory Method Pattern 이 적용 되어 있다. (Marine과 Firebat은 생성된 객체를 재 사용하지만, UniqueHero는 매번 객체를 생성한다. Client에서는 Marine과 UniqueHero를 같은 인터페이스로 접근할 수 있다.)
- 소스
public abstract class AUnit {
abstract void attack();
}
public class Marine extends AUnit {
void attack() {
System.out.println("marine attack()");
}
}
public class Firebat extends AUnit {
void attack() {
System.out.println("firebat attack()");
}
}
public class UniqueHero extends AUnit {
void attack() {
System.out.println("uniqueHero attack()");
}
}
public class Barrack {
private HashMap<Integer, AUnit> unitMap = new HashMap<Integer, AUnit>();
public AUnit getUnit(int unitType) {
if (unitType == 3)
return new UniqueHero();
if (unitMap.get(unitType) != null)
return unitMap.get(unitType);
AUnit unit = null;
if (unitType == 1)
unit = new Marine();
else if (unitType == 2)
unit = new Firebat();
else
return null;
unitMap.put(unitType, unit);
return unit;
}
public int getUnitSize() {
return unitMap.size();
}
}
public class Client {
public static void main(String[] args) {
Barrack barrack = new Barrack();
AUnit marine = barrack.getUnit(1); // marine 생성 (+1)
marine.attack();
AUnit marine2 = barrack.getUnit(1); // 이미 생성된 marine 재 사용
marine2.attack();
AUnit firebat = barrack.getUnit(2); // firbat 생성 (+1)
firebat.attack();
AUnit uniqueHero = barrack.getUnit(3); // 매번 새로운 uniqueHero 생성
uniqueHero.attack();
System.out.println("hashMap size[" + barrack.getUnitSize() + "]");
}
}
결과 화면
marine attack()
marine attack()
firebat attack()
uniqueHero attack()
unit size[2]
- 구현 관련
- 공유할려는 객체(Marine, Firebat)가 1개씩일 경우에는 Barrack을 없애고 Marine와 Firebat을 싱글톤으로 만들어도 된다. 그러나 공유할려는 객체가 2개 이상일 경우에는 Barrack에서 Object Pooling을 해주면 된다.
- 공유하는 객체가 사용되지 않으면 객체를 없애주는 것이 자원 활용에 효과적이다. 이때에는 공유 객체를 사용하지 않을 때 삭제 해야 하므로 Reference Counting 기법을 사용하면 된다.
- 참고