2009-07-15 25 views
2

有没有一种方法可以定义一个方法,每次我调用get时都会调用它?Java Getters:总是执行特定的方法

我有一个物体接触,不希望设置updateLastUsed();在我的成员约30个吸气。

+2

这听起来有点不对,因为您正通过更新对象上的字段向您的吸气器介绍副作用。 – akf 2009-07-15 20:42:19

+0

对不起,我不是母语为英语的人。你能解释“介绍副作用”是什么意思吗? – 2009-07-15 20:47:23

+1

你真的需要30个获得者吗?这听起来不像一个类,而是一个数据包。我的猜测是联系人数据应该包含在包含所有操纵联系人的类的类中。拥有一个getters类意味着你需要为每个控件编写代码来复制数据(除非你使用反射,它仍然不比散列更好)。散列可以更容易地使用动态绑定,因此您不需要编写任何代码来将字段复制到数据库或GUI控件中(这是执行此操作的首选方法)。 – 2009-07-15 20:48:51

回答

2

我会建议AOP但如果它是J2ME我们在谈论你最有可能更好手动插入“onGetCalled()”,然后在该方法中编码任何你需要的内容。您可能希望传入所调用方法的名称(或访问的属性),以备将来使用。

2

可以在一个呼叫添加到每个方法(镗孔),或使用某种形式的AOP(例如AspectJ中,下面的例子),以匹配该类型的吸气剂,并调用updateLastUsed()方法。

编辑:有几个人指出,30个干将是一个代码气味和调用的另一种方法是副作用。第一个陈述是一个公平的指标,但不是一个规则。有这样的类型可能有很多原因,没有进一步的信息,我会留下它作为建议,以检查是否可以将职责分为两种或更多类型。

关于副作用的另一点可能相关,也可能不相关。有许多交叉问题使它适用于吸气剂方法。例如日志记录,身份验证和缓存。示例方法updateLastUsed()可能是缓存策略的一部分,所以我认为对这个问题的批评不合格。

如何实现在AspectJ的切入点和建议的例子如下:

package test; 

public aspect TestAspect { 
    /** 
    * Match all getters of test.Contact and bind the target. 
    */ 
    protected pointcut contactGetters(Contact contact) : 
     execution(* test.Contact.get*()) && target(contact); 

    /** 
    * Before execution of each getter, invoke the updateLastUsed() method 
    * of the bound target. 
    */ 
    before(Contact contact): contactGetters(contact) { 
     contact.updateLastUsed(); 
    }  
} 
1

这看起来像面向方面编程(AOP)的工作。

定义一个方面的任何与get*

“新”的AspectJ 5东西支持使用注解来定义方面的切入点开始,所以你可以注释你的干将有叫切入点@Before执行执行方法的主体。

1

这样做需要像AOP那样的东西。我不知道除了this以外,J2ME的支持程度如何。

1

而且AOP,你可以使用一个java.lang.reflect.Proxy,或字节码操作...

但不是在J2ME

我建议您来电updateLastUsed()的30倍。

3

不是访问您的属性的getter的,你可以创建,是以属性名称作为输入一个普通的getter。如果属性的类型不同,则返回类型需要为Object。

在调用属性getter和updateLastUsed()方法,这个一般吸气。为了安全,所有的财产获得者都是私人的。

1

这是一种方法。这是不漂亮,但你可能更喜欢到反复:

public class GetterTest extends TestCase { 
    private static class Thing { 
     public int accessCount; 
     private String name; 
     private int age; 

     private <T> T get(T t) { 
      accessCount++; 
      return t; 
     } 

     public String getName() { 
      return get(name); 
     } 

     public int getAge() { 
      return get(age); 
     } 
    } 

    public void testGetIncrementsAccessCount() throws Exception { 
     Thing t = new Thing(); 
     assertEquals(0, t.accessCount); 
     t.getName(); 
     assertEquals(1, t.accessCount); 
     t.getAge(); 
     assertEquals(2, t.accessCount); 
    } 
} 

很显然,我的get()仅仅是增加accessCount,你会想一些其他的行为,但这个想法是存在的。

1

使用正则表达式将方法调用追加到getter标头。

查找:

\0updateLastUsed();\1

这些表达式使用使用Eclipse 3.5(伽利略)测试 “全部替换”:

\w+ get\w+\s*\(\)\s*\{(\s*)

与更换一世在“查找/替换”对话框中。

请注意,您使用的编辑器必须支持多行匹配(或者您必须启用它)。对于EmEditor的8.05,我不得不修改搜索字符串是:

\w+ get\w+\s*\(\)\s*\{\s*(\n\s*)

,以使新线明确匹配。替换字符串保持不变。

1

你可以做一些奇特的事情,但老实说这就是为什么宏被添加到编辑器中,以便你可以快速重复无聊的代码。

我只是让所有的getters调用该方法,然后使用宏创建调用(如果它需要通过方法不同)。这一切只需要做一次,然后你只是忘了它...

0

我会说接近对象来调用所需的方法。