概述
本文将和读者一起来理解GOF设计模式之OBSERVER(代理)。同样,本文将用JAVA对GOF中的示例代码改些,同时附上测试用例。
模式结构
GOF对STRATEGY的模式结构描述如
策略Strategy提供了AlgorithmInterface()接口,而其继承者ConcreteStrategy们将实现AlgorithmInterface()的多态。最后,Context初始化不同的strategy并调用strategy.AlgorithmInterface来实现策略。
看了这个模式结构图,有没有感觉就是一个类的多态。在子类中通过多态的方式实现了不同的方法实现策略。实际上就是这么一回事。
代码示例
为了简单明了地实现策略模式,笔者对示例代码做了瘦身。类结构如
Composition在构造函数中注入Compositor实例,并在Repair接口中调用compositor.Compose()实现策略。
完整代码如
package gof.composition;
import org.springframework.beans.factory.annotation.Qualifier;
import org.springframework.stereotype.Component;
@Component
@Qualifier("arrayCompositor")
public class ArrayCompositor extends Compositor {
@Override
public void Compose() {
System.out.println("compse in ArrayCompositor");
}
}
package gof.composition;
import org.springframework.context.annotation.Scope;
import org.springframework.stereotype.Component;
@Component
@Scope("prototype")
public class Composition {
public Compositor compositor;
public Composition(Compositor compositor) {
this.compositor = compositor;
}
public void Repair() {
this.compositor.Compose();
}
}
package gof.composition;
abstract public class Compositor {
public abstract void Compose();
}
package gof.composition;
import org.springframework.beans.factory.annotation.Qualifier;
import org.springframework.stereotype.Component;
@Component
@Qualifier("simpleCompositor")
public class SimpleCompositor extends Compositor {
@Override
public void Compose() {
System.out.println("compose in SimpleCompositor");
}
}
package gof.composition;
import org.springframework.beans.factory.annotation.Qualifier;
import org.springframework.stereotype.Component;
@Component
@Qualifier("texCompositor")
public class TeXCompositor extends Compositor {
@Override
public void Compose() {
System.out.println("compse in TeXCompositor");
}
}
测试用例
package gof.composition;
import org.springframework.context.annotation.ComponentScan;
import org.springframework.context.annotation.Configuration;
@Configuration
@ComponentScan
public class CompositionConfig {
}
package gof.composition;
import org.junit.Rule;
import org.junit.Test;
import org.junit.contrib.java.lang.system.StandardOutputStreamLog;
import org.junit.runner.RunWith;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.context.ApplicationContext;
import org.springframework.test.context.ContextConfiguration;
import org.springframework.test.context.junit4.SpringJUnit4ClassRunner;
import org.springframework.test.context.support.AnnotationConfigContextLoader;
import gof.composition.ArrayCompositor;
import gof.composition.Composition;
import gof.composition.SimpleCompositor;
import gof.composition.TeXCompositor;
@ContextConfiguration(classes=CompositionConfig.class,loader=AnnotationConfigContextLoader.class)
@RunWith(SpringJUnit4ClassRunner.class)
public class CompositionTest {
@Rule
public final StandardOutputStreamLog log = new StandardOutputStreamLog();
@Autowired
protected ApplicationContext context;
@Autowired
protected ArrayCompositor arrCompositor;
@Autowired
protected SimpleCompositor simpCompositor;
@Autowired
protected TeXCompositor texCompositor;
@Test
public void testArrayCom() {
Composition comp = (Composition) this.context.getBean("composition", this.arrCompositor);
comp.Repair();
}
@Test
public void testSimpComp() {
Composition comp = (Composition) this.context.getBean("composition", this.simpCompositor);
comp.Repair();
}
@Test
public void testTexComp() {
Composition comp = (Composition) this.context.getBean("composition", this.texCompositor);
comp.Repair();
}
}