标签: command-pattern

序列化对函数的调用

我需要在我的应用程序中实现任务的概念。在我的项目中,任务是必须执行的操作,并由名称标识:每个任务还​​具有输入参数(类型和值)并产生一个或多个输出。

必须实现 Task 类,如何表达“有某种结果的操作”的概念?我可以将操作的名称存储在字符串属性中,但是如何表达此操作返回的类型?同样,当这些参数也可能是不同类型时,如何实现操作的输入参数列表?

目标是序列化 Task 对象并将其发送到另一个节点。接收者分析接收到的 Task 对象,读取操作名称并执行相应的函数。

例如,假设节点 A 和节点 B“具有”以下方法......

节点A的服务:

- double getAreaOfRectangle(double length, double width);
- double getAreaOfTriangle(double base, double height);
- double getAreaOfParallelogram(double base, double height).
Run Code Online (Sandbox Code Playgroud)

节点B的服务:

- double getAreaOfCircle(double radius);
- double getAreaOfTrapezoid(double base1, double base2, double height).
Run Code Online (Sandbox Code Playgroud)

如果节点 C 需要计算一个矩形的面积,它知道它必须联系节点 A 并通过指定操作(double areaOfRectangle)和输入(double width and double height)向节点 A 发送消息。同样,如果节点C需要计算一个圆的面积,它必须向节点B发送消息,指定操作和半径的长度。为了发送输入,因为它们可能是不同的类型(甚至是新的用户定义类型),我可以使用一个对象数组......

一些任务可能依赖于其他任务,即,因为输入参数可能至少有另一个任务的一个输出,所以我还需要实现一个任务的输出和另一个任务的输入之间的链接。

我应该如何继续定义类?

c# wcf command-pattern

5
推荐指数
1
解决办法
4500
查看次数

Guava中的任何东西都类似于Functional Java的效果?

我知道纯函数式编程的目标之一是消除可变性,从而排除副作用.但是让我们面对现实吧,即使存在所有的函数式编程库,Java也不是一种函数式语言.事实上,似乎有些FP库知道并期待这一点.例如,在Functional Java中,有一个Effect类.在Jedi FP库中,有Command界面.这允许您 - 除其他外 - 将类型安全的命令模式应用于Iterable没有令人讨厌的for循环样板的元素.

Command<PhoneNumber> makeCall = new Command<PhoneNumber> {
    public void execute(PhoneNumber p) { p.call(); }
}
List<PhoneNumber> phoneList = ...
FunctionalPrimitives.forEach( phoneList, makeCall );
Run Code Online (Sandbox Code Playgroud)

所以问题是,番石榴中有类似的东西吗?

在接受澄清后接受回复

我正在开发一个框架,它可以帮助解决大多数Java FP库中固有的"垂直问题",在某些情况下.所以,我竟让如上图所示的代码示例:即明确宣布一个新的类实现的Command所有其垂直噪声过甜的烦躁,只需在声明之后立即应用它的目的.

我更多地考虑实际的命令模式,其中可能有几个可能的命令在其他地方声明,并且只有其中一个被传递到想要迭代应用它的代码中.此外,我的框架的目标是使创建功能接口对象(函数,谓词,命令,其他简单的lambda)更加惯用,而不是简单地将垂直问题移动到其他地方.我早就意识到这不在番石榴的范围内.但是由于其他FP库中有类似Command的接口,我只想知道Guava中是否存在模拟.

使用我的框架的更完整的代码示例可能是这样的:

class Stuff {
    private final Stuff CALLS_TO = callsTo(Stuff.class); // a proxy
    public static final Command<Stuff> CMD1 = commandFor(CALLS_TO.someMethod1());
    public static final Command<Stuff> CMD2 = commandFor(CALLS_TO.someMethod2());

    // methods exist for use elsewhere, but …
Run Code Online (Sandbox Code Playgroud)

java side-effects command-pattern functional-java guava

5
推荐指数
1
解决办法
3726
查看次数

.NET MVC 3中的命令模式(从控制器中删除垃圾)

我正在尝试在我的.NET MVC 3应用程序上实现此命令模式,专门用于保存对Thing的编辑.我还没有决定如何继续.在我得到实际问题之前,这里是简化的代码:

public class ThingController
{
    private readonly ICommandHandler<EditThingCommand> handler;

    public ThingController(ICommandHandler<EditThingCommand> handler)
    {
        this.handler = handler;
    }

    public ActionMethod EditThing(int id)
    {
        ...build EditThingViewModel and return with View...
    }

