分享
 
 
 

Eclipse Template与模式

王朝other·作者佚名  2007-05-10
窄屏简体版  字體: |||超大  

Eclipse Template与模式

Eclipse Template对我们是一个相当有用的工具,能节省我们很多写重复代码的时间;也能减少我们对copy&paste的使用。

关于Eclipse Templage的基础知识,详见我的Blog:Eclipse Template用法探讨。

而模式在我们的面向对象的编程的一个重要手段,特别是Java编程,更加离不开模式。然而,在模式的使用过程中,我们也会遇到很多重复代码的问题。这篇文章就是试图将Eclipse Template和模式结合起来,来解决我们在使用模式过程中遇到的重复代码的问题。

本文将要阐述将Eclipse Template和模式结合起来的相关问题,所以首先要求大家使用的IDE是Eclipse,如果有人使用的是其他的IDE,如netbean等,那么请首先熟悉该IDE的Template的用法。其次,本文还要求大家有模式基础,本文所涉及到的模式,由于文章内容所限,不会说明该模式的来龙去脉,如果不熟悉,请大家查阅相关资料。

单态模式是我们比较常用的一种模式,阎宏博士在其著作:《Java与模式》中,将单态模式分为三种,即:饿汉式单态模式、懒汉式单态模式和登记式单态模式。

其中,饿汉式单态模式的示例代码为:

public class EagerSingleton

{

private static final EagerSingleton m_instance = new EagerSingleton();

/**

* 私有的默认构造子

*/

private EagerSingleton() { }

/**

* 静态工厂方法

*/

public static EagerSingleton getInstance()

{

return m_instance;

}

……

}

该示例代码是一段相当实用的代码,几乎每一个饿汉式单态模式的应用都会有上面的代码出现,所不同的是类名,在实际代码中,你肯定不会叫EagerSingleton。然后不同的是被省略号省掉的部分,用户编写该类的业务逻辑。

如果我们经常使用饿汉式单态模式的话,就会发现编写上面的代码是十分枯燥的重复劳动。如果我们使用copy&paste,又不得不对代码中涉及到的类名做一次又一次的修改。

现在如果我们使用Eclipse Template工具,则该问题的解决变得十分简单。

首先,我们设计一个名为:EagerSingleton的Template,其Pattern为:

privatestaticfinal ${enclosing_type} m_instance = new ${enclosing_type}();

/**

*私有的默认构造子

*/

private ${enclosing_type}() { }

/**

*静态工厂方法

*/

publicstatic ${enclosing_type} getInstance()

{

return m_instance;

}

${cursor}

这样,我们就可以使用该Template,在类的代码的适当的位置输入Template名:EagerSingleton,然后点击Alt+/,如下图:

最后,得到结果为:

可以看到上面的结果,既不需要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();

}

return m_instance;

}

……

}

同上面的饿汉式单态模式一样,这个类前面的代码在每一个使用了该模式的类里都一样,属于重复代码,后面被省略号省掉的部分才是各个类自己的业务逻辑。

我们来设计一个名为LazySingleton的Template,其pattern为:

privatestatic ${enclosing_type} m_instance = null;

/**

*私有的默认构造子,保证外界无法直接实例化

*/

private ${enclosing_type}() { }

/**

*静态工厂方法,返还此类的惟一实例

*/

synchronizedpublicstatic ${enclosing_type} getInstance()

{

if (m_instance == null)

{

m_instance = new ${enclosing_type}();

}

return m_instance;

}

${cursor}

有关这个Template的测试结果,在这里就不再给出,请大家自己测一测,一定能深入体会到Eclipse Template的精妙之处。

第三种是登记式的单态模式,是为了解决单态模式类不能被继承而设计的一个新的单态模式,其示例代码如下:

public class RegSingleton

{

static private HashMap m_registry = new HashMap();

static

{

RegSingleton x = new RegSingleton();

m_registry.put( x.getClass().getName() , x);

}

/**

* 保护的默认构造子

*/

protected RegSingleton() {}

/**

* 静态工厂方法,返还此类惟一的实例

*/

static public RegSingleton getInstance(String name)

{

if (name == null)

{

name = "RegSingleton";

}

if (m_registry.get(name) == null)

{

try

{

m_registry.put( name,Class.forName(name).newInstance() ) ;

}

catch(Exception e)

{

System.out.println("Error happened.");

}

}

return (RegSingleton) (m_registry.get(name) );

}

……

}

同样,每一个应用该模式的类的自身的业务逻辑被代码中的省略号省略掉。省略号前面的代码是每一个应该该模式的类的重复代码。

