可以看到上面的结果,既不需要copy&paste,也不需要一个个地去修改类名为:TemplateTest。使用了Eclipse Template,我们可以很轻松的解决重复代码的问题。 下面我们来看看懒汉式单态模式,其示例代码如下: public class LazySingleton { private static LazySingleton m_instance = null; /** * 私有的默认构造子,保证外界无法直接实例化 */ private LazySingleton() { } /** * 静态工厂方法,返还此类的惟一实例 */ synchronized public static LazySingleton getInstance() { if (m_instance == null) { m_instance = new LazySingleton();
该模式的示例代码如下: public class Factory { public static Animal getInstance(String name) { try { Class cls = Class.forName(name); return (Animal)cls.newInstance(); } catch(Exception e) { e.printStackTrace(); return null; } } } 对于这段代码,我们可以设计一个名为:DynaFactory的Template,其Pattern为: publicstatic ${interface} getInstance(String name) { try { Class cls = Class.forName(name); return (${interface})cls.newInstance(); } catch(Exception e) { e.printStackTrace(); returnnull; } } 这个Template中的参数${interface}代表的是该工厂类生产的产品的接口,可以是你的实际项目中的任何接口,你只需要在代码中用实际的接口代替${interface}即可,如下: 图中正在将interface参数修改为Animal。 还有一个经典例子是多态工厂模式,关于该模式的阐述,我在我的Blog:幕后英雄的用武之地——浅谈Java内部类的四个应用场景中的第四个例子中讲到。 要使用该模式,有多达两处的代码重复,请看下面的示例:
abstract class ShapeFactory {
protected abstract Shape create();
private static Map factories = new HashMap();
public static void
addFactory(String id, ShapeFactory f) {
factories.put(id, f);
}
// A Template Method:
public static final
Shape createShape(String id) {
if(!factories.containsKey(id)) {
try {
// Load dynamically
Class.forName("c05.shapefact2." + id);
} catch(ClassNotFoundException e) {
throw new RuntimeException(
"Bad shape creation: " + id);
}
// See if it was put in:
if(!factories.containsKey(id))
throw new RuntimeException(
"Bad shape creation: " + id);
}
return
((ShapeFactory)factories.get(id)).create();
}} 该代码有相当大的重复性,除了类名:ShapeFactory在每一个应用中不一样,还有接口:Shape不一样,还有就是包:c05.shapefact2 不一样。 下面是另外的一段代码:
class Circle implements Shape {
private Circle() {}
public void draw() {
System.out.println("Circle.draw");
}
public void erase() {
System.out.println("Circle.erase");
}
private static class Factory
extends ShapeFactory {
protected Shape create() {
return new Circle();
}
}
static {
ShapeFactory.addFactory(
"Circle", new Factory());
}
}在这段代码里,内部类:Factory也是重复的。
下面我们分别用两个Template来代表它们,首先设计一个名为:PolyFactory的Template,其Pattern为: protectedabstract ${interface} create(); privatestatic Map factories = new HashMap(); publicstaticvoid addFactory(String id, ${enclosing_type} f) { factories.put(id, f); } // A Template Method: publicstaticfinal ${interface} createProduct(String id) { if(!factories.containsKey(id)) { try { // Load dynamically Class.forName("${enclosing_package}." + id); } catch(ClassNotFoundException e) { thrownew RuntimeException("Bad product creation: " + id); } // See if it was put in: if(!factories.containsKey(id)) thrownew RuntimeException("Bad product creation: " + id); } return ((${enclosing_type})factories.get(id)).create(); } 使用该Template后的结果为: 第二个类的重复代码也设计成一个名为:PolyProduct的Template,其Pattern为: private ${enclosing_type}() {} privatestaticclass Factory extends ${Factory_name} { protected ${interface} create() { returnnew ${enclosing_type}(); } } static { ${Factory_name}.addFactory("${enclosing_type}", new Factory()); } 使用该模式后的结果为: 像这样的例子,在模式中真是比比皆是,最后以一个代理模式的例子来作为本文的结束,以后大家在使用模式的时候,不妨将模式和Eclipse Template结合起来使用,用来缩短我们的开发时间。 代理模式在我的Blog:代理模式、动态代理和面向方面中有过讲述,在那篇文字的最后,有这样一段代码: public class ProxyImpl extends BaseProxy { protected ProxyImpl(Object o) { super(o); } public static Object getInstance(Object foo) { return getInstance(foo,new ProxyImpl(foo)); } //委派前的动作 public void doBegin() { // TODO Auto-generated method stub System.out.println("begin doing....haha"); } //委派后的动作 public void doAfter() { // TODO Auto-generated method stub System.out.println("after doing.....yeah"); } } 这个动态代理经过了模板方法模式的简化,已经相当的简单了,但仍然有重复的代码。可以做如下的简化。 我们设计一个名为:DynaProxy的Template,其Pattern为: protected ${enclosing_type}(Object o) { super(o); } publicstatic Object getInstance(Object foo) { return getInstance(foo,new ${enclosing_type}(foo)); } 好了,到此本文该结束了.Eclipse Template的确是一个好的工具,能极大的减轻我们code重复代码.模式是面向对象编程的精华所在.而将模式和Eclipse Template则更加的妙不可言.还等什么呢?赶快行动吧!