java方法数组:适配器模式?
问题描述: 我希望能够将方法列表传递给只在一个类中定义了方法的其他类。如果在一个类中定义了方法,其中一些方法具有输入参数和非void返回类型,我希望能够将其中一些方法的列表(可能有重复项)作为参数传递给其他类的构造函数
代码说明: 下面的代码是一个粗糙的示例,如果它偏离了主要目标,则可以忽略它。除了下面的例子之外,另一个例子是方法为int-Add(int-n1,int-n2)、int-Subtract(int-n1,int-n2)、Multiply等。。接口有一个名为int-MathOperation的方法(int-n1,int-n2)
尝试解决问题: 适配器模式似乎具有我正在寻找的功能,但我只看到接口中的方法没有输入或输出参数的示例。下面是我为这个问题编写的一个示例实现
问题类比: 您有一个随机图片生成器web服务。有30种突变可以应用于图像。客户端连接并单击“生成”按钮,其中一些函数的随机列表被传递给web服务中的其他类,然后这些类继续使用自己的数据运行这些函数,同时还收集并可能重新使用返回值来生成一些变异的cat映像。它不能只显式调用另一个类中的方法,因为该过程需要在运行时随机完成。这就是为什么我倾向于生成一个随机的方法列表,这些方法在单击“生成”按钮时按顺序执行
我希望我已经说清楚了
public class SomeClass {
...
public double UseWrench(double torque, boolean clockwise) { ... }
public double UsePliers(double torque, boolean clockwise) { ... }
public double UseScrewDriver(double torque, boolean clockwise) { ... }
public boolean UseWireCutters(double torque) { ... }
interface IToolActions {
double TurnFastener(double torque, boolean clockwise);
boolean CutWire(double torque);
}
private IToolActions[] toolActions = new IToolActions[] {
new IToolActions() { public double TurnFastener(double torque, boolean clockwise) { double UseWrench(double torque, boolean clockwise); } },
new IToolActions() { public double TurnFastener(double torque, boolean clockwise) { double UsePliers(double torque, boolean clockwise); } },
new IToolActions() { public double TurnFastener(double torque, boolean clockwise) { double UseScrewDriver(double torque, boolean clockwise); } },
new IToolActions() { public boolean CutWire(double torque) { boolean UseWireCutters(double torque); } },
};
}
public class Worker<T> {
public List<? extends IToolActions> toolActions;
public Worker(List<? extends IToolActions> initialToolSet){
toolActions = initialToolActions;
}
}
# 1 楼答案
好吧,我要成为“那个家伙”。。。一个理解问题但无论如何都要求重述问题的人,因为我认为你走错了路。所以,请容忍我:如果你喜欢你所看到的,那就太好了;如果不是,我理解
基本上,你的意图/动机/目的与“适配器”的用途不同。命令模式更适合
但首先,更一般地说,设计“可重用软件的元素”(源于原始GOF设计模式书的标题)的目标之一是,当您添加功能时,您不想修改代码;相反,您希望在不触及现有功能的情况下添加代码。所以,当你有:
如果你想在工具箱里加一把螺丝刀,这很糟糕:
相反,在理想情况下,所有现有代码都将保持不变,您只需添加一个新的编译单元(即,添加一个新文件)和一个单元测试,然后对现有代码进行回归测试(这不太可能,因为现有代码都没有更改)。例如:
希望它能清楚地说明如何将其扩展到您的示例中。工作人员直接进入工具列表(或者,为了清楚起见,不用“工具”,只需称之为“命令”)
这种模式还允许轻松的“撤销”功能和“重试”,以及记忆(缓存结果,以便不必重新运行)
# 2 楼答案
虽然@alainlompo有一般的想法,但Java8通过使用诸如
BiConsumer
(对于double)或甚至仅仅是类对象的Consumer
之类的东西大大简化了这一点。事实上,你可以疯狂地接受varargs lambdas:然后,这很容易简化:
虽然这样应用它似乎有点尴尬(因为它是一种适配器模式),但您可以很容易地看到它如何应用于类主体:
当然,您不需要varargs,只需传递一个
Collection
就可以了等等,还有更多
如果你想要一个结果,你甚至可以通过
Function
使用一个自返回方法,例如:java 8中的函数API提供了更大的灵活性,使类似这样的复杂问题的编写变得极其简单
# 3 楼答案
@John这是我解决你问题的方法
我使用了MathOperations的例子来简化它。首先,我认为我最好将接口放在某个类之外,比如:
我创建了两个实现这个接口的类的示例,以及SomeClass内部的一个匿名实现(我做了一个加法、乘法和一个匿名“减法”)
重写toString()只是为了让我将在本文末尾展示的示例更具可读性
这是我的SomeClass类,它包含一个GetRandomListoOperations,在这里我模拟当点击按钮时发生的事情
这是我的SomeOther类(可能对应于你的工人类)
}
我有一个简单的测试类,它包含一个连接这两个类的main
下面是几个处决的例子:
还有另一个例子
我希望这能有所帮助