这个模式的重复代码却更加的庞大,而我们使用Eclipse Template却更加地显示出了Eclipse Template的优越性。下面我们看看该Template是怎么设计的:

我们还是设计一个名为:RegSingleton的Template,其Pattern如下:

static private HashMap m_registry = new HashMap();

static

{

${enclosing_type} x = new ${enclosing_type}();

m_registry.put( x.getClass().getName() ,x);

}

/**

*保护的默认构造子

*/

protected ${enclosing_type}() {}

/**

*静态工厂方法,返还此类惟一的实例

*/

staticpublic ${enclosing_type} getInstance(String name)

{

if (name == null)

{

name ="${enclosing_package}.${enclosing_type}";

}

if (m_registry.get(name) == null)

{

try

{

m_registry.put( name,Class.forName(name).newInstance() ) ;

}

catch(Exception e)

{

System.out.println("Error happened.");

}

}

return (${enclosing_type}) (m_registry.get(name) );

}

${cursor}

大家不妨测试一下看看,是不是Eclipse Template显示出来巨大的优越性?

通过上面的三个例子,大家都看到了将Eclipse Template和模式结合起来的巨大威力,相信也引起了大家极大的兴趣。下面我们再结合几个例子来看看Eclipse Template和模式结合起来的效果。

结合了反射的工厂模式非常灵活,可以被广泛的使用。这个模式在我的Blog:“模式”专栏中有阐述。

该模式的示例代码如下:

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则更加的妙不可言.还等什么呢?赶快行动吧!

 
 
 
免责声明:本文为网络用户发布,其观点仅代表作者个人观点,与本站无关,本站仅提供信息存储服务。文中陈述内容未经本站证实,其真实性、完整性、及时性本站不作任何保证或承诺,请读者仅作参考,并请自行核实相关内容。
2023年上半年GDP全球前十五强
 百态   2023-10-24
美众议院议长启动对拜登的弹劾调查
 百态   2023-09-13
上海、济南、武汉等多地出现不明坠落物
 探索   2023-09-06
印度或要将国名改为“巴拉特”
 百态   2023-09-06
男子为女友送行,买票不登机被捕
 百态   2023-08-20
手机地震预警功能怎么开?
 干货   2023-08-06
女子4年卖2套房花700多万做美容:不但没变美脸,面部还出现变形
 百态   2023-08-04
住户一楼被水淹 还冲来8头猪
 百态   2023-07-31
女子体内爬出大量瓜子状活虫
 百态   2023-07-25
地球连续35年收到神秘规律性信号,网友:不要回答!
 探索   2023-07-21
全球镓价格本周大涨27%
 探索   2023-07-09
钱都流向了那些不缺钱的人,苦都留给了能吃苦的人
 探索   2023-07-02
倩女手游刀客魅者强控制(强混乱强眩晕强睡眠)和对应控制抗性的关系
 百态   2020-08-20
美国5月9日最新疫情:美国确诊人数突破131万
 百态   2020-05-09
荷兰政府宣布将集体辞职
 干货   2020-04-30
倩女幽魂手游师徒任务情义春秋猜成语答案逍遥观:鹏程万里
 干货   2019-11-12
倩女幽魂手游师徒任务情义春秋猜成语答案神机营:射石饮羽
 干货   2019-11-12
倩女幽魂手游师徒任务情义春秋猜成语答案昆仑山:拔刀相助
 干货   2019-11-12
倩女幽魂手游师徒任务情义春秋猜成语答案天工阁:鬼斧神工
 干货   2019-11-12
倩女幽魂手游师徒任务情义春秋猜成语答案丝路古道:单枪匹马
 干货   2019-11-12
倩女幽魂手游师徒任务情义春秋猜成语答案镇郊荒野:与虎谋皮
 干货   2019-11-12
倩女幽魂手游师徒任务情义春秋猜成语答案镇郊荒野:李代桃僵
 干货   2019-11-12
倩女幽魂手游师徒任务情义春秋猜成语答案镇郊荒野:指鹿为马
 干货   2019-11-12
倩女幽魂手游师徒任务情义春秋猜成语答案金陵:小鸟依人
 干货   2019-11-12
倩女幽魂手游师徒任务情义春秋猜成语答案金陵:千金买邻
 干货   2019-11-12
 
推荐阅读
 
 
 
>>返回首頁<<
 
靜靜地坐在廢墟上,四周的荒凉一望無際,忽然覺得,淒涼也很美
© 2005- 王朝網路 版權所有