den*_*chr 5 java oop methods design-patterns switch-statement
我一直试图找到一种方法来从我的基类中标记几个方法,以便客户端类可以通过标记来调用它们.示例代码是:
public class Base {
public void method1(){
..change state of base class
}
public void method2(){
..change state of base class
}
public void method3(){
..change state of base class
}
}
Run Code Online (Sandbox Code Playgroud)
main()方法的客户端类将通过随机指令序列调用Base的每个方法:
public static void main(String[] args) {
String sequence = "ABCAABBBABACCACC"
Base aBase = new Base();
for (int i = 0; i < sequence.length(); i++){
char temp = sequence.charAt(i);
switch(temp){
case 'A':{aBase.method1(); break;}
case 'B':{aBase.method2(); break;}
case 'C':{aBase.method3(); break;} }
}
System.out.println(aBase.getState());
}
Run Code Online (Sandbox Code Playgroud)
现在我希望从Client对象中完全摆脱switch语句.我知道通过多态替换switch的技术,但是想避免创建一组新类.我希望简单地将这些方法存储在适当的数据结构中,并以某种方式用序列中的匹配字符标记它们.
地图可以轻松地存储具有值/键对的对象,这些对象可以完成工作(如我在此处所做)或命令模式,但由于我不想用对象替换这些方法,可能有不同的方法,存储方法并让客户有选择地调用它们?
任何建议表示赞赏
像这样的东西?
public class Base {
private final Map<Character, Method> methods = new HashMap<Character, Method>();
public Base() throws SecurityException, NoSuchMethodException {
methods.put('A', getClass().getMethod("method1"));
methods.put('B', getClass().getMethod("method2"));
methods.put('C', getClass().getMethod("method3"));
}
public Method getMethod(char c) {
return methods.get(c);
}
public void method1() {}
public void method2() {}
public void method3() {}
}
Run Code Online (Sandbox Code Playgroud)
然后
public static void main(String[] args) throws Exception {
String sequence = "ABCAABBBABACCACC";
Base aBase = new Base();
for (int i = 0; i < sequence.length(); i++) {
char temp = sequence.charAt(i);
aBase.getMethod(temp).invoke(aBase);
}
}
Run Code Online (Sandbox Code Playgroud)
我会对有问题的方法使用注释,允许它被标记为"标记方法",并提供用于该方法的标记字符串.
从那时起,实现变得更加简单; 你可以使用反射来迭代类的方法并检查它们的注释; 也许在启动时静态地执行此操作并填充从标记字符串到java.lang.reflect.Method的映射.
然后在处理命令字符串时,调用与每个标记对应的方法.
编辑:一些示例代码:
import java.lang.annotation.*;
@Retention(RetentionPolicy.RUNTIME)
@interface TaggedMethod {
String tag();
}
Run Code Online (Sandbox Code Playgroud)
然后在基类中:
public class Base {
@TaggedMethod(tag = "A")
public void method1(){
..change state of base class
}
@TaggedMethod(tag = "B")
public void method2(){
..change state of base class
}
@TaggedMethod(tag = "C")
public void method3(){
..change state of base class
}
}
Run Code Online (Sandbox Code Playgroud)
......并在客户端:
private static final Map<String, Method> taggedMethods = new HashMap<String, Method>();
// Set up the tag mapping
static
{
for (Method m : Base.class.getDeclaredMethods())
{
TaggedMethod annotation = m.getAnnotation(TaggedMethod.class)
if (annotation != null)
{
taggedMethods.put(annotation.tag(), m);
}
}
}
Run Code Online (Sandbox Code Playgroud)
以便您可以访问:
public static void main(String[] args) throws Exception
{
String sequence = "ABCAABBBABACCACC"
Base aBase = new Base();
for (int i = 0; i < sequence.length(); i++)
{
String temp = sequence.substring(i,1);
Method method = taggedMethods.get(temp);
if (method != null)
{
// Error handling of invocation exceptions not included
method.invoke(aBase);
}
else
{
// Unrecognised tag - handle however
}
}
System.out.println(aBase.getState());
}
Run Code Online (Sandbox Code Playgroud)
顺便说一下,这段代码还没有编译或测试...... :-)