我想要一个实现,其中需要根据条件从两个类之一中调用一个方法。为了说明这一点,可以说我有两个简单的类:
public class A implements IObject {
@Override
public void doIt() {
System.out.println("OBJECTA");
}
}
public class B implements IObject {
@Override
public void doIt() {
System.out.println("OBJECTB");
}
}
和界面
public interface IObject {
void doIt();
}
我动态调用类函数的方法实现为:
void call(String s, A a, B b, Consumer<IObject> o) {
if(s.equalsIgnoreCase("CONDITION")) {
o.accept(a);
} else {
o.accept(b);
}
}
我可以这样称呼该方法
A objectA = new A();
B objectB = new B();
call("CONDITION", objectA, objectB, IObject::doIt);
call("OTHER", objectA, objectB, IObject::doIt);
这实际上将根据条件参数在类doIt
或A
上调用B
是否存在一种更清洁的方式来实现这一目标,也许可以减少参数的数量,从而减少功能call
的签名?
谢谢
答案 0 :(得分:2)
据我了解,您的问题:
((condition) a:b).doIt()
与下面的代码)。为什么不使用这样的模式:
A a = new A();
B b = new B();
String hint = ...;
List<Executor> list = new ArrayList<>();
list.add(new Executor("CONDITION"::equalsIgnoreCase, a::doIt));
list.add(new Executor(s -> true, b::doIt));
for (Executor executor : list) {
if (executor.process(hint)) {
break;
}
}
使用Executor
类:
class Executor {
private final Predicate<String> predicate;
private final Runnable runnable;
...
public boolean process(String s) {
if (!predicate.test(s)) {
return false;
}
runnable.run();
return true;
}
}
循环将评估条件,然后运行代码(如果为true),否则继续执行下一个元素。
Executor类在技术上不绑定到a
或b
;只有初始设置。
答案 1 :(得分:2)
这是一种完全不同的方法,利用了java.lang.reflect.Proxy
:
import java.lang.reflect.InvocationHandler;
import java.lang.reflect.Method;
import java.lang.reflect.Proxy;
/**
*
* @author ben
*/
public class Test {
public interface IObject {
void doIt();
}
public static class A implements IObject {
@Override
public void doIt() {
System.out.println("OBJECTA");
}
}
public static class B implements IObject {
@Override
public void doIt() {
System.out.println("OBJECTB");
}
}
public static void main(String[] args) {
final boolean condition = true;
IObject proxyObj = (IObject)Proxy.newProxyInstance(Test.class.getClassLoader(), new Class[]{IObject.class}, new InvocationHandler() {
@Override
public Object invoke(Object proxy, Method method, Object[] args) throws Throwable {
if (condition)
new A().doIt();
else
new B().doIt();
return null;
}
});
proxyObj.doIt();
}
}
在这里,您正在为接口创建代理对象。
当您对此对象调用.doIt()
时,调用处理程序将根据条件调用相应的实现。
然后可以传递代理并使用调用处理程序。
(应该清楚,这段代码仅给出一个概念,并且仅仅是如何使用代理接口/对象解决此问题的示例。)
答案 2 :(得分:1)
这实际上取决于您的用例。如果用例与您所描述的一样简单,则可以删除Consumer并直接在call函数中调用doIt。但是,我建议进一步推广该功能:
curl -X "PUT" http://your.url/demo/modify ...
然后通过以下方式调用它:
Path.DirectorySeparatorChar
以这种方式进行操作更干净,更扩展。它也需要相同数量的代码。 (未经测试,可能有错误,但是您知道了)。您可能会在纯(“纯”)函数式编程语言中看到这种方法,其中if语句只是一个带有条件的函数和两个函数(一个为true,一个为false)。
答案 3 :(得分:1)
使用 “工厂设计模式”
可以轻松实现上述要求工厂设计模式涉及以下三个步骤:
这是一个有效的演示:
// File name: Demo.java
interface IObject {
public void doIT();
}
class A implements IObject {
public void doIT() {
System.out.println("DoIT - Class A");
}
}
class B implements IObject {
public void doIT() {
System.out.println("DoIT - Class B");
}
}
class IObjectFactory {
static IObject getObject(String CONDITION) {
if(CONDITION.equalsIgnoreCase("CONDITION")) {
return (new A());
}
return (new B());
}
}
public class Demo {
public static void main(String[] args) {
IObject io1 = IObjectFactory.getObject("condition");
IObject io2 = IObjectFactory.getObject("no condition");
io1.doIT();
io2.doIT();
}
}
输出:
> javac Demo.java
> java Demo
DoIT - Class A
DoIT - Class B