@Test public void enhancedSubclassIsDirtyWorks() { SampleClass2 testObject2 = new SampleClass2(); testObject2.setFoo(toString()); long bar = System.nanoTime(); testObject2.setBar(bar); assertEquals(toString(), testObject2.getFoo()); assertEquals(bar, testObject2.getBar()); SampleClass2 enhanced = enhancer2.enhance(testObject2); ((Snapshot) enhanced).snapshot(); assertNotSame(testObject2, enhanced); assertNotNull(enhanced); assertDirty(enhanced, false); assertEquals(toString(), enhanced.getFoo()); assertEquals(bar, enhanced.getBar()); enhanced.setFoo(null); assertNull(enhanced.getFoo()); assertDirty(enhanced, true); enhanced.setFoo(toString()); assertDirty(enhanced, false); enhanced.setBar(0L); assertEquals(0L, enhanced.getBar()); assertDirty(enhanced, true); enhanced.setFoo("something else"); ((Snapshot) enhanced).snapshot(); assertDirty(enhanced, false); }
public T enhance(T t) { if (!needsEnhancement(t)) { return t; } try { return getEnhancedClass().getConstructor(baseClass).newInstance(t); } catch (Exception e) { throw new RuntimeException(String.format("Could not enhance object %s (%s)", t, t.getClass()), e); } }
Enhancer { public T enhance(T t) { if (!needsEnhancement(t)) { return t; } try { return getEnhancedClass().getConstructor(baseClass).newInstance(t); } catch (Exception e) { throw new RuntimeException(String.format("Could not enhance object %s (%s)", t, t.getClass()), e); } } }
Enhancer { public T enhance(T t) { if (!needsEnhancement(t)) { return t; } try { return getEnhancedClass().getConstructor(baseClass).newInstance(t); } catch (Exception e) { throw new RuntimeException(String.format("Could not enhance object %s (%s)", t, t.getClass()), e); } } protected  Enhancer(Class<T> baseClass); }
Enhancer { public T enhance(T t) { if (!needsEnhancement(t)) { return t; } try { return getEnhancedClass().getConstructor(baseClass).newInstance(t); } catch (Exception e) { throw new RuntimeException(String.format("Could not enhance object %s (%s)", t, t.getClass()), e); } } protected  Enhancer(Class<T> baseClass); abstract boolean needsEnhancement(Object object); void validateClassIsEnhanceable(Class<T> baseClass); final Class<T> getBaseClass(); Class<? extends T> getEnhancedClass(); T newInstance(); T enhance(T t); }
Enhancer { public T enhance(T t) { if (!needsEnhancement(t)) { return t; } try { return getEnhancedClass().getConstructor(baseClass).newInstance(t); } catch (Exception e) { throw new RuntimeException(String.format("Could not enhance object %s (%s)", t, t.getClass()), e); } } protected  Enhancer(Class<T> baseClass); abstract boolean needsEnhancement(Object object); void validateClassIsEnhanceable(Class<T> baseClass); final Class<T> getBaseClass(); Class<? extends T> getEnhancedClass(); T newInstance(); T enhance(T t);  }