- iOS/Objective-C 元类和类别
- objective-c - -1001 错误,当 NSURLSession 通过 httpproxy 和/etc/hosts
- java - 使用网络类获取 url 地址
- ios - 推送通知中不播放声音
手头的任务是创建我的 Java Web 应用程序的一部分,这将使我能够以组合方式轻松执行小块代码。手头的任务是允许用户以任何顺序编写“ Action ”。我遇到的困难是将参数传递给我的操作。
一切都从 Action 界面开始:
public interface Action {
void resolve(Context context);
}
当 Action 被解析时,它的代码被执行。代码可以是任何东西:调用 Java 中的方法,执行一些 Javascript...
在这里,“上下文”对我来说是个问题。每个 Action 都在特定上下文中执行。这个想法是创建 Action 的用户可以指定从概念中检索哪个对象,例如正在解析当前 Action 的用户,或在 Action 的特定界面中指定的其他对象。
例如,让我们看一下这个 Action :
public final class ActionScript implements Action {
private final Parameters parameters;
private final String methodName;
private final ScriptsLibrary library;
public ActionScript(ScriptsLibrary library, String methodName, Parameters parameters) {
this.parameters = parameters;
this.library = library;
this.methodName = methodName;
}
@Override
public void resolve(Context context) {
try {
((Invocable) library.getEngine()).invokeFunction(methodName, context);
} catch (ScriptException | NoSuchMethodException ex) {
throw new RuntimeException(ex);
}
}
}
这是一个使用 Nashorn 在 Javascript 中调用 Action 的简单包装器。参数可以是任何东西:数据库中具有特定 id 的对象,用户配置的 int/String/boolean 值...
一个 Action 的代码可以是这样的:
public class DummyAction implements Action {
@Override
public void resolve(Context context) {
User userExecutingTheAction = context.get("ExecutingUser");
System.out.println("User " + userExecutingTheAction);
}
}
所以 Action 可以检索运行时参数(例如:执行 Action 的用户...)和静态参数(在加载 Action 时创建 - 例如从配置文件),以及所有来自概念的参数。此外,用户可以在运行时注入(inject)的参数中指定对对象的引用。
Action 也可以嵌套/修饰以实现完整的组合性。例如:
public class DummyWrapperAction implements Action {
private final Action wrappedAction;
public DummyWrapperAction(Action wrappedAction) {
this.wrappedAction = wrappedAction;
}
@Override
public void resolve(Context context) {
System.out.println("Before");
wrappedAction.resolve(context);
System.out.println("After");
}
}
这样可以轻松创建操作:
// executes specific action 1 or specific action 2 based on a condition
Action myAction = new LoggingAction(new ConditionalAction(new Condition(3), new SpecificAction1(), new SpecificAction2()));
知道了这一切,设计上下文类最干净的是什么?它应该分成几个元素吗?难点在于在运行时将所有需要的东西注入(inject)到类中,并确保不与潜在的包装操作发生冲突。
Context 基本实现负责:
我觉得它做得太多了。设计受到拥有很多责任的概念类的影响,它们应该是碎片化的(现在应用程序的每个部分都与概念相关联)。但是怎么办?这是我在干净编码中尝试实现的目标:
以真正的面向对象和面向方法的方式,如何解决这个特定的设计问题?
编辑:删除接口(interface)方法中的公共(public)声明符
编辑 2:我有很多有趣的解决方案,但对我来说更有意义的是每个 Action 都使用特定类型的上下文进行参数化的解决方案。我这样重组了事情:
最佳答案
我已将 Action
接口(interface)的 Context
设为通用:
public interface Action<C extends Context> {
void resolve(C context); // no need to use 'public' modifier here
// interface methods are always public
}
然后,Context
可以是标记接口(interface)、强制执行契约的接口(interface)或具有默认方法实现的抽象类:
public interface Context {
User get(String user);
// other default methods here
}
然后,你可以这样做:
public class LogUserContext implements Context {
@Override
public User get(String user) {
// materialize user here
}
}
让用户登录的Action
可以是:
public class LogUserAction implements Action<LogUserContext> {
@Override
public void resolve(LogUserContext context) {
User user = context.get("theUser");
// log the user in
}
}
对于包装的Action
,我会使用WrapperContext
上下文:
public interface WrapperContext extends Context {
Context getWrappedContext();
}
实现:
public class DummyWrappedContext implements WrapperContext {
private final Context wrappedContext;
public DummyWrapperContext(Context wrappedContext) {
this.wrappedContext = wrappedContext;
}
@Override
public Context getWrappedContext() {
return this.wrappedContext;
}
// TODO other methods from Context, etc.
}
现在你的 DummyWrapperAction
可以如下所示:
public class DummyWrapperAction implements Action<WrapperContext> {
private final Action wrappedAction;
public DummyWrapperAction(Action wrappedAction) {
this.wrappedAction = wrappedAction;
}
@Override
public void resolve(WrapperContext context) {
System.out.println("Before");
Context wrappedContext = context.getWrappedContext();
wrappedAction.resolve(wrappedContext);
System.out.println("After");
}
}
这个想法也是包装上下文。您可以通过允许链接或修饰上下文以及使用负责所有上下文通用任务的抽象类来增强此设计。
关于java - 如何在保持干净的编程实践的同时设计一个通用的 Action 类?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/32948198/
当包裹在 EmberJS Controller 的 actions 中时,如何从另一个 Action 调用一个 Action ? 使用现已弃用的方式定义操作的原始代码: //app.js App.In
我有一个 Action (一个yaml文件),用于将docker镜像部署到Google Cloud Run。 我希望收到通知构建和推送结果的Slack或电子邮件。 构建操作完成后,如何触发消息操作?
Selenium 的 actions 类中存在的 tick(Action action) 和 tick(Interaction...actions) 方法的用途是什么? 是否与点击任何 webElem
简短的背景故事 我们目前为数百名用户提供对话操作。我们在过去三年中为我们的一位客户开发了这个 Action 作为“工作”。正如我们最近发现的那样,我们会受到对话行为的影响。 当然,我们现在正在研究如何
考虑系统用户可以并发方式执行两个操作,第一个操作 (A1) 仅对用户的订单执行,第二个操作 (A2) 包括在执行时执行 (A1),如下面的使用所述-案例图..((考虑A1完全执行U1,A2完全执行U2
我正在为 android 中的 ActionBar 而苦苦挣扎。 这是我的问题:我的操作项没有显示在操作栏中,而是堆叠在操作溢出中,无论我做什么.. 我花了一天的时间寻找解决方案,但我似乎找不到缺少的
我正在构建一个工作流,其中一个操作为工作流中的一个步骤提供条件。我该如何使用这个值? 该操作的值为空,因此计算结果为 false,并且从未部署过任何内容... jobs: build: s
鉴于您有一些全局 View (例如,显示加载屏幕),您可能希望在许多情况下发生这种情况,为该行为创建一个 Action 创建者/ Action 对还是为相关 Action 创建 reducer 更合适
我有一个使用 DialogFlow 构建的 Actions on Google 代理,其中包含多个操作(例如 actions.intent.MAIN 和 get_day_of_week)。 当我在 3
是否可以从我的 action.yml 文件中引用另一个 GitHub 操作? 请注意,我在这里谈论的是操作,而不是工作流程。我知道这可以通过工作流来完成,但是操作可以引用其他操作吗? 最佳答案 答案似
在 Vuex 操作中,我们有以下实现。 async actionA({ commit, dispatch }) { const data = this.$axios.$get(`/apiUrl`)
我正在将我的应用程序服务器从 Jboss 4.2 迁移到 7.1。我在 Struts 配置中收到以下错误。 struts.xml 中定义的 Action 被调用,而 Action 包中的操作未被调用。
我向 ActLand 发送请求,然后 intercept(),如果没有登录则重定向到 Login.jsp。 struts.xml:
我有一个 Action 创建器,它接受一个 id 和一个回调函数。它向服务器发送请求以执行某些操作并返回一个虚拟操作。我在这里想做的就是调用回调函数并退出,因为该虚拟操作对我来说没有用处,例如喜欢帖子
我已经使用 Html.Action 方法调用了另一个 View 。当用户单击操作链接时,我想在 subview 内使用参数调用相同的操作。 当我写这段代码时,我得到了这个错误信息: Html.Acti
是 public event Action delt = () => { Console.WriteLine("Information"); }; 的重载版本 Action delg = (a, b)
countresultsfrom.addActionListener(new ActionListener() { public void actionPerforme
我刚刚看到一个 brand-new video在 Rx 框架上,一个特别的签名引起了我的注意: Scheduler.schedule(this IScheduler, Action) 在 23:55,
我创建了一个在我的开发者帐户中完美运行的 DialogFlow 应用程序。 但我需要以另一个用户的身份对其进行测试,因此在我的 Google Action 模拟器中,我添加了另一个测试帐户作为项目的所
我正在尝试实现消息存储拦截器以在我的 JSp 上显示 ActionMessage,但无法访问 ActionMessage。有人可以提供一个链接如何实现消息存储拦截器吗? 最佳答案 这是我的一个应用程序
我是一名优秀的程序员,十分优秀!