    [HttpPost]
    public ActionMethod EditThing(int id, EditThingViewModel vm)
    {
        var command = new EditThingCommand
        {
            ...not sure yet...
        };

        this.handler.Handle(command);

        ...redirect somewhere...
    }
}
Run Code Online (Sandbox Code Playgroud)

我的EditThingViewModel完全与我的域断开连接,该域由POCO类组成.看起来我的EditThingCommand应该如下所示:

public class EditThingCommand
{
    Thing ModifiedThing;
}
Run Code Online (Sandbox Code Playgroud)

但是,构建ModifiedThing仍然会在我的控制器中发生.这是本案中的大部分工作.在构建ModifiedThing时(以及应用于它的"旧"时间戳进行乐观并发检查),剩下的就是命令在我的数据上下文上调用Update.

显然,能够使用其他命令轻松装饰它是有价值的,但我也希望能够在我的控制器之外移动ModifiedThing的构造.(也许这个问题就是这个问题.)EditThingCommand在我的域中,没有对EditThingViewModel的引用,所以它不能去那里.在我的表示层中有另一个命令将我的viewmodel映射到我的poco实体是否有意义?

single-responsibility-principle command-pattern asp.net-mvc-3

5
推荐指数
1
解决办法
836
查看次数

用于绘制应用程序中的撤消/重做的命令模式

我想在一个小的绘图应用程序中实现undo/redo .似乎命令模式非常适合使用,但我不确定如何最好地实现它.

据我了解的模式,有必要在每个命令中包含:

  1. 用于重做的绘画操作的详细信息(例如,行 - >开始和结束点,自由格式行 - > GeneralPath)
  2. 更改撤消之前组件的状态.在这种情况下,这将是受命令影响的区域的小快照图像.

我的理解是,每个命令都需要是"原子的"或自包含的,并具有撤消/重做该操作所需的所有信息.

不幸的是,这需要存储比我最初预期更多的信息.对于一条线,我们还必须考虑类似的东西Color,Stroke并且RenderingHints最初用于绘制它.这将我的"简单的小命令"变成了一些东西......在内存中更笨重,并且有更多的样板代码可以生成(每个都是可序列化的bean 1).

出于记忆保护的原因(大多数情况下),我想要"欺骗"命令的规范.也许每100次更新都会备份整个绘图区域,但是不存储已更改图像的任何部分,只需为每次新的绘制操作重建最后(最多)100个命令.但是Graphics在绘制每个零件之前确保对象的状态是正确的似乎是有问题的- 这部分可能需要一条线,但是RenderingHints之前更改了4个命令,之前Color更改了98个命令,而Stroke最后一个保持相同227个命令.

追求更高效的内存命令似乎将模式从"原子"方面抛到了窗外.这反过来导致难以确定可能影响渲染的最早命令.

我是不是该:

  • 寻找新的模式?
  • 尝试通过调整模式来实现我的特殊需求?
  • 将所有这些丢弃在垃圾箱中作为过早优化,并以最简单(并且最耗费内存消耗)的方式对其进行编码,以便遵循定义的命令模式?

更新

  1. "每个都是一个可序列化的豆子" 在第二个想法,没有.我做了圆顶检查,发现a Graphics2D(整齐地封装了绘制时使用的许多参数)不可序列化.此外,a BasicStroke 是可序列化的,但不存储笔划的粗细.我可以创建许多属性的可序列化版本,但它似乎会产生更多的代码,所以我将放弃该规范.同样.我只会尝试BufferedImage在运行时存储对引用的引用.

java oop undo undo-redo command-pattern

5
推荐指数
1
解决办法
2658
查看次数

ASP.NET MVC - 正确使用View Model和Command模式

我已经编写ASP.NET MVC应用程序一段时间了,我发现它们是使用命令模式的好地方:我们将每个用户请求表示为命令 - 一组输入参数 - 然后处理此命令(处理包括验证和其他域逻辑),结果将发送回用户.

我在我的应用程序中使用的另一件事是视图模型.我发现它们是将数据传递给视图比使用域对象作为模型或填充ViewData/ViewBag更方便的方式.

这两个概念非常适合将显示给用户的数据与用户输入及其处理分开,但它们在ASP.NET MVC中并不完全一致.

假设我想在开发一个简单的网上商店时使用命令和视图模型,用户可以在其中查看产品,并可以通过提供产品名称和电子邮件地址来订购产品:

class ProductViewModel 
{
    public ProductViewModel(int id) { /* init */ }
    public int Id { get; set; }
    public string Name { get; set; }
    // a LOT of other properties (let's say 50)
}

class OrderProductCommand
{
    public int ProductId { get; set; }

    [Required(ErrorMessage = "Name not specified")]
    public string Name { get; set; }

    [Required(ErrorMessage ="E-Mail not specified")]
    public string Email { get; set; }

    public CommandResult …
Run Code Online (Sandbox Code Playgroud)

asp.net-mvc design-patterns command-pattern

5
推荐指数
1
解决办法
1431
查看次数

Hystrix命令对象:新vs单例

HystrixCommand对象实现创建为Singleton 是否正确?如果是这样,它将保留线程直到执行完成并且不再创建了吗?

singleton multithreading command-pattern threadpool hystrix

5
推荐指数
1
解决办法
361
查看次数

在命令模式中键入错误

我正在尝试为命令本身实现具有强类型输入和输出参数的命令模式.

首先,我创建了两个标记命令输入和输出的接口:

interface IRequest { }
interface IResponse { }
Run Code Online (Sandbox Code Playgroud)

然后我创建了基类和接口.这是抽象的接收器

interface IReceiver<TRequest, TResponse>
    where TRequest : IRequest
    where TResponse : IResponse
{
    TResponse Action( TRequest request );
}
Run Code Online (Sandbox Code Playgroud)

这是抽象的命令

abstract class AbstractCommand<TRequest, TResponse>
    where TRequest : IRequest
    where TResponse : IResponse
{
    protected IReceiver<TRequest, TResponse> _receiver;

    public AbstractCommand( IReceiver<TRequest, TResponse> receiver ) {
        _receiver = receiver;
    }

    public abstract TResponse Execute( TRequest request );
}
Run Code Online (Sandbox Code Playgroud)

现在我正在尝试使用这些对象,因此我创建了所需的具体类

class TypeARequest : IRequest
{
    public TypeARequest() {
    }

    public int NumericValueA { …
Run Code Online (Sandbox Code Playgroud)

c# command-pattern

5
推荐指数
1
解决办法
83
查看次数

使用map进行多次调用的Java流检查结果

关于正确使用流和地图,我有以下问题。

问题如下

我有一种方法可以从输入中读取文件并将记录插入数据库中,简而言之,它会产生一些副作用

此外,同一个函数返回某种状态,让我们说一个布尔值(我对此有一定的自由度)表明函数运行良好。

public static boolean execute(String filename){

    // Perform some side effects (e.g. write on DB)

    return true; // or false according to some criteria;

}
Run Code Online (Sandbox Code Playgroud)

然后,我必须用两个文件来调用它,我必须检测至少一个文件是否运行良好(即,如果至少一个执行返回 true)

我的简单解决方案是:(一种命令模式的简化版本)

public class Entrypoint {

    public static boolean myFunction(String input) {
        System.out.println("executed..." + input);
        return !input.equals("B");
    }

    public static void main(String[] args) {

        List<String> lst = Arrays.asList("A", "B", "C", "D", "E", "F");

        long callsOk = lst.stream().map(Entrypoint::myFunction)
            // .filter(x -> x.equals(true)).count();
            .filter(x -> x).count(); // Better, as suggested by Donat …
Run Code Online (Sandbox Code Playgroud)

java command-pattern java-8 java-stream

5
推荐指数
1
解决办法
117
查看次数

使用数据注释和DDD"ChangeProperty"方法进行命令验证

以下简单的实体...

public class MyEntity
{
    [MaxLength(100)]
    [Required]
    public string Name { get; private set; }
}
Run Code Online (Sandbox Code Playgroud)

...是否可以读取正在装饰"Name"属性的数据注释并验证ChangeName方法中指定的值,以便ValidationResults可以连接到其他验证结果.我假设使用MethodInfo或PropertyInfo对象有些怎么样?

我有这个,但感觉非常笨拙.

    public ValidationResult ChangeName(string value)
    {
        var property = GetType().GetProperty("Name");
        var attribute = property.GetCustomAttributes(typeof(MaxLengthAttribute), true)[0] as MaxLengthAttribute;
        if (attribute == null) return null; //yield break;

        if (value.Length > attribute.Length)
        {
            return new ValidationResult(NameValidation.NameTooLong);
        }

        return null;
    }
Run Code Online (Sandbox Code Playgroud)

我希望能够从我的验证器中的方法调用ChangeName(value),就像这样.

    private IEnumerable<ValidationResult> ValidateMyEntity(MyEntityAddCommand command)
    {
        MyEntity myEntity = new MyEntity();
        yield return myEntity.ChangeName(command.Name);
    }
Run Code Online (Sandbox Code Playgroud)

到目前为止我读到的大多数内容都说数据注释是针对CRUD而不是DDD,但为什么不使用它们,因为它们是描述验证行为的好方法,它将与我的MVC视图模型上的数据注释验证一致.有没有更好或更简洁的方法可以做到这一点?所有建议都赞赏.

c# validation domain-driven-design command-pattern data-annotations

4
推荐指数
1
解决办法
804
查看次数

访客vs仆人vs命令模式

这里讨论了Command和Servant模式的相似之处.但另一方面,我看到仆人与访客非常相似,而且非常相似,我不知道有什么区别?两者都通过添加功能为其他类对象服务.但命令模式不会添加功能,而是包装它,对吧?请解释一下我的困惑在哪里.

design-patterns visitor-pattern command-pattern

4
推荐指数
1
解决办法
1879
查看次数