Created
July 3, 2012 21:55
-
-
Save fumokmm/3043617 to your computer and use it in GitHub Desktop.
Javaで型トークンを利用したファクトリクラス
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
package fumokmm.test.factory; | |
import java.util.*; | |
import org.junit.*; | |
import static org.junit.Assert.*; | |
import static org.hamcrest.CoreMatchers.*; | |
public class FactoryTest { | |
static abstract class Alphabet { | |
abstract String whoAmI(); | |
} | |
static class A extends Alphabet { | |
@Override String whoAmI() { return "I'm A!"; } | |
} | |
static class B extends Alphabet { | |
@Override String whoAmI() { return "I'm B!"; } | |
} | |
static class C extends Alphabet { | |
@Override String whoAmI() { return "I'm C!"; } | |
} | |
static interface Animal {} | |
static class Cat implements Animal {} | |
static class Dog implements Animal {} | |
static class Factory<T> { | |
private Map<Class<? extends T>, T> instanceMap = | |
new HashMap<Class<? extends T>, T>(); | |
public <U extends T> U getOrCreate(Class<U> clazz) { | |
if (! instanceMap.containsKey(clazz)) { | |
try { | |
instanceMap.put(clazz, clazz.newInstance()); | |
} catch (InstantiationException e) { | |
e.printStackTrace(); | |
} catch (IllegalAccessException e) { | |
e.printStackTrace(); | |
} | |
} | |
return clazz.cast(instanceMap.get(clazz)); | |
} | |
} | |
// 以下テスト | |
Factory<Alphabet> factory; | |
@Before | |
public void setup() { | |
factory = new Factory<Alphabet>(); | |
} | |
@Test | |
public void createするテスト() { | |
A a = factory.getOrCreate(A.class); | |
assertThat(a instanceof A, is(true)); | |
B b = factory.getOrCreate(B.class); | |
assertThat(b instanceof B, is(true)); | |
C c = factory.getOrCreate(C.class); | |
assertThat(c instanceof C, is(true)); | |
} | |
@Test | |
public void AlphabetとしてCreateするテスト() { | |
Alphabet someAlp = factory.getOrCreate(A.class); | |
assertThat(someAlp.whoAmI(), is("I'm A!")); | |
assertThat(someAlp instanceof A, is(true)); | |
someAlp = factory.getOrCreate(B.class); | |
assertThat(someAlp.whoAmI(), is("I'm B!")); | |
assertThat(someAlp instanceof B, is(true)); | |
} | |
@Test | |
public void Factoryの使い分けのテスト() { | |
// Animal用のFactory | |
Factory<Animal> aniFactory = new Factory<Animal>(); | |
aniFactory.getOrCreate(Cat.class); | |
aniFactory.getOrCreate(Dog.class); | |
//aniFactory.getOrCreate(A.class); | |
// => コンパイルエラー:aniFactoryは Animal を extends (implements) したクラスのみ生成可能 | |
} | |
@Test | |
public void インスタンスは同じファクトリ内で使い回されるテスト() { | |
assertThat("最初はサイズ0", factory.instanceMap.size(), is(0)); | |
A a1 = factory.getOrCreate(A.class); | |
assertThat("Aを生成&取得", factory.instanceMap.size(), is(1)); | |
factory.getOrCreate(B.class); | |
assertThat("Bを生成&取得", factory.instanceMap.size(), is(2)); | |
A a2 = factory.getOrCreate(A.class); | |
assertThat("Aは既に取得済みなので増えない", factory.instanceMap.size(), is(2)); | |
assertSame("同じオブジェクトのはず", a1, a2); | |
} | |
} |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment